aboutsummaryrefslogtreecommitdiff
path: root/lib/Apache/Inject
diff options
context:
space:
mode:
authorroot <root@rbsd.ankarstrom.se>2021-04-29 00:02:41 +0000
committerroot <root@rbsd.ankarstrom.se>2021-04-29 00:11:29 +0000
commit96e026c1815f123e5a60ee106cb802fc841faa6c (patch)
tree5f410a9d50a757e21b104afc2d22a8a22551b60d /lib/Apache/Inject
parent6cac80b5c80e89ac46e8a8fc928aa98de183a47f (diff)
downloadApache-Inject-96e026c1815f123e5a60ee106cb802fc841faa6c.tar.gz
Fix filter-related bugHEADmaster
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.pm32
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;
}