RewriteRule to remove version number - apache

I have implemented a cache busting solution on a site where a version number is added to the end of the file name, before the file extension. However I am having an issue with one of the rules not working.
Typical requests:
/static/deploy/styles/site_78_direct.min.0.css
/static/deploy/styles/ie/site_78_direct.0.css
I need the above to be redirected to the following:
/static/deploy/styles/site_78_direct.min.css
/static/deploy/styles/ie/site_78_direct.css
I came up with the following which half works:
RewriteRule ^/static/deploy/styles/ie/(.*).([0-9]+).css$ /static/deploy/styles/ie/$1.css [L]
RewriteRule ^/static/deploy/(scripts|styles)/(.*).min.([0-9]+).(js|css)$ /static/deploy/$1/$2.min.$4 [L]
The above redirects properly but I want it to ignore the following:
/static/deploy/styles/ie/site_78_direct-blessed1.css
I basically only want to redirect if there is a number between fullstops, i.e. .0.css
Any help would be greatly appreciated.

Make sure to escape the dot otherwise it will match any character.
Besides just this single rule should work for both cases:
RewriteRule ^(/?static/deploy/.+?)\.\d+\.(js|css)$ $1.$2 [L,NC]

Related

Block direct access to .php files, less the index.php file and ajax.php file

been looking for your help, i found a method, but it is not as i wish. if someone can help me.
What I want is that nobody can enter a direct URL with .php
example when I enter my domain.com/buy/product.php, I want it to be forbidden,
I was looking for information here, I found this code that worked for me but in .htaccess
RewriteEngine On
RewriteCond %{THE_REQUEST} "^.+? [^?]+\.php(?:[?/# ]|$)" [NC]
RewriteRule !^index\.php$ - [F,L,NC]
it worked fine for me, but the problem that I in a directory /include/ajax.php , I use an ajax. and it gives me error to execute the ajax by browsing.
Now what I'm thinking how to make it work with that htaccess code that you can enter the index.php and /include/ajax.php, I tried all means but it does not work for me.
In another case if you know any code to add to my php or how to do for my version which is version 7.3, but without ruining my code.
Rather than giving you the answer straight out, I'm going to give you some hints so that you aren't copying code you don't understand.
Each RewriteRule has three parts:
the pattern to match against the URL sent by the browser
the URL to rewrite to
an optional set of flags for extra options
Before each rule, you can optionally have one or more RewriteCond lines which apply extra conditions to the rule; each has three parts:
a variable to match against
the pattern to match
an optional set of flags for extra options
The most important flag in this case is [F], short for [forbidden], which says "if the rule matches, instead of rewriting or redirecting, just server a 403 response.
You should very rarely need to test against %{THE_REQUEST}, which is a raw version of the request line from the browser; much more often, you want %{REQUEST_URI} and/or %{QUERY_STRING}.
The patterns in both RewriteRule and RewriteCond can be negated (i.e. "must not match this pattern") by starting them with !
So, if you wanted to return a 403 for all URLs ending ".bad", except for URLs ending "not.bad" or "only-a-little.bad", you could write this (note that $ is the way to say "must end here" in the regex patterns):
RewriteCond %{REQUEST_URI} !not.bad$
RewriteCond %{REQUEST_URI} !only-a-little.bad$
RewriteRule .bad$ - [F]
Hopefully it should be straight-forward enough to see how to adapt that to your requirements.
The full list of options and variables available is in the Apache manual.
After 2 days of looking for some code, I was able to read and understand.
study how htaccess works.
Thanks to the users who guided me, I found the solution.
Although my title is not quite correct.
My intention was always to block all .php that always the user wanted to enter directly by .PHP, I had found the code above, but it did not work with a specific file in the /include/ajax.php folder, exactly it was an ajax, I could not find solution.
exactly it was an Ajax, I could not find the solution to make it work.
Until I managed to solve this way.
RewriteEngine on
RewriteCond %{THE_REQUEST} ajax\.php [NC]
RewriteRule ^ - [NC,L]
RewriteCond %{THE_REQUEST} .+\.php [NC]
RewriteRule ^ - [F,L]
This causes all .php to be blocked, except the index.php and the /include/ajax.php file.
This is how it worked for me.
If I am right or wrong, can you give me some guidance.
I leave this in case someone might find it useful in the future.
I was always recommended to route my php, that I would forget about these problems.
I will keep it in mind as I move forward in the future, to route my php.

