aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README55
-rw-r--r--lib/Apache/Inject.pm16
-rw-r--r--lib/Apache/Inject/Filter.pm32
3 files changed, 69 insertions, 34 deletions
diff --git a/README b/README
index ebbea98..f8fe202 100644
--- a/README
+++ b/README
@@ -116,31 +116,36 @@ OPERATION
and forwards their combined contents.
CAVEATS
- Apache::Inject::Filter uses a regular expression to determine the proper
- location of the injected header. It supports all valid HTML. However, it
- does not parse embedded CSS and JavaScript, which means that it is
- *possible* to construct an example where it will fail:
-
- <script>
- /* this looks like the closing tag for script: </script> */
- /* this looks like an opening tag for a new element: <title> */
- </script>
- <body>
- This is where the header <i>should</i> be inserted.
- <script>
- /* this looks like the closing tag for the title: </title>
- This is where the header is <i>actually</i> inserted.
- */
- </script>
- </body>
-
- This specific type of document, however, is *incredibly* unlikely. In
- this case, an ad-hoc solution is simpler, more efficient and more
- maintainable than a general one.
-
- On FreeBSD, you may need to enable the accf_http kernel module in order
- for the tests to work. Note that Apache::Inject works fine without the
- module; it is only the tests that require it.
+ * Apache::Inject::Filter uses a regular expression to determine the
+ proper location of the injected header. It supports all valid HTML.
+ However, it does not parse embedded CSS and JavaScript, which means
+ that it is *possible* to construct an example where it will fail:
+
+ <script>
+ /* this looks like the closing tag for script: </script> */
+ /* this looks like an opening tag for a new element: <title> */
+ </script>
+ <body>
+ This is where the header <i>should</i> be inserted.
+ <script>
+ /* this looks like the closing tag for the title: </title>
+ This is where the header is <i>actually</i> inserted.
+ */
+ </script>
+ </body>
+
+ This specific type of document, however, is *incredibly* unlikely.
+ In this case, an ad-hoc solution is simpler, more efficient and more
+ maintainable than a general one.
+
+ * Because of how Apache filters work, Inject may fail to find the end
+ of the <head> if the <head> is very long (in my experience over 7000
+ characters). If this happens, it will decline the request, and the
+ contents will be served as though Inject had not been enabled.
+
+ * On FreeBSD, you may need to enable the accf_http kernel module in
+ order for the tests to work. Note that Apache::Inject works fine
+ without the module; it is only the tests that require it.
DIAGNOSTICS
Apache::Inject and Apache::Inject::Filter log all errors and warnings to
diff --git a/lib/Apache/Inject.pm b/lib/Apache/Inject.pm
index 1d6f49b..68e003e 100644
--- a/lib/Apache/Inject.pm
+++ b/lib/Apache/Inject.pm
@@ -182,6 +182,10 @@ intelligently and forwards their combined contents.
=head1 CAVEATS
+=over
+
+=item *
+
Apache::Inject::Filter uses a regular expression to determine the
proper location of the injected header. It supports all valid HTML.
However, it does not parse embedded CSS and JavaScript, which means
@@ -204,10 +208,22 @@ This specific type of document, however, is I<incredibly> unlikely.
In this case, an ad-hoc solution is simpler, more efficient and
more maintainable than a general one.
+=item *
+
+Because of how Apache filters work, Inject may fail to find the end
+of the E<lt>headE<gt> if the E<lt>headE<gt> is very long (in my
+experience over 7000 characters). If this happens, it will decline
+the request, and the contents will be served as though Inject had
+not been enabled.
+
+=item *
+
On FreeBSD, you may need to enable the accf_http kernel module in
order for the tests to work. Note that Apache::Inject works fine
without the module; it is only the tests that require it.
+=back
+
=head1 DIAGNOSTICS
Apache::Inject and Apache::Inject::Filter log all errors and
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;
}