Test::Apache::RewriteRules
Perl
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
config
lib/Test/Apache
t/test
t_deps/modules
.gitignore
.gitmodules
.travis.yml
Makefile
README.pod

README.pod

NAME

Test::Apache::RewriteRules - Testing Apache's Rewrite Rules

SYNOPSIS

  use Test::Apache::RewriteRules;
  use Path::Class;
  
  $Test::Apache::RewriteRules::HttpdPath = '/path/to/httpd';
  my $apache = Test::Apache::RewriteRules->new;
  $apache->add_backend(name => 'ReverseProxyedHost1');
  $apache->add_backend(name => 'ReverseProxyedHost2');
  $apache->rewrite_conf_f(file('apache.rewrite.conf'));
  
  $apache->start_apache;
  
  $apache->is_host_path(q</foo/a>, 'ReverseProxyedHost1', q</a>,
                        'Handled by reverse-proxyed host 1');
  $apache->is_host_path(q</bar/b>, 'ReverseProxyedHost2', q</b>,
                        'Handled by reverse-proxyed host 2');
  $apache->is_host_path(q</baz>, '', q</baz>,
                        'Handled by the proxy itself');
  $apache->is_redirect(q</hoge/z>, q<http://external.test/z>);
  $apache->is_status_code(q</secret>, 403);
  
  $apache->stop_apache;

  # apache.rewrite.conf
  RewriteEngine on
  RewriteRule /foo/(.*)  http://%{ENV:ReverseProxyedHost1}/$1 [P,L]
  RewriteRule /bar/(.*)  http://%{ENV:ReverseProxyedHost2}/$1 [P,L]
  RewriteRule /hoge/(.*) http://external.test/$1 [R,L]

DESCRIPTION

The Test::Apache::RewriteRules module sets up Apache HTTPD server for the purpose of testing of a set of RewriteRules in apache.conf Apache configuration.

METHODS

$apache = Test::Apache::RewriteRules->available;

Returns whether the features provided by this module is available or not. At the time of writing, it returns false if no Apache httpd executable is found.

$apache = Test::Apache::RewriteRules->new;

Returns a new instance of the class.

$apache->add_backend(name => HOST_NAME);

Registers a backend (i.e. a host that handles HTTP requests). An environment variable whose name is HOST_NAME will be defined in the automatically-generated Apache configuration file such that it can be used in rewrite rules.

$apache->copy_conf_as_f(ORIG_FILE, [PATTERN1 => REPLACE1, PATTERN2 => REPLACE2, ...], OPTIONS...)

Copies the file represented by the Path::Class::File object given as the first argument into the temporary directory and then, optionally replaces its content by applying patterns given as the second argument.

Patterns, if specified, must be an array reference containing string or regular expression followed by string or code reference. If the replaced string is specified as a code reference, its return value is used for the replacement. If the pattern is specified as a regular expression and the replaced string is specified as a code reference, the code reference can use $1, $2, ... to access to captured substrings.

The remaining arguments are interpreted as key-value pairs. If a rewrite_include option is specified, files referenced from the specified file using the Include directives are recursively copied into the temporary directory. The value must be a code reference. The code is invoked with an argument, the path (string) specified in the Include directive, and is expected to return the path (string) representing the referenced file in your testing environment. It would be useful if paths specified in configuration files assumes different file system layout from your testing environment.

Contents of the referenced files are also replaced using the patterns when the inherit_patterns option is also specified.

The method returns the Path::Class::File object representing the copied file.

$apache->rewrite_conf_f(PATH_CLASS_FILE)

Sets the Path::Class::File object that represents the path to the RewriteRules' part of the Apache configuration to test.

$apache->start_apache

Boots the Apache process. It should be invoked before any is_host_path call.

$apache->is_host_path(REQUEST_PATH, EXPECTED_HOST_NAME, EXPECTED_PATH, [NAME])

Checks whether the request for REQUEST_PATH is handled by host EXPECTED_HOST_NAME with path EXPECTED_PATH. The host name should be specified by the name registered using add_backend method, or the empty string if the request would be handled by the reverse proxy (i.e. the rewriting host) itself. This method acts as a test function of Test::Builder or Test::More. The argument NAME, if specified, represents the name of the test.

$apache->is_redirect(REQUEST_PATH, EXPECTED_REDIRECT_URL, [NAME], [code => CODE])

Checks whether the request for REQUEST_PATH is HTTP-redirected to the EXPECTED_REDIRECT_URL. This method acts as a test function of Test::Builder or Test::More. The argument NAME, if specified, represents the name of the test.

Optionally, you can specify the expected HTTP status code. The default status code is 302 (Found).

$apache->is_status_code(REQUEST_PATH, EXPECTED_STATUS_CODE, [NAME])

Checks whether the response returned for a request for REQUEST_PATH has status code of EXPECTED_REQUEST_CODE. The argument NAME, if specified, represents the name of the test.

$apache->stop_apache

Shuts down the Apache process.

You can set the expected client environment used to evaluate is_host_path, is_redirect, and is_status_code by code blocks provided by Test::Apache::RewriteRules::ClientEnvs module.

Where REQUEST_PATH is expected, the host for the request (as used in the HTTP Host: request header field) can be specified by prepending // followed by host (hostname optionally followed by : and port number) before the real path.

ENVIRONMENT VARIABLES

If the environment variable TEST_APACHE_HTTPD is set, the value is used as the path to the Apache's httpd executable. If the variable is not specified, but the Perl global variable $Test::Apache::RewriteRules::HttpdPath is set to a non-default value, the value is used as the path to the httpd. Otherwise, the httpd file is searched from commonly-installed paths. If the specified path is invalid, or no httpd is found at all, the module bails out.

Likewise, the environment variable TEST_APACHE_APXS can be used to specify the path to the apxs command of Apache. However, you usually don't have to specify this, as apxs is usually installed at the same location as httpd.

If the environment variable TEST_APACHE_DEBUG is set to a true value, or the Perl global variable $Test::Apache::RewriteRules::DEBUG is set to a true value, then the debug mode is enabled. In debug mode, some additional debug messages are printed. Moreover, temporary directories containing auto-generated configuration files and log files are not deleted upon the termination of the Perl process.

EXAMPLES

See t/test/apache-rewriterules*.t and t/test/apache-rewriterules*.conf.

DEPENDENCY

Apparently, the module depends on Apache HTTP Server. It requires Apache 2.2 with appropriate modules installed.

The module also requires Perl 5.8 or later, as well as modules: Exporter::Lite, Path::Class, Test::Differences, LWP::UserAgent, and HTTP::Request.

DEVELOPMENT

Latest version of the module is available in the GitHub repository <https://github.com/wakaba/perl-test-apache-rewriterules>.

HISTORY

1.0

Initial released version.

1.1

Added is_status_code method.

1.2

Added rewrite_include option.

SEE ALSO

mod_rewrite <http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html>.

Test::More.

Test::Apache::RewriteRules::ClientEnvs.

Test::Apache::RewriteRules で mod_rewrite のテストを書こう, id:onishi, October 17, 2010, <http://d.hatena.ne.jp/onishi/20101017/1287277579> (In Japanese).

AUTHOR

Wakaba (id:wakabatan) <wakabatan@hatena.ne.jp>.

ACKNOWLEDGEMENTS

This module was originally developed as part of Ugomemo Hatena project, then improved at Hatena Application Platform Development Team.

Thanks to Kentaro Kuribayashi (id:antipop) and id:shiba_yu36 for their contributions.

The repository contains a copy of Net::TCP::FindPort module, whose latest version is available from <https://github.com/wakaba/perl-net-tcp-findport>.

LICENSE

Copyright 2010-2011 Hatena <http://www.hatena.ne.jp/>.

Copyright 2012 Wakaba <wakaba@suikawiki.org>.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.