diff options
author | root <root@rbsd.ankarstrom.se> | 2021-04-24 21:00:42 +0000 |
---|---|---|
committer | root <root@rbsd.ankarstrom.se> | 2021-04-24 21:00:42 +0000 |
commit | ea1ab70148decb7f5015d5c52511cd84ddf0ad17 (patch) | |
tree | 2a526f44b12c44364439f8245373ea8eb89f7f20 | |
parent | bc581b57b8300b848c41bd42864415f5e3415242 (diff) | |
download | Apache-Inject-ea1ab70148decb7f5015d5c52511cd84ddf0ad17.tar.gz |
Fix bug when second argument is absent, improve documentation
Before, the InjectFoot variable wasn't cleared.
-rw-r--r-- | README | 36 | ||||
-rw-r--r-- | lib/Apache/Inject.pm | 63 | ||||
-rw-r--r-- | lib/Apache/Inject/Handler.pm | 1 | ||||
-rwxr-xr-x | t/SMOKE | 2 | ||||
-rw-r--r-- | t/basic.t | 56 |
5 files changed, 108 insertions, 50 deletions
@@ -16,8 +16,9 @@ DESCRIPTION The Inject directive takes one or two arguments, which correspond to the file names of two HTML files in the document root. The contents of these files are then inserted into any requested HTML file. The first file - (the header) is inserted before the body of the requested HTML file, - while the second file (the footer) is inserted after the body. + (the header) is inserted at the top of the body of the requested HTML + file, while the second, optional file (the footer) is inserted at the + bottom of the body. The directive is smart enough to place the header and footer in the proper places. The contents of the header file is inserted after any @@ -26,6 +27,20 @@ DESCRIPTION the source of the requested HTML page). Likewise, the contents of the second file is placed before any potential final </html>. + The Inject directive serves a much more specific purpose than + server-side includes. It is designed for injecting headers and footers + that belong in the <body> element, such as headings, menu bars and + copyright notices. While you can technically include <head> elements in + your header file, they will be placed in the body of the HTML page and + not in the head. + + The main benefit over server-side includes is that the header and footer + is specified in the server configuration instead of the HTML files + themselves. Thus, it is useful for adding headers and footers to a large + number of pre-existing static HTML pages. Furthermore, this means that + the headers and footers on all pages can be changed at once by a single + change in the server configuration. + Please note: * The Inject directive is valid only inside directory sections, such @@ -33,11 +48,9 @@ DESCRIPTION .htaccess files if AllowOverride Limit/AuthConfig/All is enabled. * The file paths given to Inject are relative to the document root of - the current server or virtual server. - - * Apache::Inject is designed for injecting headers and footers that - belong in the <body> element, such as headings, menu bars and - copyright notices. It is not built for inserting <head> elements. + the current server or virtual server -- not the directory to which + the current directory section or .htaccess file applies. They should + be specified without a leading slash. INSTALLATION To install this module type the following: @@ -68,13 +81,18 @@ OPERATION concatenates them intelligently and prints their combined contents. DIAGNOSTICS - Apache::Inject::Handler logs all errors and warnings to the Apache log - file. Below is a list of all issued errors and warnings. + Apache::Inject and Apache::Inject::Handler log all errors and warnings + to the Apache log file. Below is a list of all issued errors and + warnings. Note that whenever Apache::Inject::Handler issues an error or a warning, this means that it also declines the request, letting Apache handle it as it would if the Inject directive were not used. + Error: Argument cannot be a single space + The file names given to Inject are not allowed to by a single space, + as this is a special value signifying absence of an argument. + Error: InjectHead/InjectFoot should not begin with slash, as it is already always relative to document root The paths given to Inject are always relative to the document root, diff --git a/lib/Apache/Inject.pm b/lib/Apache/Inject.pm index eb4fa36..83870bd 100644 --- a/lib/Apache/Inject.pm +++ b/lib/Apache/Inject.pm @@ -2,13 +2,13 @@ package Apache::Inject; use 5.008000; use strict; -use warnings; our $VERSION = '0.01'; use Apache2::CmdParms (); -use Apache2::Module (); use Apache2::Const qw/OR_LIMIT OR_AUTHCFG TAKE12/; +use Apache2::Log (); +use Apache2::Module (); my @directives = ( { name => 'Inject', @@ -22,18 +22,23 @@ Apache2::Module::add(__PACKAGE__, \@directives); sub Inject { my ($self, $parms, @args) = @_; - # Construct directives for passing arguments to handler - my @vars; - my @names = qw/InjectHead InjectFoot/; for (@args) { - s/\\/\\\\/; s/"/\\"/; - push @vars, 'PerlSetVar ' . (shift @names) . ' "' . $_ . '"'; + if ($_ eq ' ') { + $parms->server->log_error('Inject: Argument cannot be a single space'); + } } + # Construct directives for passing arguments to handler + my $head = $args[0]; + my $foot = $args[1] || ' '; # single space signifies absence of argument + $head =~ s/\\/\\\\/; s/"/\\"/; + $foot =~ s/\\/\\\\/; s/"/\\"/; + # Add relevant directives to current configuration $parms->add_config(['SetHandler perl-script', 'PerlResponseHandler Apache::Inject::Handler', - @vars]); + qq{PerlSetVar InjectHead "$head"}, + qq{PerlSetVar InjectFoot "$foot"}]); } 1; @@ -61,9 +66,9 @@ called Inject. The Inject directive takes one or two arguments, which correspond to the file names of two HTML files in the document root. The contents of these files are then inserted into any requested HTML -file. The first file (the header) is inserted before the body of -the requested HTML file, while the second file (the footer) is -inserted after the body. +file. The first file (the header) is inserted at the top of the +body of the requested HTML file, while the second, optional file +(the footer) is inserted at the bottom of the body. The directive is smart enough to place the header and footer in the proper places. The contents of the header file is inserted after @@ -73,6 +78,20 @@ E<lt>headE<gt> or E<lt>bodyE<gt> tag is present in the source of the requested HTML page). Likewise, the contents of the second file is placed before any potential final E<lt>/htmlE<gt>. +The Inject directive serves a much more specific purpose than +server-side includes. It is designed for injecting headers and +footers that belong in the E<lt>bodyE<gt> element, such as headings, +menu bars and copyright notices. While you can technically include +E<lt>headE<gt> elements in your header file, they will be placed +in the body of the HTML page and not in the head. + +The main benefit over server-side includes is that the header and +footer is specified in the server configuration instead of the HTML +files themselves. Thus, it is useful for adding headers and footers +to a large number of pre-existing static HTML pages. Furthermore, +this means that the headers and footers on all pages can be changed +at once by a single change in the server configuration. + Please note: =over @@ -84,14 +103,10 @@ blocks. It is valid in .htaccess files if AllowOverride Limit/AuthConfig/All is enabled. =item * -The file paths given to Inject are relative to the document root -of the current server or virtual server. - -=item * -Apache::Inject is designed for injecting headers and footers that -belong in the E<lt>bodyE<gt> element, such as headings, menu bars -and copyright notices. It is not built for inserting E<lt>headE<gt> -elements. +The file paths given to Inject are relative to the B<document root> +of the current server or virtual server -- B<not> the directory to +which the current directory section or .htaccess file applies. They +should be specified without a leading slash. =back @@ -128,8 +143,9 @@ contents. =head1 DIAGNOSTICS -Apache::Inject::Handler logs all errors and warnings to the Apache -log file. Below is a list of all issued errors and warnings. +Apache::Inject and Apache::Inject::Handler log all errors and +warnings to the Apache log file. Below is a list of all issued +errors and warnings. Note that whenever Apache::Inject::Handler issues an error or a warning, this means that it also declines the request, letting @@ -137,6 +153,11 @@ Apache handle it as it would if the Inject directive were not used. =over +=item Error: Argument cannot be a single space + +The file names given to Inject are not allowed to by a single space, +as this is a special value signifying absence of an argument. + =item Error: InjectHead/InjectFoot should not begin with slash, as it is already always relative to document root diff --git a/lib/Apache/Inject/Handler.pm b/lib/Apache/Inject/Handler.pm index 794eb2f..b1e6319 100644 --- a/lib/Apache/Inject/Handler.pm +++ b/lib/Apache/Inject/Handler.pm @@ -55,6 +55,7 @@ sub inject { # 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{^/}) { @@ -1,6 +1,6 @@ #!/usr/local/bin/perl # WARNING: this file is generated, do not edit -# generated on Sat Apr 24 18:58:44 2021 +# generated on Sat Apr 24 21:00:04 2021 # 01: /usr/local/lib/perl5/site_perl/mach/5.32/Apache/TestConfig.pm:1003 # 02: /usr/local/lib/perl5/site_perl/mach/5.32/Apache/TestConfig.pm:1095 # 03: /usr/local/lib/perl5/site_perl/mach/5.32/Apache/TestSmoke.pm:775 @@ -5,7 +5,7 @@ use Apache::Test; use Apache::TestUtil; use Apache::TestRequest qw/GET_BODY/; -plan tests => 5; +plan tests => 7; my $head; # expected page header my $foot; # expected page footer @@ -13,55 +13,73 @@ my @body; # sections of page body # Read contents of header and footer -open my $h, '<', 't/htdocs/head.html' or die "Could not open < head.html: $!"; -open my $f, '<', 't/htdocs/foot.html' or die "Could not open < foot.html: $!"; +open my $h, '<', 't/htdocs/head.html' + or die "Could not open < t/htdocs/head.html: $!"; +open my $f, '<', 't/htdocs/foot.html' + or die "Could not open < t/htdocs/foot.html: $!"; $head = do { local $/; <$h> }; $foot = do { local $/; <$f> }; close $h; close $f; -# Set up helpers +# Helper for replacing file contents -sub set_conf { - open my $c, '>', 't/htdocs/.htaccess' or die; - print $c shift; - close $c; -} -sub set_body { - open my $b, '>', 't/htdocs/test.html' or die; - print $b join('', @_); - close $b; +sub set { + my $file = shift; + open my $fh, '>', $file or die "Could not open > $file: $!"; + print $fh join('', @_); + close $fh; } # Run tests -set_conf <<CONF; +set 't/htdocs/.htaccess', <<CONF; Inject head.html foot.html CONF +set 't/htdocs/subdir/.htaccess', <<CONF; +Inject head.html +CONF + @body = ("<title>Test</title>\n", "This is a test page.\n"); -set_body @body; +set 't/htdocs/test.html', @body; ok GET_BODY('/test.html'), "${body[0]}$head${body[1]}$foot", '<head>-less head'; @body = ("<head>...</head>\n", "This is a test page.\n"); -set_body @body; +set 't/htdocs/test.html', @body; ok GET_BODY('/test.html'), "${body[0]}$head${body[1]}$foot", '<head>-ful head'; @body = ("<html>\n", "This is a test page.\n", "</html>\n"); -set_body @body; +set 't/htdocs/test.html', @body; ok GET_BODY('/test.html'), "${body[0]}$head${body[1]}$foot${body[2]}", '<html>-wrapped document'; @body = ("<!doctype html>\n", "This is a test page.\n"); -set_body @body; +set 't/htdocs/test.html', @body; ok GET_BODY('/test.html'), "${body[0]}$head${body[1]}$foot", '<!doctype>'; @body = ("\n<!doctype html>\n", "This is a test page.\n"); -set_body @body; +set 't/htdocs/test.html', @body; ok GET_BODY('/test.html'), "${body[0]}$head${body[1]}$foot", '<!doctype> with leading newline'; +@body = ("This is a test page.\n"); +set 't/htdocs/subdir/test.html', @body; +ok GET_BODY('/subdir/test.html'), "$head${body[0]}", + 'different injection in subdirectory'; + +set 't/htdocs/subdir/.htaccess', <<CONF; +Inject " " +CONF + +set 't/htdocs/ ', 'head'; # needed in case " " is (incorrectly) accepted +ok GET_BODY('/subdir/test.html') eq "head${body[0]}" && 1 || 0, 0, + 'single-space argument should fail'; + unlink 't/htdocs/.htaccess'; unlink 't/htdocs/test.html'; +unlink 't/htdocs/subdir/.htaccess'; +unlink 't/htdocs/subdir/test.html'; +unlink 't/htdocs/ '; |