Reputation: 26730
I'm doing a rewrite with mod_rewrite on every request that does not match an existing file or directory. This is my configuration:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [NC,L]
This is used to map URLs like /abc/foo
or /abc/foo/10
to my app. And it works just fine.
To improve the performance, my app now stores the results of a call to /abc/foo
in a file foo
in the corresponding directory /abc
- so that after the first call the rewrite conditions do no longer apply (file does not exist) and apache directly serves the data without first invoking the app. Works fine as well.
The problem is: Requesting /abc/foo/10
does now no longer cause the URL to get rewritten, instead I get an error "404 File Not Found". The log entries state that the rewrite condition !-f
is no longer true, but actually the file /abc/foo/10
does not exist. /abc/foo
exists, but is a file, not a directory.
How can I get this to work?
(MultiViews is disabled)
Upvotes: 3
Views: 3442
Reputation: 5229
Project design is a little bit wrong - others already pointed out that it's not scallable - how could You cache a request to /abc/foo/10 if there is already a /abc/foo file?
Answer to that and to Your problem is usage of subfolders instead of files.
So instead of cache structure of:
/abc/foo
/abc/bar
...?
use:
/abc/index.html
/abc/foo/index.html
/abc/bar/index.html
/abc/foo/10/index.html
and each time create new directory with index.html
This time Apache would find out that there is /abc/foo folder but no /abc/foo/10 file in it, so RewriteCond will apply.
edit
You could also try a different way - to modify url with mod_rewrite, changing urls:
/abc/foo
/abc/bar
/abc/foo/10
to something like:
/cache/abc~foo
/cache/abc~bar
/cache/abc~foo~10
htaccess rules (roughly):
# redirecting to cache folder and removing last '/'
RewriteCond %{REQUEST_URI} ^/(abc|cde)
RewriteRule ^(.*?)/?$ /cache/$1 [L]
# recursive replacing '/' with '~'
RewriteCond %{REQUEST_URI} ^/cache/.*/
RewriteRule cache/(.*)/(.*)$ /cache/$1~$2 [L]
Your standard htaccess rules should follow
Upvotes: 2
Reputation: 703
This is because foo exists as a file and apache serves foo with the additional /10 passed as a query string. So, your application should write some additional code to the foo file, that also checks if a request includes some additional url component and then handle creation of the directory "foo" and the file 10.
Upvotes: 4
Reputation: 17871
You must be in per-dir/htaccess context w/ AcceptPathInfo on.
Therefore REQUEST_FILENAME matched the part that existed, and is not the same as REQUEST_URI.
Use the REQUEST_URI var if you don't care where the request was previously mapped in your rewritecond.
In per-vh context, these vars are always the same.
Upvotes: 3