Remove first part of url - .htaccess

I am quite sure that this is the right way, but it's not working. I'm trying to rewrite this
domain.com/halloo/wp-content/uploads/image.jpg
to
domain.com/wp-content/uploads/image.jpg
using this in the .htaccess
RewriteRule ^/halloo/wp-content/(.*)$ /wp-content/$1 [R=301,L]
I can't figure out why it's not working.

The regex targets for rewrite rules in htaccess files won't start with a /, which means your rule will never match (because there's never a request that starts with /).
Also, your rule takes the request /halloo/wp-content/foo and redirects the browser to /wp-content/foo. If you want to rewrite it internally so that /halloo/wp-content/foo remains in the URL address bar, remove the R=301, part from the flags.
RewriteRule ^halloo/wp-content/(.*)$ /wp-content/$1 [L]
This means you must request domain.com/halloo/wp-content/uploads/image.jpg in the browser. If you actually wanted it the other way around, just swap the "from regex" and the "to URI":
RewriteRule ^wp-content/(.*)$ /halloo/wp-content/$1 [L]
Edit:
To get rid of the /halloo/ from the browser's address bar, you need something like this:
RewriteCond %{THE_REQUEST} \ /+halloo/wp-content([^ \?]+)
RewriteRule ^ /wp-content$%1 [L,R]

Related

Rewriting Dynamic URLs in htaccess not working

I want to rewrite
mypage.com/country/country.php?country=something
to
mypage.com/country/something
in the address bar, using htaccess
I've tried many things and looked everywhere and the closest I've got is:
RewriteCond %{QUERY_STRING} country=([^\&]*)
RewriteRule ^country.php$ /country/%1? [R,L]
But this just produces a rewrite loop that alternates between the two links above and I don't understand why.
I want both
mypage.com/country.php?country=something
and
mypage.com/country/something
when entered, to show
mypage.com/country/something
in the address bar
Any help?
If you have a rewrite loop it suggests that besides that rule, you also have a rule that translates it back. You'll need the 'ugly' url to only trigger when it is an external request. The easiest way to do that is by matching %{THE_REQUEST}.
#Ugly to fancy url; should be R=301 when it works
RewriteCond %{THE_REQUEST} ^(GET|POST)\ /country\.php\?country=([^\&]*)\ HTTP
RewriteRule ^country.php$ /country/%2? [R,L]
RewriteRule ^country/(.*)/?$ /country.php?country=$1 [L]

Surprising rewriting of URL by htaccess rule

