Skip to content

Instantly share code, notes, and snippets.

@getify
Created June 2, 2010 18:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save getify/422758 to your computer and use it in GitHub Desktop.
Save getify/422758 to your computer and use it in GitHub Desktop.
Options +ExecCGI
AddHandler perl-script cgi
PerlResponseHandler ModPerl::Registry
PerlOptions +ParseHeaders
RewriteEngine on
RewriteCond %{ENV:REDIRECT_REDIRECT_INTERNAL_ROUTING} !yes
RewriteRule .* routing.cgi [L,E=INTERNAL_ROUTING:yes]
## So, this .htaccess file first redirects all requests to one script
## called "routing.cgi". It also sets an environment variable called
## "INTERNAL_ROUTING". Owing to the mod_rewrite redirect, Apache
## "kindly" renames the environment variable immediately to
## "REDIRECT_INTERNAL_ROUTING".
## The purpose of this environment variable is to prevent infinite
## recursion if inside of routing.cgi I tell Apache to
## silently/internally redirect to another file like a .html file.
## Note: such a redirect will actually be the *second* redirect in
## the current scope, the first being from mod_rewrite.
## The really amusing part is that the filter to prevent the recursion
## has to inspect an environment variable called
## "REDIRECT_REDIRECT_INTERNAL_ROUTING", with 2x the "REDIRECT_"
## being prepended, since Apache "sees" two redirects. Ridiculous.
@clmarquart
Copy link

If you try using this condition: RewriteCond %{REQUEST_FILENAME} !routing.cgi you may not need the environment variables at all. I tested it out and it seems to avoid the recursion, not sure what your cgi is doing. If you still need the variable without the REDIRECT_

SetEnvIf REDIRECT_INTERNAL_ROUTING ^yes$ INTERNAL_ROUTING=yes
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !routing.cgi
RewriteRule .* /routing.cgi [L,E=INTERNAL_ROUTING:yes]

@cody_marquart

@getify
Copy link
Author

getify commented Jun 2, 2010

the point of the flag is not to prevent recursion on routing.cgi itself... the [L] flag I believe accomplishes that. The point is to prevent this condition from passing if, from inside routing.cgi, I issue a:

$->internal_redirect_handler("/some/other/file.html");

That internal Apache redirect command will cause the .htaccess to be re-evaluated, which will recurse back into routing.cgi infinitely if I don't find a way for the redirects issued from the Perl to be ignored and not mapped to "routing.cgi". I tried several different things, and was only able to get an environment variable to persist long enough to be useful for this task.

So, the idea is, set an environment variable when the first top-level request from the browser comes in and the request is routed to routing.cgi... then let routing.cgi redirect internally to any file it wants to, and don't cause those redirects to get trapped by the mod_rewrite rules.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment