diff options
author | root <root@rbsd.ankarstrom.se> | 2021-04-29 00:02:41 +0000 |
---|---|---|
committer | root <root@rbsd.ankarstrom.se> | 2021-04-29 00:11:29 +0000 |
commit | 96e026c1815f123e5a60ee106cb802fc841faa6c (patch) | |
tree | 5f410a9d50a757e21b104afc2d22a8a22551b60d /lib/Apache/Inject | |
parent | 6cac80b5c80e89ac46e8a8fc928aa98de183a47f (diff) | |
download | Apache-Inject-master.tar.gz |
Apparently, an Apache filter can be invoked more than once for a
single request, depending on the size of the contents [1].
Luckily, though, a filter can save state in the ctx field [1,2].
The solution isn't perfect, as it can't handle arbitrary long heads,
but they're very unlikely.
[1] https://httpd.apache.org/docs/2.4/developer/output-filters.html#invocation
[2] https://perl.apache.org/docs/2.0/user/handlers/filters.html#Introducing_Filters
Diffstat (limited to 'lib/Apache/Inject')
-rw-r--r-- | lib/Apache/Inject/Filter.pm | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/lib/Apache/Inject/Filter.pm b/lib/Apache/Inject/Filter.pm index f87cdc1..67511e2 100644 --- a/lib/Apache/Inject/Filter.pm +++ b/lib/Apache/Inject/Filter.pm @@ -49,15 +49,29 @@ sub handler : FilterRequestHandler { return DECLINED; } - my ($buf, $content); - $content .= $buf while $f->read($buf); - return DECLINED if not $content =~ /$doc/; - - $f->print($+{head}) if $+{head}; - inject($f, "InjectHead"); - $f->print($+{body}) if $+{body}; - inject($f, "InjectFoot"); - $f->print($+{rest}) if $+{rest}; + # First pass + if (not $f->ctx) { + my ($buf, $content); + $content .= $buf while $f->read($buf); + if (not $content =~ /$doc/) { + $f->r->warn('Inject: Cannot find <body> (<head> too long?)'); + return DECLINED; + } + + $f->print($+{head}) if $+{head}; + inject($f, "InjectHead"); + $f->print($+{body}) if $+{body}; + inject($f, "InjectFoot"); + $f->print($+{rest}) if $+{rest}; + + $f->ctx(1); + } + + # Any subsequent pass + else { + my $buf; + $f->print($buf) while $f->read($buf); + } return OK; } |