I've zeroed my problem and I've specific question.
With only the following code in the .httaccess why index2.php gets called if I type in my URL as www.mysite.com/url2 ?
RewriteEngine On
RewriteCond %{REQUEST_URI} (.html|.htm|.feed|.pdf|.raw)$ [NC]
RewriteRule (.*) index2.php [L]
I've also tested it at http://www.regextester.com and should not replace it with index2.php:
In the end I want this rule to skip any URL starting with /url2 or /url2/*.
EDIT: I've made screen recording of this problem: http://screenr.com/BBBN
You have this in your .htaccess:
RewriteEngine On
RewriteCond %{REQUEST_URI} (.html|.htm|.feed|.pdf|.raw)$ [NC]
RewriteRule (.*) index2.php [L]
What it does? it rewrites anything that ends with html, htm, feed , pdf , raw to index2.php. So, if you are getting results as your URL is ends with those extensions, then there are two possible answers:
There is another rewrite rule in an .htaccess in upper directories (or in server config files) that causes the URL to be rewritten.
Your URL actually ends with those extensions. have in mind, what you enter in your address bar, will be edited and rewritten. For example, if you enter www.mysite.com/url2 in your address bar and that file doesn't exist on server, your server will try to load the proper error document. So, if your error document is /404.html, it will be rewritten to index2.php at the end.
Update:
I think it's the case. create a file named 404.php in your document root. Inside your main .htaccess (in your document root), put this:
ErrorDocument 404 /404.php
delete all other ErrorDocument directives.
inside 404.php , put this:
<?php
echo 'From 404.php file';
?>
Logic behind it:
When you have a weird behavior in mod_rewrite, the best solution in my experience is using rewrite log. to enable rewrite log put this in your virtualhost or other server config directives you may choose:
RewriteLogLevel 9
RewriteLog "logs/RewriteLog.log"
be careful: the code above will enable rewrite log and start logging at highest level possible (logging everything). It will decrease your server speed and the log file will become huge very quickly. Do this only on your dev server.
Explanation: When you try to access www.mysite.com/url2, Apache gives your URL to rewrite module. Rewrite module checks if any of RewriteRules applies to your URL. Because you have one rule and it doesn't apply to your URL, it tries to load the normal file. But this file does not exit. So, Apache will do the next step which is showing the proper error message. When you set a custom error file, Apache will run the test against the new address. For example if error document is /404.html, Apache checks whether your rule applies to /404.html or not. Since it does, it will rewrite it.
The point to remember is apache will do this every time there is change in URL, whether the change is made by rewrite module or not!
The rule you list should work as you expect if this is the only rule. Fact is that theory is fun, but apparently it doesn't work as expected. Please note that . will match ANY CHARACTER. If you want to match the full stop/period character, you'll need to escape it. That's why I use \.(html|htm|feed|pdf|raw)$ instead of (.html|.htm|.feed|.pdf|.raw)$ below.
You can add another RewriteCond that simply doesn't match if the url starts with /url2, like below. This might not be a viable solution if there are lots of urls that shouldn't be matched.
RewriteCond %{REQUEST_URI} !^/url2
RewriteCond %{REQUEST_URI} \.(html|htm|feed|pdf|raw)$ [NC]
RewriteRule (.*) index2.php [L]
To get a better understanding of what is happening you can alter the rule to something like this. Now simply enter the urls you dont want to be matched in the url bar and inspect the url bar after the redirect happens. In the url-parameter you now see what url actually triggered this rule to match. This screencast shows you a similar version working with a sneaky rewriterule that is working away on the url.
#A way of finding out what is -actually- matched
RewriteCond %{REQUEST_URI} \.(html|htm|feed|pdf|raw)$ [NC]
RewriteCond %{REQUEST_URI} !/foo
RewriteRule (.*) /foo?url=$1 [R,L]
You can decide to match the %{THE_REQUEST} variable instead. This will always contain the request itself. If something else is rewriting the url, this variable doesn't change, meaning you can use this to overwrite any changes. Make sure the url won't be matching itself. You would get something like below. An example screencast can be found here.
#If it doesn't end on .html/htm/feed etc, this one won't match
RewriteCond %{THE_REQUEST} ^(GET|POST)\ /.*\.(html|htm|feed|pdf|raw)\ HTTP [NC]
RewriteCond %{REQUEST_URI} !^/index2\.php$
RewriteRule (.*) /index2.php [L]

.htaccess url rewriting and redirect 301

At the moment we have one page which shows a list of links
each link has got its own ID number
each link gets opened with the file info.php?ID=X
for example:
www.mysite.com/info.php?ID=1 shows the link "weather italy"
www.mysite.com/info.php?ID=2 shows the link "weather france"
Since we have several links for "weather italy" and "weather france" we would like to rewrite new urls (weather-italy and weather-france) in .htacces
Whith the new urls we would have the folowing structure:
www.mysite.com/weather-italy/info.php?ID=1
www.mysite.com/weather-france/info.php?ID=2
With the following code we tell the server to rewrite the urls and call the original file:
RewriteRule ^weather-italy/info.php?$ info.php [NC,L]
RewriteRule ^weather-france/info.php?$ info.php [NC,L]
This works fine.
To avoid double indexing we want to redirect 301 the old link to the new link.
We have achieved that with the following code:
RewriteCond %{THE_REQUEST} \?ID=1
RewriteRule ^info\.php$ http://www.touristinfo.fr/weather-italy/info\.php [L,R=301]
RewriteCond %{THE_REQUEST} \?ID=2
RewriteRule ^info\.php$ http://www.touristinfo.fr/weather-france/info\.php [L,R=301]
This also does the job but combined with the first part of the script is produces a never ending loop.
What is wrong with our code?
Thanks a lot for your help :)
%{THE_REQUEST} is supposed to only match if the url you want to match is an external request. Your problem is that the regex you made is not specific enough.
Let's examine what happens. You go to example.com/info.php?ID=2. The first two rules don't match, but the 4th one does. You end up with a redirect to example.com/weather-france/info.php?ID=2.
This goes through your .htaccess again. The second rule matches, and internally rewrites it to info.php?ID=2. The [L] flag doesn't make a difference here, because the url will be pulled through .htaccess until it stops changing. On the second cycle through .htaccess, the url will now match the 4th rule, even though the external request contained /weather-france/info.php?ID=2. ID=2 is in the external request too, and the internal rewrite is now info.php again.
The fix is to make %{THE_REQUEST} match enough so that the rewritten url doesn't match it anymore.
On a further note: Familiar yourself with the difference between regex and strings in RewriteRules and RewriteConds. You escaped a dot in a string, while leaving a dot in a regex unescaped. The ? is "match the previous character 0 or 1 times", not a question mark literal. The query string cannot be matched in the first argument of RewriteRule.
You'll end up with:
RewriteRule ^weather-italy/info\.php$ info.php [NC,L]
RewriteRule ^weather-france/info\.php$ info.php [NC,L]
RewriteCond %{THE_REQUEST} ^(GET|POST)\ /info\.php\?ID=1
RewriteRule ^info\.php$ http://example.com/weather-italy/info.php [L,R]
RewriteCond %{THE_REQUEST} ^(GET|POST)\ /info\.php\?ID=2
RewriteRule ^info\.php$ http://example.com/weather-france/info.php [L,R]

Pretty url doesn't show in url-bar

I have an htaccess file with several redirects, Now I want to create a pretty url for some link. I tried the following sentence and it does nothing:
RewriteEngine On
RewriteRule ^/example1.html /?page_id=100 [NC]
When I type www.MyDomain.com/?page_id=100 in my browser, the site shows, but the url still looks the same as I typed it. How would I change my sentence to show example.html in the url-bar instead of ?page_id=100 ?
Thanks in advance
You have a rule that says:
When the browser requests: /example1.html
Then show them: /?page_id=100
It goes one way, it doesn't do anything if the browser requests /?page_id=100. If you want to do something about a browser requesting the query string URL, *you need a rule to tell mod_rewrite to do it*:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(index\.php)?\?page_id=100($|\ |&)&?([^\ ]*)
RewriteRule ^ /example1.html?%3 [L,R=301]
Also, you may want to get rid of the / in the pattern of your rule:
RewriteRule ^example1.html /?page_id=100 [NC]
Leading slashes are stripped off when matching against rules in an htaccess file.

Mod rewrite to redirect except on a certain page

Trying to write a rewrite rule in my htaccess so that any request to /en/shop/index.html or /fr/shop/index.html stays on the server, but if the user goes to any other page it redirects to a different server. Here's what I've got so far and it doesn't work.
RewriteRule ^(.*)/shop/(.*) [L]
RewriteRule ^(.*)$ http://www.newwebsite.com/$1 [R=301]
Add a dash to tell the first RewriteRule that you want the matches to be passed through unchanged:
RewriteRule ^.*/shop(/.*)?$ - [L]
I also removed the first set of parentheses since you're not using the results of the match so there's no need to store the matched patterns. I assumed you might need to match /shop without a trailing slash so that's why the (/.*)? section is there.

Resources