Question

We're trying to set up a local development XAMPP machine (Apache2, on Windows 8).

All mod_rewrite directives work fine, except one specific kind of directive: We try to redirect a request for some directories to a specific file.

RewriteEngine On
RewriteRule ^/?$ add_survey.php [QSA,L]

index.php is served instead. We also tried ^.?$, ^$, /* but none of these worked.

This works though (but is too inclusive)

RewriteRule ^.*$ add_survey.php [QSA,L]

I checked the usual suspects (for me), i.e. Options -Multiviews and Options -Indexes, my colleague is now playing with mod_dir, though I don't really see why it would be the culprit.

To clarify our use case:
Requests to /survey/ should go to add_survey.php, while all other requests go to e.g. /survey/SURVEYNAME/upload and in this context the index.php file is served as /survey/SURVEYNAME/.

Basically all files are structured under the specific available surveys, the only file that can be called without a specific available survey is the one which allows you to create a new one.

/survey/               #-> add new survey, e.g. NAME (/survey/add_survey.php)
/survey/NAME/          #-> manage existing survey NAME (/survey/index.php?survey_name=NAME)
/survey/NAME/results   #-> view results in NAME (/survey/results.php?survey_name=NAME)
Was it helpful?

Solution

tl;dr: add
DirectoryIndex disabled

I made a pull request for your convenience ;) https://github.com/rubenarslan/formr.org/pull/82

A little late, but i stubled into this problem today not on XAMPP but Apache 2.4.7 on Ubuntu 14.04.1 ...

After looking at the debugging output of Apache/rewrite it looks like Apache is trying index files instead of using the correct rewrite. So my solution ( or more likely workaround :) is to disable DirectoryIndex for the survey and run directory:

/webroot/admin/run/.htaccess:

<IfModule mod_rewrite.c>
DirectoryIndex disabled
RewriteEngine On
RewriteRule ^/?$ add_run.php [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/?([A-Za-z0-9_]+)/?$ index.php?run_name=$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php !-d
RewriteCond %{REQUEST_FILENAME}.php !-f
RewriteRule ^([A-Za-z0-9_]+)/([A-Za-z0-9_]+)/?$ $2.php?run_name=$1 [QSA,L]
    # on HU subdomain
#   RewriteBase /survey/admin/run/
</IfModule>

/webroot/admin/survey/.htaccess:

<IfModule mod_rewrite.c>
DirectoryIndex disabled
RewriteEngine On
RewriteRule ^/?$ add_survey.php [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/?([A-Za-z0-9_]+)/?$ index.php?study_name=$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php !-d
RewriteCond %{REQUEST_FILENAME}.php !-f
RewriteRule ^([A-Za-z0-9_]+)/([A-Za-z0-9_]+)/?$ $2.php?study_name=$1 [QSA,L]
    # on HU subdomain
#   RewriteBase /survey/admin/survey/
</IfModule>

For those of you who are into this kind of kinky stuff and maybe can help gaining deeper understanding - the debug logs:

strip per-dir prefix: /var/www/formr/webroot/admin/survey/ -> 
applying pattern '^/?$' to uri ''
rewrite '' -> 'add_survey.php'
add per-dir prefix: add_survey.php -> /var/www/formr/webroot/admin/survey/add_survey.php

looks fine... but wait...

strip document_root prefix: /var/www/formr/webroot/admin/survey/add_survey.php -> /admin/survey/add_survey.php
internal redirect with /admin/survey/add_survey.php [INTERNAL REDIRECT]

now let's just try index.html instead

strip per-dir prefix: /var/www/formr/webroot/admin/survey/index.html -> index.html
applying pattern '^/?$' to uri 'index.html'
strip per-dir prefix: /var/www/formr/webroot/admin/survey/index.html -> index.html
applying pattern '^/?([A-Za-z0-9_]+)/?$' to uri 'index.html'
strip per-dir prefix: /var/www/formr/webroot/admin/survey/index.html -> index.html
applying pattern '^([A-Za-z0-9_]+)/([A-Za-z0-9_]+)/?$' to uri 'index.html'
pass through /var/www/formr/webroot/admin/survey/index.html

and .cgi ... not seen this for some time...

strip per-dir prefix: /var/www/formr/webroot/admin/survey/index.cgi -> index.cgi
applying pattern '^/?$' to uri 'index.cgi'
strip per-dir prefix: /var/www/formr/webroot/admin/survey/index.cgi -> index.cgi
applying pattern '^/?([A-Za-z0-9_]+)/?$' to uri 'index.cgi'
strip per-dir prefix: /var/www/formr/webroot/admin/survey/index.cgi -> index.cgi
applying pattern '^([A-Za-z0-9_]+)/([A-Za-z0-9_]+)/?$' to uri 'index.cgi'
pass through /var/www/formr/webroot/admin/survey/index.cgi

and .pl ...

strip per-dir prefix: /var/www/formr/webroot/admin/survey/index.pl -> index.pl
applying pattern '^/?$' to uri 'index.pl'
strip per-dir prefix: /var/www/formr/webroot/admin/survey/index.pl -> index.pl
applying pattern '^/?([A-Za-z0-9_]+)/?$' to uri 'index.pl'
strip per-dir prefix: /var/www/formr/webroot/admin/survey/index.pl -> index.pl
applying pattern '^([A-Za-z0-9_]+)/([A-Za-z0-9_]+)/?$' to uri 'index.pl'
pass through /var/www/formr/webroot/admin/survey/index.pl

and last but not least .php ... oohh ... look... index.php...

strip per-dir prefix: /var/www/formr/webroot/admin/survey/index.php -> index.php
applying pattern '^/?$' to uri 'index.php'
strip per-dir prefix: /var/www/formr/webroot/admin/survey/index.php -> index.php
applying pattern '^/?([A-Za-z0-9_]+)/?$' to uri 'index.php'
strip per-dir prefix: /var/www/formr/webroot/admin/survey/index.php -> index.php
applying pattern '^([A-Za-z0-9_]+)/([A-Za-z0-9_]+)/?$' to uri 'index.php'
pass through /var/www/formr/webroot/admin/survey/index.php

OTHER TIPS

You can use this in /survey/.htaccess:

DirectoryIndex add_survey.php

EDIT:

<IfModule mod_rewrite.c>
DirectoryIndex add_survey.php
RewriteEngine On
RewriteBase /survey/

RewriteRule ^/?$ add_survey.php [QSA,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php !-d
RewriteCond %{REQUEST_FILENAME}.php !-f
RewriteRule ^(\w+)/(\w+)/?$ $2.php?study_name=$1 [QSA,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/?(\w+)/?$ index.php?study_name=$1 [QSA,L]

</IfModule>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top