Difference between revisions of "Mod rewrite/Hide a script"
(Created page with " Using mod_rewrite, we'd like to route all requests for a domain <code>sub.example.com/</code> to be redirected to a single FastCGI script at <code>d/dispatch.fcgi</code> ...") |
|||
Line 102: | Line 102: | ||
====/d/.htaccess==== | ====/d/.htaccess==== | ||
− | Without at least <code>RewriteEngine on</code> here, a 500 results. | + | Without at least <code>RewriteEngine on</code> here, a 500 results. (This is because when this .htaccess is missing, the root .htaccess handles the directory, getting caught in an infinite loop.) |
<syntaxhighlight lang=apache> | <syntaxhighlight lang=apache> | ||
Line 150: | Line 150: | ||
| /d/dispatch.fcgi/foo/bar | | /d/dispatch.fcgi/foo/bar | ||
| /foo/bar | | /foo/bar | ||
+ | |} | ||
+ | |||
+ | ==Almost perfect== | ||
+ | |||
+ | ====/.htaccess==== | ||
+ | |||
+ | |||
+ | <syntaxhighlight lang=apache> | ||
+ | RewriteEngine on | ||
+ | |||
+ | RewriteCond %{ENV:REDIRECT_STATUS} ^$ | ||
+ | RewriteRule ^(.*)$ d/dispatch.fcgi/$1 | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | ====/d/.htaccess (omit)==== | ||
+ | |||
+ | Omit this file so that the directory is also handled by the root .htaccess. | ||
+ | |||
+ | ===Failures=== | ||
+ | |||
+ | Everything works as specified except this bit where Apache insistently appends a trailing slash when something looks like a directory. | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! If the client requests… | ||
+ | ! then the rewrite must be to… | ||
+ | ! and PATH_INFO should be… | ||
+ | ! but instead, PATH_INFO is… | ||
+ | |- | ||
+ | | sub.example.com/d | ||
+ | | sub.example.com/d/dispatch.fcgi/d | ||
+ | | /d | ||
+ | | N/A (server 301s the request to sub.example.com/d/, with a trailing slash) | ||
|} | |} |
Revision as of 13:41, 15 January 2015
Using mod_rewrite, we'd like to route all requests for a domain sub.example.com/
to be redirected to a single FastCGI script at d/dispatch.fcgi
under the document root. This would be trivial, except that a request to sub.example.com/d/dispatch.fcgi
has to behave differently depending on whether the request came from the browser or from a rewrite rule.
These are a few minimum criteria for success:
Contents
Easy criteria
If the client requests… | then the rewrite must be to… | and PATH_INFO should be… |
---|---|---|
sub.example.com/ | sub.example.com/d/dispatch.fcgi/ | / |
sub.example.com/foo | sub.example.com/d/dispatch.fcgi/foo | /foo |
sub.example.com/foo/ | sub.example.com/d/dispatch.fcgi/foo/ | /foo/ |
sub.example.com/foo/bar | sub.example.com/d/dispatch.fcgi/foo/bar | /foo/bar |
Difficult criteria
If the client requests… | then the rewrite must be to… | and PATH_INFO should be… |
---|---|---|
sub.example.com/d | sub.example.com/d/dispatch.fcgi/d | /d |
sub.example.com/d/ | sub.example.com/d/dispatch.fcgi/d/ | /d/ |
sub.example.com/d/dispatch.fcgi | sub.example.com/d/dispatch.fcgi/d/dispatch.fcgi | /d/dispatch.cgi |
sub.example.com/d/dispatch.fcgi/ | sub.example.com/d/dispatch.fcgi/d/dispatch.fcgi/ | /d/dispatch.fcgi/ |
sub.example.com/d/dispatch.fcgi/foo | sub.example.com/d/dispatch.fcgi/d/dispatch.fcgi/foo | /d/dispatch.fcgi/foo |
sub.example.com/d/dispatch.fcgi/foo/ | sub.example.com/d/dispatch.fcgi/d/dispatch.fcgi/foo/ | /d/dispatch.fcgi/foo/ |
sub.example.com/d/dispatch.fcgi/foo/bar | sub.example.com/d/dispatch.fcgi/d/dispatch.fcgi/foo/bar | /d/dispatch.fcgi/foo/bar |
Test script
This script is placed at d/dispatch.fcgi under the document root.
#!/usr/bin/perl
use FCGI;
my %original_env = %ENV;
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;
my $counter = 0;
while ( FCGI::accept() >= 0 ) {
$counter++;
print "Content-Type: text/plain\n\n";
print "PATH_INFO: $ENV{PATH_INFO}\n";
print Dumper { '0-counter' => $counter, '1-initial-env' => \%original_env, '2-script-env' => \%ENV };
}
The trivial (and incorrect) answer
This is the answer we'd give if we didn't care about hiding.
Files
/.htaccess
RewriteEngine on
RewriteRule ^(.*)$ d/dispatch.fcgi/$1 [L]
/d/.htaccess
Without at least RewriteEngine on
here, a 500 results. (This is because when this .htaccess is missing, the root .htaccess handles the directory, getting caught in an infinite loop.)
RewriteEngine on
Failures
If the client requests… | then the rewrite must be to… | and PATH_INFO should be… | but instead, PATH_INFO is… |
---|---|---|---|
sub.example.com/d | sub.example.com/d/dispatch.fcgi/d | /d | N/A (The directory listing for /d/ is displayed) |
sub.example.com/d/ | sub.example.com/d/dispatch.fcgi/d/ | /d/ | N/A (The directory listing for /d/ is displayed) |
sub.example.com/d/dispatch.fcgi | sub.example.com/d/dispatch.fcgi/d/dispatch.fcgi | /d/dispatch.cgi | (empty string) |
sub.example.com/d/dispatch.fcgi/ | sub.example.com/d/dispatch.fcgi/d/dispatch.fcgi/ | /d/dispatch.fcgi/ | / |
sub.example.com/d/dispatch.fcgi/foo | sub.example.com/d/dispatch.fcgi/d/dispatch.fcgi/foo | /d/dispatch.fcgi/foo | /foo |
sub.example.com/d/dispatch.fcgi/foo/ | sub.example.com/d/dispatch.fcgi/d/dispatch.fcgi/foo/ | /d/dispatch.fcgi/foo/ | /foo/ |
sub.example.com/d/dispatch.fcgi/foo/bar | sub.example.com/d/dispatch.fcgi/d/dispatch.fcgi/foo/bar | /d/dispatch.fcgi/foo/bar | /foo/bar |
Almost perfect
/.htaccess
RewriteEngine on
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.*)$ d/dispatch.fcgi/$1
/d/.htaccess (omit)
Omit this file so that the directory is also handled by the root .htaccess.
Failures
Everything works as specified except this bit where Apache insistently appends a trailing slash when something looks like a directory.
If the client requests… | then the rewrite must be to… | and PATH_INFO should be… | but instead, PATH_INFO is… |
---|---|---|---|
sub.example.com/d | sub.example.com/d/dispatch.fcgi/d | /d | N/A (server 301s the request to sub.example.com/d/, with a trailing slash) |