I've used mod_rewrite
for years but never encountered this behavior before, and it's had me scratching my head for about two hours now.
Given a website directory structure like this:
www/
+-- .htaccess
+-- image.py
+-- images/
+-- somefolder/
| +-- somefile.png
+-- otherfolder/
+-- otherfile.png
And an .htaccess file that contains just this much:
RewriteEngine on
RewriteRule ^images/([a-zA-Z0-9_-]+)$ image.py?name=$1 [L,NC]
If I request a file or folder that matches the rewrite rule but doesn't exist, I get the rewrite as I expect:
http://example.com/images/foo --> http://example.com/image.py?name=foo
http://example.com/images/other-folder --> http://example.com/image.py?name=other-folder
But if the file or folder does exist, I get really bizarre results: I'd expect that either the rule applies or it doesn't, but instead of "no change" or "rewrite," I get a really bizarre partially-rewritten URL:
http://example.com/images/somefolder --> http://example.com/somefolder?name=somefolder
> GET /images/somefolder HTTP/1.1
> Host: www.example.com
> User-Agent: curl/7.54.1
> Accept: */*
< HTTP/1.1 301 Moved Permanently
< Date: Sat, 10 Feb 2018 22:39:29 GMT
* Server Apache is not blacklisted
< Server: Apache
< Location: https://www.example.com/images/somefolder/?name=somefolder
No other .htaccess
files exist, so I'm at a loss to explain why a one-liner is producing such weird results.
Disabling Option -Multiviews
(as suggested here: mod_rewrite doesnt work if file with same name as argument exists ) has no effect. The problem seems similar to the one suggested here ( mod_rewrite, can't rewrite existing file ), but I already have the rule marked as [L]
.
So does anyone know why this is happening? Is this a bug? Is there a way to tell Apache to ignore "real" directories and just apply the rewrite rule? Or do I have no choice but to redesign my site to avoid this bug/quirk?
(Also, this is a shared host, so I don't even have read access to httpd.conf
, much less the ability to change it, if something in there is causing this. My hosting company claims it's running Apache 2.2.22, but I can't know for sure.)