I currently have the following in my .htaccess file which rewrites all files names so I can limit access to my media.
#RewriteCond %{REQUEST_FILENAME} -s
#RewriteRule ^wp-content/uploads/(.*)$ dl-file.php?file=$1 [QSA,L]
However, I would like specific files to be ignored. For example: ^wp-content/uploads/2022/12/image-26.png and ^wp-content/uploads/2022/11/horse47.jpg
How can I update my rewrite rules to skip those specific files (and others).
I tried rewriting the original files after the above (3rd line) but does not work.
Solved thank you. Mr White
I tried rewriting the original files after the above (3rd line) but does not work.
"After" is too late, the request will have already been rewritten to your script! You would need to rewrite the files before your existing rule.
For example:
RewriteRule ^wp-content/uploads/2022/12/image-26\.png$ - [L]
RewriteRule ^wp-content/uploads/2022/11/horse47\.jpg$ - [L]
# Existing directives go here...
The L flag prevents the following rules from being processed.
Don't forget to backslash-escape the literal dot and include the end-of-string anchor on the regex.
Alternatively, add exceptions (conditions) to the existing rule. For example:
RewriteCond $1 !^2022/12/image-26\.png$
RewriteCond $1 !^2022/11/horse47\.jpg$
RewriteCond %{REQUEST_FILENAME} -s
RewriteRule ^wp-content/uploads/(.*) dl-file.php?file=$1 [QSA,L]
The ! prefix negates the expression. So it is successful when it does not match.
Related
I have a sample link:
https://stackoverflow.com/test/index.php/product/01-00030am-1a1y
I want remove /product it become to
https://stackoverflow.com/test/index.php/01-00030am-1a1y
This is .htaccess
RewriteCond %{HTTP_HOST}
RewriteRule ^test/index.php/product/(.*)$ test/index.php/$2 [R=301]
But it never work, how to fix it
I believe its $1 not $2
$2 would refer to the second matched group which you haven't set it. Try:
RewriteCond %{HTTP_HOST}
RewriteRule ^test/index.php/product/(.*)$ /test/index.php/$1 [R=301,L]
The [L] flag causes mod_rewrite to stop processing the rule set. In most contexts, this means that if the rule matches, no further rules will be processed. Docs
Check here or here for more info about .htaccess rules.
Also please make sure that you have mod_rewrite on otherwise, it will not work. If not, I guess you can add it in your .htaccess
RewriteEngine On
RewriteCond %{HTTP_HOST}
RewriteRule ^test/index.php/product/(.*)$ /test/index.php/$1 [R=301,L]
As an alternative, If you're using WooCommerce, give woo-permalink-manager plugin a try.
I'm trying to minify css/js files if there is exists minified css/js copy of this file with .min. in it's name though .htaccess. I'm using following code:
RewriteCond %{DOCUMENT_ROOT}/$1.min.$2 -f
RewriteRule ^([^.]+)\.(css|js)$ /$1.min.$2 [L,NC]
So, when I go to /current/assets/css/main.css I see /current/assets/css/main.min.css instead. Is there any way to make it only if I add some GET parametr to url? For example /current/assets/css/main.css?t=1 gives minified file, but /current/assets/css/main.css not. I tried:
RewriteCond %{DOCUMENT_ROOT}/$1.min.$2 -f
RewriteRule ^([^.]+)\.(css|js)\?t=[0-9].*$ /$1.min.$2 [L,NC]
But it's not working. Guess I mabye should use %{QUERY_STRING} but can't get how. Thanks for advices.
I found how to do that. It was all about %{QUERY_STRING}.
RewriteCond %{QUERY_STRING} ^t=([0-9]*)$
RewriteCond %{DOCUMENT_ROOT}/$1.min.$2 -f
RewriteRule ^([^.]+)\.(css|js)$ /$1.min.$2 [L,NC]
I am using WordPress on RHEL6, and have some rewrites so that CSS is hosted at http://servername/css rather than http://servername/wp-content/themes/themename/css/.
I am moving from an Nginx install to Apache, and own the server. In that case, I don't want to use htaccess for redirects, I just want them in the httpd.conf. If I enable htaccess and put this in there, it all seems to work fine.
In my conversion, I added the / at the beginning of the rule. The current code below works for everything, except real files not handled by the css, js, img, font rules. As in, things that are actually hosted under /assets or other directories. I have a feeling this is due to the REQUEST_FILENAME, and if anything, a slash missing for the next rule - but I can't seem to figure it out.
RewriteRule ^/index\.php$ - [L]
RewriteRule ^/css/(.*) /wp-content/themes/themename/css/$1 [QSA,L]
RewriteRule ^/js/(.*) /wp-content/themes/themename/js/$1 [QSA,L]
RewriteRule ^/img/(.*) /wp-content/themes/themename/img/$1 [QSA,L]
RewriteRule ^/font/(.*) /wp-content/themes/themename/font/$1 [QSA,L]
RewriteRule ^/plugins/(.*) /wp-content/plugins/$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
If I try to access http://servername/assets/image.png, I actually am being rewritten to /index.php, from the rewrite log
init rewrite engine with requested uri /assets/311.jpg
applying pattern '^/index\.php$' to uri '/assets/311.jpg'
applying pattern '^/css/(.*)' to uri '/assets/311.jpg'
applying pattern '^/js/(.*)' to uri '/assets/311.jpg'
applying pattern '^/img/(.*)' to uri '/assets/311.jpg'
applying pattern '^/font/(.*)' to uri '/assets/311.jpg'
applying pattern '^/plugins/(.*)' to uri '/assets/311.jpg'
applying pattern '.' to uri '/assets/311.jpg'
RewriteCond: input='/assets/311.jpg' pattern='!-f' => matched
RewriteCond: input='/assets/311.jpg' pattern='!-d' => matched
rewrite '/assets/311.jpg' -> '/index.php'
/assets is a real folder that has real images. By looking at this log, it would make me think that !-f should have said 'yes, this is a file', rather than passing it to index.php afterwards.
After doing some research and testing, I found this was easily related to the difference in scope between htaccess and httpd.conf, and needing to include DOCUMENT_ROOT
If you are using htaccess in /var/www/html/test/, you will only be looking in /test, and therefore something like test/assets/image.jpg would pass, because /assets/image.jpg is valid.
In the case of httpd.conf though, unless you use these rules inside a Directory directive, you are not pathed to the virtual host folder. So in my case, it was looking for /assets/image.jpg off the root of the server.
To get around this, I just had to include %{DOCUMENT_ROOT} before %{REQUEST_FILENAME}.
My final block in httpd.conf looks like:
RewriteRule ^/index\.php$ - [L]
RewriteRule ^/css/(.*) /wp-content/themes/themename/css/$1 [QSA,L]
RewriteRule ^/js/(.*) /wp-content/themes/themename/js/$1 [QSA,L]
RewriteRule ^/img/(.*) /wp-content/themes/themename/img/$1 [QSA,L]
RewriteRule ^/font/(.*) /wp-content/themes/themename/font/$1 [QSA,L]
RewriteRule ^/plugins/(.*) /wp-content/plugins/$1 [QSA,L]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
I have been tearing my hair out trying to solve an issue with htaccess on wordpress network site and i've gained so much information from stackoverflow in the past that i thought this would be the best place to ask. And apologies up front if im not posting correctly, it my first time.
here are the specifics of my setup (i cannot show or allow access to the site as i have agreed to an NDA of sorts)
there are 2 sites. the first is the root site "/" and the second is "/mythoughts/" as shown in network admin.
the "/mythoughts/" site is a replacement for an old custom blog someone built that uses variables in the url (custom)
the themes i am using are twentyten and roots (obviously roots doesnt do tidy url rewrites as its on a network setup)
the problem is this.
first "index.php is being removed from the url (its not a problem, but i think it might cause problems when i try to do other rewrites.)
second, the old site has variables in the urls in 2 instances.
the first instance is this
www.thesite.com/mythoughts/index.php?year=2010&month=9
which i need to rewrite as
www.thesite.com/mythoughts/2010/9
first of all the index.php is automatically removed
i have tried so many different things like
RewriteRule ^mythoughts/index.php?year=(.*)&month=(.*)$ mythoughts/$1/$2 [R=301,L]
does not work
the second instance is this
www.thesite.com/mythoughts/index.php?thought=101
which should rewrite to
www.thesite.com/mythoughts/title-of-the-post
i have a script that can match the url variable to the title of the post (and replace remove illegal characters) but the rewrites just do not work.
here is the htaccess i currently have (a bare wordpress)
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
# uploaded files
RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-includes/ms-files.php?file=$2 [L]
# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^[_0-9a-zA-Z-]+/(wp-(content|admin|includes).*) $1 [L]
RewriteRule ^[_0-9a-zA-Z-]+/(.*\.php)$ $1 [L]
RewriteRule . index.php [L]
</IfModule>
#END WordPress
if anyone can help in pointing me in the right direction on this whole htaccess thing (which i have been struggling with for the last few weeks) i would be totally greatful.
thanks in advance guys and girls.
In the first instance, you have:
RewriteRule ^mythoughts/index.php?year=(.*)&month=(.*)$ mythoughts/$1/$2 [R=301,L]
But you can't match against the query string in a rewrite rule. Also, since you've got a rule to rewrite it back, you'll just create a redirect loop. You need to match against the actual request and not the URI.
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /mythoughts/index\.php\?year=([^&]*)&month=([^&\ ]*)
RewriteRule ^ mythoughts/%1/%2 [R=301,L]
As for:
i have a script that can match the url variable to the title of the post (and replace remove illegal characters) but the rewrites just do not work.
I don't see any script in your htaccess, maybe if you include the rule or the script.
after continuing my search even though i posted the question on stack (the great) overflow
here is what i ended up with.
in the first instance with the double url string the answer was
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /mythoughts/index\.php\?year=([0-9\-]+)&month=([0-9\-]+)\ HTTP/ [NC]
RewriteRule ^index\.php$ http://site.co.uk/mythoughts/%1/%2? [R=301,L]
so the initial url would have been
www.site.co.uk/mythoughts/index.php?year=2010&month=12
and the rewrite result is
www.site.co.uk/mythoughts/2010/12/
PERFECT !!!!
in the second instance, first to answer Jons question.
the script is written with php, it scans through the old database concatin strings from the id of the url variable, as example the variable in the url below
www.site.co.uk/mythoughts/index.php?though=21
this post or database entry has a title, and in wordpress the title is used in the permalink
so it would be
www.site.co.uk/mythoughts/sublime-and-powerful-outcomes
the script takes the id for the first condition of the rewrite, and puts the id in its place. The second part takes the title of the post and swaps spaces with dashes and special characters removed.
which results in the new url.
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /mythoughts/index\.php\?thought=21
\ HTTP/ [NC]
RewriteRule ^index\.php$ http://site.co.uk/mythoughts/sublime-and-powerful-outcomes? [R=301,L]
thanks to Jon for taking the time to answer this.
hope this helps someone
Im installing phpancake,
there is a folder there shema like this
application/
install/
library/
public/
sql_schema/
install.html
install.php
What does this rule mean?
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /vote/public/index.php [NC,L]
The rewrite has two parts. The first one specifies that if the requested filename is a regular file with a size greater than 0 (-s), a symbolic link (-l) or a directory (-d), rewrite to nowhere, eg. take no action. [NC,L] means that the rule is non case sensitive and the last rule that these conditions match.
All other requests are forwarded to /vote/public/index.php.
The purpose of this rewrite is that an actual, existing file can be fetched from the server without interference. Without the first rule, every file request (css and js files, images etc) would go to index.php which would mess things up pretty badly.
Usually this is written in one declaration, though. You can negate the conditions, and then the [OR] statemens can be taken out also:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-s
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /vote/public/index.php [NC,L]
This is equivalent to the original statement.
Those are mainly standard rewrites which check if the requested file (or directory or symbolic link) exists on disk, in which case the file/directory/etc. should be used.
All other matches should go to /votes/public/index.php
The first rule will pass through all requests that can be mapped to a regular file with a size greater than zero (-s), a symbolic link (-l) or a directory (-d). Every other request is fetched by the second rule and rewritten to /vote/public/index.php.