aboutsummaryrefslogtreecommitdiff
path: root/lib/Apache/Inject/Handler.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Apache/Inject/Handler.pm')
-rw-r--r--lib/Apache/Inject/Handler.pm82
1 files changed, 82 insertions, 0 deletions
diff --git a/lib/Apache/Inject/Handler.pm b/lib/Apache/Inject/Handler.pm
new file mode 100644
index 0000000..5a40fd8
--- /dev/null
+++ b/lib/Apache/Inject/Handler.pm
@@ -0,0 +1,82 @@
+package Apache::Inject::Handler;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache2::RequestRec ();
+use Apache2::RequestUtil ();
+use Apache2::Const qw/OK DECLINED/;
+
+my $doc = qr{
+ \A
+ (?<head> \s*
+ (<!doctype[^>]*>)? \s*
+ (<html[^>]*>)? \s*
+ ( <head[^>]*>.*?</head> \s*
+ | ( <title[^>]*>.*?</title> \s*
+ | <base[^>]*> \s*
+ | <meta[^>]*> \s*
+ | <link[^>]*> \s*
+ | <style[^>]*>.*?</style> \s* # n.b.
+ | <script[^>]*>.*?</script> \s* # n.b.
+ )+
+ )?
+ (<body[^>]*>)?
+ )?
+ (?<body> .*? )
+ (?<rest> </html> \s* )?
+ \z
+}xmsi;
+
+sub inject {
+ my ($r, $var) = @_;
+
+ # Retrieve value implicitly set by Inject directive
+ return if not (my $val = $r->dir_config($var));
+
+ # Validate path
+ if ($val =~ m{^/}) {
+ warn "$var should not begin with slash, "
+ . "as it is already always relative to document root";
+ }
+ if ($val =~ m{^../|/../|/..$}) {
+ warn "$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 {
+ warn "$var $root/$val does not exist";
+ return;
+ };
+ print for <$fh>;
+ close $fh;
+}
+
+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/;
+
+ # Or is DocumentRoot guaranteed not to be empty?
+ if (not $r->document_root) {
+ warn '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;
+}
+
+1;