mod_rewrite always uses index.php

I'm rebuilding one of my websites (redesign + pdo instead of regular mysql).
So far so good, everything works out, except from 1 RewriteRule in .htaccess.
All of my url-rewrites are going fine with this kind of rule:
RewriteRule pages/(.*)/ index.php?type=page&page=$1&%{QUERY_STRING}
RewriteRule pages/(.*) index.php?type=page&page=$1&%{QUERY_STRING}
(note: making use of index.php)
For my shopping cart, I want to use a clean, separate page, with this rule:
RewriteRule ^shop/shopping-cart-overview/$ /pages/shoppingcart/overview.php
RewriteRule ^shop/shopping-cart-overview$ /pages/shoppingcart/overview.php
Problem: instead of using the file "/pages/shoppingcart/overview.php", it still uses index.php as in the other rules.
I uploaded full htaccess in txt, so you can read it yourself:
www.mymobisite.be/htaccess.txt
Thank you in advance for your time, help and advice!
Tom V.
The problem is the order of the rules. The shop/shopping-cart comes before the pages rule.
The first rule rewrites shop/shopping-cart-overview/ to /pages/shoppingcart/overview.php, which in turn is rewritten to index.php?type=page&page=shoppingcart/overview.php.
You should either reorder your rewrite rules or use the [L] modifier (L=last).
RewriteRule ^shop/shopping-cart-overview/$ /pages/shoppingcart/overview.php [L]
RewriteRule ^shop/shopping-cart-overview$ /pages/shoppingcart/overview.php [L]

RewriteRule to remove all slashes

Hi I have tried everything and can't find a solution.
When a user access this URL
http://www.mydomain.com/B/13/B0/BD62CB5382479EFE5EE122BE6FB.jpg?pid=5623
I want it to rewrite it to (not using redirect)
http://www.mydomain.com/B13B0BD62CB5382479EFE5EE122BE6FB.jpg?pid=5623
how do I remove the '/' ?
Your help is very appreciated .
Try with this rule (your htaccess must be located in your document root folder)
RewriteCond %{QUERY_STRING} ^pid=([0-9]+)$
RewriteRule ^/?([^/]+)/([^/]+)/([^/]+)/([^/]+)\.jpg$ /$1$2$3$4.jpg?pid=%1 [L]
EDIT: this code will only work with urls like in your example (with 3 slashes and pid in query string)
EDIT2: to simplify query string if you have multiple params (maybe in different order) we don't need RewriteCond anymore but QSA flag instead
RewriteRule ^/?([^/]+)/([^/]+)/([^/]+)/([^/]+)\.jpg$ /$1$2$3$4.jpg [L,QSA]
If that rule should remove any number of slashes, not just a fixed number, you have to create a loop. TO do so, you can use the \[N\] flag, which will cause the rewriting process to start all over with the current URL. Be careful when doing this, this could lead to infinite loops when done wrong ;)
RewriteRule ^/?(.*)/(.*) $1$2 [N]
Should work however. You can test it with this online tool.
[Edit]: Complete rewrite - I forgot about the [N] Flag ;)

Htaccess Match Random 6 characters, with exceptions?

