I have a simple rewrite rule that checks if a *.gz version of the requesting file exists, and if so returns that file to the browser (it's based around this technique for serving compressed CSS & JS: https://blog.jcoglan.com/2007/05/02/compress-javascript-and-css-without-touching-your-application-code/).
Assume that my CSS & JS reside in a /cache subdirectory of my site, e.g.:
http://domain.com/cache/app.css
http://domain.com/cache/app.css.gz
http://domain.com/cache/app.js
http://domain.com/cache/app.js.gz
When the following directives are placed within the .htaccess file at webroot, everything works as expected:
AddEncoding gzip .gz
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{HTTP_USER_AGENT} !Safari
RewriteCond %{REQUEST_FILENAME}.gz -f
RewriteRule ^(.*)$ $1.gz [QSA,L]
However I'd prefer to place these rules within a separate .htaccess file that sits within that /cache directory. But pasted as-is, the rules no longer work. From what I can tell, the last RewriteCond is failing, e.g. the condition which checks if the requested filename exists.
I've tried adding RewriteBase /cache/ but that didn't seem to work. I've removed my webroot .htaccess in case there was another directive there that was conflicting. I've also tried changing the RewriteRule to:
RewriteRule ^(.*)$ /cache/$1.gz [QSA,L]
And while I think that might be correct in the end, it still doesn't work - like I said because from what I can tell it's the RewriteCond which is failing.
So I'm stumped! Any help?
Following rule should work from /cache/.htaccess:
AddEncoding gzip .gz
RewriteEngine On
# Determine the RewriteBase automatically/dynamically
RewriteCond $0#%{REQUEST_URI} ^([^#]*)#(.*)\1$
RewriteRule ^.*$ - [E=BASE:%2]
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{HTTP_USER_AGENT} !Safari
RewriteCond %{DOCUMENT_ROOT}%{ENV:BASE}/$1\.gz -f [NC]
RewriteRule ^(.+?)/?$ $1.gz [L]
Related
I am having some problem with my rewrite rule.
I have the below rewrite code
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^subcategory/([0-9a-zA-Z_-]+) child-category.php?cat=$1 [NC,L,QSA]
RewriteRule ^([^\.]+?)/?$ $1.php [NC,L]
It's working great, however when i add child-category.php in the sub folder doctor and try to access the file it doesn't work.
http://localhost:8888/community/doctor/subcategory/health -> Doesn't work
http://localhost:8888/community/subcategory/health -> working fine.
It should work in the sub folder as well, can anyone see anything obvious to why its not working?
I fixed it myself,
Here's the solution:
I copy .htaccess file in the sub folder and it's working perfect, you can apply different rewrite rules for each folder.
I've been using .htaccess files for 15 years so I feel reasonably confident with them. But today I discovered that the "file exists" check doesn't seem to work correctly with Apache's Alias command - and I can't figure out why not (I've read the docs multiple times and can't find anything that would explain this specifically).
e.g. this simple http conf:
Alias /site /sites/site1.com
e.g. with this simple htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /site/
# this never matches: (despite being used in most examples all over the web)
RewriteCond %{DOCUMENT_ROOT}/$1.extension -f
# this doesn't match either: RewriteCond %{REQUEST_FILENAME} -f
RewriteRule (.*)$ FailOnPurpose [NC]
</IfModule>
...never triggers. The intent here was:
When a request comes in...
... check if there is a file with that name and the extension "extension"
... if so: rewrite
e.g. if I request:
http://example.com/site/a.png
and there's a file:
/sites/site.com/a.png.extension
then I expected the RewriteCond to work.
If I remove all aliases from apache, and use plain direct subfolders, then it works.
You cannot use DOCUMENT_ROOT inside context of alias directory because DOCUMENT_ROOT will point to a path outside alias path and your condition will always fail.
You may use this rule:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME}.extension -f
RewriteRule (.*) FailOnPurpose [L,QSA]
I have tested it on my local Apache 2.4 within an alias .htaccess
First question so grace is much appreciated! I have a site that use to have tens of thousands of .html files that are now index.html files inside directories. For example, file1.html has become /file1/ (/file1/index.html). I don't want to spend inodes on individual files to do this, so I was hoping it'd be possible to do in a htaccess file. I suppose it'd have to test existence of the directory which isn't actually possible right?
Add this to your .htaccess in your web root / directory
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}/$1 -d # Dir exists?
RewriteRule ^(.*)\.html$ /$1/ [R=301,L]
Put this in your the directory that contains all directories:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^\/(.*)\.html$
RewriteRule .* /%1/ [R=301,L]
I do display images from
mysite.com/upload/cropped/{username}.jpg
Is there a way to create an .htaccess so missing images inside
mysite.com/upload/cropped/{username}.jpg are replaced by
mysite.com/upload/cropped/defaultAvatar.jpg ?
Thanks
Yes it can be done using this rewrite rule in DOCUMENT_ROOT/.htaccess:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(upload/cropped)/[^.]+\.jpg$ /$1/defaultAvatar.jpg [NC,L]
Assuming that there is no other .htaccess in your system in sub directories.
I am trying to do a rewrite for all requests EXCEPT if the URL points to:
An existing file
A directory with an index file
So I have the following that should have dealt with it:
RewriteCond %{REQUEST_FILENAME} !-s
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ redirect.php [QSA]
But when I navigate to a folder that contains an index.php (and yes I have checked that DirectoryIndex is set to index.php), it still performs the rewrite.
The funny thing I also found is that if I had a .htaccess in that folder with RewriteEngine on (just that), then the rewrite rule above works...
Any pointers?
You need to check for the directory part:
RewriteCond %{REQUEST_FILENAME}/index\.php !-f
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ redirect.php [QSA,L]
Also:
The funny thing I also found is that if I had a .htaccess in that folder with RewriteEngine on (just that), then the rewrite rule above works...
This is because rewrite rules in subdirectories have precedence over any rules in parent directories. So if you have a subdirectory with RewriteEngine On, with no rules, then that means that subdirectory has precedence over rewrite rules in the parent directory and there are no rules. (a bit confusing).
Try this rule in your root .htaccess:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/$1/index.php !-f
RewriteRule ^(.*?)/?$ redirect.php [L]