From 356ace1a5f618d00f145b640acb989dd0197e8d6 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 26 Apr 2021 23:36:30 +0000 Subject: Use filter instead of handler This makes it work for HTML content that has already been processed, e.g., by PHP. This change was delightfully easy to make. --- lib/Apache/Inject/Filter.pm | 93 ++++++++++++++++++++++++++++++++++++++++++++ lib/Apache/Inject/Handler.pm | 90 ------------------------------------------ 2 files changed, 93 insertions(+), 90 deletions(-) create mode 100644 lib/Apache/Inject/Filter.pm delete mode 100644 lib/Apache/Inject/Handler.pm (limited to 'lib/Apache/Inject') diff --git a/lib/Apache/Inject/Filter.pm b/lib/Apache/Inject/Filter.pm new file mode 100644 index 0000000..f87cdc1 --- /dev/null +++ b/lib/Apache/Inject/Filter.pm @@ -0,0 +1,93 @@ +package Apache::Inject::Filter; + +use 5.010000; +use strict; + +use mod_perl2; +use base qw/Apache2::Filter/; +use Apache2::Const qw/OK DECLINED/; +use Apache2::Log (); +use Apache2::RequestRec (); +use Apache2::RequestUtil (); + +my $doc = qr{ + \A + (? \s* + ( )? \s* + ( ]*> )? \s* + ( )? \s* + ( ]*> )? \s* + ( )? \s* + ( ]*> .*? \s* + | ( ]*> \s* + | ]*> \s* + | ]*> .*? \s* + | ]*> .*? \s* + | ]*> .*? \s* + | ]*> \s* + | \s* + )+ + )? + ( )? \s* + ( ]*> )? \s* + )? + (? .*? ) + (? \s* + ( )? \s* + )? + \z +}xmsi; + +sub handler : FilterRequestHandler { + my $f = shift; + + return DECLINED if not $f->r->content_type; + return DECLINED if not $f->r->content_type =~ m{^text/html($|;.*)}; + + if (not $f->r->document_root) { + $f->r->warn('Inject: Declining due to empty document root'); + 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}; + + return OK; +} + +sub inject { + my ($f, $var) = @_; + + # Retrieve value implicitly set by Inject directive + return if not (my $val = $f->r->dir_config($var)); + return if $val eq '-'; # special value signifying absence of argument + + # Validate path + if ($val =~ m{^/}) { + $f->r->log_error("Inject: $var should not begin with slash, as it is already always relative to document root"); + } + if ($val =~ m{^../|/../|/..$}) { + $f->r->log_error("Inject: $var cannot extend past document root"); + return; + } + + # note: document root has been confirmed not to be empty + my $root = $f->r->document_root; + + # Read contents of specified file + open my $fh, '<', "$root/$val" or do { + $f->r->log_error("Inject: $var $root/$val does not exist"); + return; + }; + $f->print($_) for <$fh>; + close $fh; +} + +1; diff --git a/lib/Apache/Inject/Handler.pm b/lib/Apache/Inject/Handler.pm deleted file mode 100644 index ae81fbb..0000000 --- a/lib/Apache/Inject/Handler.pm +++ /dev/null @@ -1,90 +0,0 @@ -package Apache::Inject::Handler; - -use 5.010000; -use strict; - -use mod_perl2; -use Apache2::Const qw/OK DECLINED/; -use Apache2::Log (); -use Apache2::RequestRec (); -use Apache2::RequestUtil (); - -my $doc = qr{ - \A - (? \s* - ( )? \s* - ( ]*> )? \s* - ( )? \s* - ( ]*> )? \s* - ( )? \s* - ( ]*> .*? \s* - | ( ]*> \s* - | ]*> \s* - | ]*> .*? \s* - | ]*> .*? \s* - | ]*> .*? \s* - | ]*> \s* - | \s* - )+ - )? - ( )? \s* - ( ]*> )? \s* - )? - (? .*? ) - (? \s* - ( )? \s* - )? - \z -}xmsi; - -sub handler { - my $r = shift; - - return DECLINED if not $r->content_type eq 'text/html'; - - my $content = ${$r->slurp_filename}; - return DECLINED if not $content =~ /$doc/; - - if (not $r->document_root) { - $r->warn('Inject: Declining request due to empty document root'); - return DECLINED; - } - - print $+{head} if $+{head}; - inject($r, "InjectHead"); - print $+{body} if $+{body}; - inject($r, "InjectFoot"); - print $+{rest} if $+{rest}; - - return OK; -} - -sub inject { - my ($r, $var) = @_; - - # Retrieve value implicitly set by Inject directive - return if not (my $val = $r->dir_config($var)); - return if $val eq '-'; # special value signifying absence of argument - - # Validate path - if ($val =~ m{^/}) { - $r->log_error("Inject: $var should not begin with slash, as it is already always relative to document root"); - } - if ($val =~ m{^../|/../|/..$}) { - $r->log_error("Inject: $var cannot extend past document root"); - return; - } - - # note: document root has been confirmed not to be empty - my $root = $r->document_root; - - # Read contents of specified file - open my $fh, '<', "$root/$val" or do { - $r->log_error("Inject: $var $root/$val does not exist"); - return; - }; - print for <$fh>; - close $fh; -} - -1; -- cgit v1.2.3