Alright, so I've been trying to wrap my head around (what I believe to be) a simple mod_rewrite case. Maybe it's not, but I'm hoping you can help me with that, Stack Overflow.
So what I want is this: there are several folders that need to be ignored (ie, "css", "js", "bootstrap", etc). If the url string doesn't match those, I want to check if it's a string of exactly six letters and numbers, and redirect that to one url. Otherwise, it gets redirected to another url.
This is what I have:
RewriteCond %{REQUEST_URI} !^/(index\.php|images|robots\.txt|bootstrap|phpmyadmin|css|js|font|recaptchalib.php|uploads)/
RewriteRule ^(a-z0-9+){6}$ /index.php/download/index/$1 [L]
RewriteRule ^(.*)$ /index.php/$1 [L]
If I take out the middle line, it works fine except I don't get the "match 6 random characters" functionality. With the middle line, I get a 500 error on every page.
Could someone help me out please?
You need to repeat the condition. A RewriteCond only applies to the immediately following RewriteRule. So you're second rule doesn't exclude all those folders in the pattern that you have in your condition. Try:
RewriteCond %{REQUEST_URI} !^/(index\.php|images|robots\.txt|bootstrap|phpmyadmin|css|js|font|recaptchalib.php|uploads)/
RewriteRule ^(a-z0-9+){6}$ /index.php/download/index/$1 [L]
RewriteCond %{REQUEST_URI} !^/(index\.php|images|robots\.txt|bootstrap|phpmyadmin|css|js|font|recaptchalib.php|uploads)/
RewriteRule ^(.*)$ /index.php/$1 [L]
You should let CodeIgniter handle this. Keep your .htaccess for routing to the index.php front controller, and use route(s) to handle the URI and where it should go from there.
This is especially true because now ANY six-letter URI is going to be defaulted. What if you have a controller like example.com/bloggers? It will always be assumed to be a download item, even if it's a real controller URI.
The "easiest" option (read: option that does not conflict with existing controllers/routes) is to utilize the 404_controller to check the URI and see if it's a valid download URL. Then you can run the appropriate code.
To explain a likely reason why your .htaccess code is not working: your regular expression for matching six alpha-numeric characters is wrong. Here's what you need:
^([a-zA-Z0-9]{6})$
This regex can be used as a CodeIgniter route, also, if you go that route (heh). Just remove the ^$ beginning/end characters, as CI puts them there for you.
As mentioned by Jon Lin, you also need to duplicate RewriteCond conditionals, as they are only good for one RewriteRule. After one, the conditionals reset.

Apache rewrite rules for creating user friendly urls

I am relatively new to rewrite and cant get the following to work. (clearly my domain is not testsite, but dont want my proper one going public as its not finished yet.)
i want to rewrite testsite/fishing/region/region.php?region=fife
to:
testsite/fishing/fife.php
then want to rewrite testsite/fishing/region/fishery/fishery.php?url=goldenloch
to
testsite/fishing/fife/goldenloch.php
I am using the following rules
RewriteRule ^fishing/([^/]*)\.php$ /fishing/region/region.php?region=$1 [L]
RewriteRule ^fishing/([^/]*)/([^/]*)\.php$ /fishing/region/fishery/fishery.php?url=$2&region=$1 [L]
each rule works on its own but when combined only the last one work. I have added the [L] flag which i believe should stop any other rewrite rules of the condition is met. however this still doesnt work.
I tried this and it seemed to work:
RewriteRule ^/fishing/([^/]*)\.php$ /fishing/region/region.php?region=$1 [R,L]
RewriteRule ^/fishing/([^/]*)/([^/]*)\.php$ /fishing/region/fishery/fishery.php?url=$2&region=$1 [R,L]
The only difference from yours (I think) is the leading / and I used redirects (R) just to see it was working. You should be able to remove the R so the user doesn't see the real url in his browser.
Just in case you're not, I would recommend using a command line tool (like curl) and not a browser to test this, just so you avoid any caching or other annoyances:
curl -vv 'http://localhost/fishing/fife/goldenloch.php'
You'll see the Location header in the server's response, that's the redirect at work. In my case, I see:
Location: http://localhost/fishing/region/region.php?region=fife
and
Location: http://localhost/fishing/region/fishery/fishery.php?url=goldenloch&region=fife
Turns out i needed to do
RewriteRule ^fishing/([^/]*)/([^/]*) fishery.php?url=$2&region=$1 [L]
RewriteRule ^fishing/([^/]*) region.php?region=$1 [L]
with the longer query first and it worked fine.