Difference between revisions of "Mod rewrite/Hide a script"

From HalfgeekKB
Jump to navigation Jump to search
(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> ...")
 
 
(One intermediate revision by the same user not shown)
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 151: Line 151:
 
| /foo/bar
 
| /foo/bar
 
|}
 
|}
 +
 +
==Perfection==
 +
 +
====/.htaccess====
 +
 +
 +
<syntaxhighlight lang=apache>
 +
RewriteEngine on
 +
 +
RewriteCond %{ENV:REDIRECT_STATUS} ^$
 +
RewriteRule ^(.*)$ d/dispatch.fcgi/$1
 +
</syntaxhighlight>
 +
 +
====/d/.htaccess====
 +
 +
This .htaccess doesn't do any rewriting, but a directive needs to be added here to prevent <code>/d</code> from being 301ed to <code>/d/</code> (with a trailing slash).
 +
 +
<syntaxhighlight lang=apache>
 +
DirectorySlash Off
 +
</syntaxhighlight>

Latest revision as of 13:53, 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:

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

Perfection

/.htaccess

RewriteEngine on

RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.*)$ d/dispatch.fcgi/$1

/d/.htaccess

This .htaccess doesn't do any rewriting, but a directive needs to be added here to prevent /d from being 301ed to /d/ (with a trailing slash).

DirectorySlash Off