RewriteCond when REQUEST_URI do not match htaccess apache2 - regex

I have a multilingual wordpress website and want to redirect website of given region to given language,
xyz.de --> xyz.de/de/
xyz.co.uk --> xyz.co.uk/en/
direct access to xyz.de/de and xyz.co.uk/en are working properly. So there is no problem on wordpress side.
Now, I am trying to change the htaccess file of xyz.de and xyz.co.uk so that they redirect the website.
Considering xyz.co.uk
I want to add a RewriteCond such that whenever there is no /en trailing after xyz.co.uk it will automatically add /en.
For example xyz.co.uk/<trailing address> results in xyz.co.uk/en/<trailing address>
So far I have the following code, which somehow doesn't seem to work,
RewriteCond %{REQUEST_URI} !^/en
RewriteRule ^(.*)$ http://xyz.co.uk/en/$1 [L]
The negation of /en is not working! I have also tried
RewriteCond %{REQUEST_URI} !/en
RewriteRule ^(.*)$ http://xyz.co.uk/en/$1 [L]
Could someone tell me where I am going wrong? seems like I have gone wrong in writing RegEx and suggest if there is better way to achieve the same, that does not affect the SEO across different domains.

Use THE_REQUEST variable instead of REQUEST_URI:
RewriteCond %{HTTP_HOST} \.co\.uk$ [NC]
RewriteCond %{THE_REQUEST} !/en/ [NC]
RewriteRule ^ /en%{REQUEST_URI} [L,R=302,NE]
Make sure to keep this rule as your very first rule in .htaccess.
Change it to R=301 once you've tested.

Related

Rewriting a subdomain to root/subdomain

I currently have the following location: localhost/dir1/ex.html
I'm trying to achieve a situation where dir1.localhost/ex.html maps to that first url. The following .htaccess rule works:
RewriteCond %{HTTP_HOST} =dir1.localhost
RewriteRule ^(.*)$ http://localhost/dir1/$1 [L]
However, this is not what I am looking for as it quite obviously redirects. I want to keep the url the same (dir1.localhost).
How would one go about doing this? Many thanks in advance.
If you want your subdomain to point to the folder internally ,Remove the hostname from your rule's destination :
RewriteCond %{HTTP_HOST} =dir1.localhost
RewriteCond %{REQUEST_URI} !^/dir1
RewriteRule ^(.*)$ /dir1/$1 [L]`

removing one of parameters from adress with htaccess

I need to remove unnecessary parameter from the URL.
URL looks like: example.com/index.php?page=shop.product_details&product_id=11824&category_id=5 and I need to remove category_id parameter by htaccess 301 redirect because it doesn't change anything no matter of given number.
I tried several formulas, my last try, based on my findings here and elsewhere in google is:
RewriteCond %{REQUEST_URI} ^\?page=shop\.product
RewriteCond %{QUERY_STRING} category_id
RewriteRule (.*) /$1? [R=301,L]
But nothing works, adress stil stays the same.
Mod_rewrite is on, before this I'm making 301 redirects using RewriteRules and everything works smoothly.
You can use this rule:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^(.+?&)?category_id=[^&]*(.*)$
RewriteRule ^(index\.php)?$ %{REQUEST_URI}?%1%2 [R=301,L]

mod_rewrite / redirection with ? in a query string

I'm diving into the uses of htaccess/mod rewrite for the first time and I'm having a little bit of trouble with a redirect/mask.
I have a test directory in my root folder called modrw, in that folder is a index.php file with a nice and simple:
<?php echo $_GET['name']; ?>
In the browser if I type www.domain.com/modrw/{word}/ then the word is echoed on the page, which is what I want.
If I type www.domain.com/modrw/name={word} then I am redirected to www.domain.com/modrw/{word}/ and the word is also echoed as I intended.
However, if I direct the browser to the URL www.domain.com/modrw/?name={word}/ the word is echoed but I am not redirected to www.domain.com/modrw/{word}/ like I hoped.
How is the ? causing troubles? In the RewriteRule code below the ? is included, I've tried it a couple different ways but can't get it working.
Here is my htaccess file:
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_URI} ^/[^\.]+[^/]$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1/ [R=301,L]
RewriteRule ^modrw/?name=([^/\.]+)/?$ http://www.domain.com/modrw/$1 [R]
RewriteRule ^modrw/([^/\.]+)/?$ modrw/?name=$1
What is causing the problem, is there a specific way to include the ?, does it not pick this up at all? Am I taking completely the wrong approach?
I've also tried using Options +FollowSymlinks but I'm not entirely sure what this does nor if it's needed at all...
Remember that RewriteRuleonly matches REQUEST_URI. To match query string you must use RewriteCond with variable %{QUERY_STRING}. For ex. in your case:
RewriteCond %{QUERY_STRING} ^name=(.*)(&|$) [NC]
RewriteRule ^modrw /modrw/%1? [L,R,NC]

Problem using .htaccess to replace characters in URL

I've tried dozens of different ways of doing this but can't get any of them to work. My .htaccess does a few things, like setting a custom 404 and blocking image hotlinking. I want to do two things on the URL: add www. if it isn't there (rather annoying Facebook login can't cope with two different sources!), and replacing // with / except after http:.
I've tried this:
# Replace // with /
RewriteCond %{REQUEST_URI} (.*)(?<!http:)\/{2,5}(.*)
RewriteRule .* %1/%2 [R=301,L]
And this:
# Replace // with /
RewriteCond %{REQUEST_URI} (.*).com\/\/(.*)
RewriteRule .* %1.com/%2 [R=301,L]
And all sorts of permutations. Can anybody tell me what I'm doing wrong?
I need to do this because sometimes multiple /s are being inserted between the .com and the rest of the URL.
Thanks
I don't think http:// is part of REQUEST_URI at all (or of any other environment variable for that matter). It will get parsed out by the browser, and used to determine the nature of the request, long before the actual request is made.
I can be wrong, but I think this is not fixable on htaccess level. The link would have to be properly formatted in the first place.
Update: Looking at the information Apache passes on to PHP, I think I'm right. The protocol used to make the request is not part of the URI components we get to play with.
Here's how to force www.:
<IfModule mod_rewrite.c>
#Add WWW
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
#End Add WWW
</IfModule>
Considering what #Tim mentioned below, I would check %{REQUEST_URI} if it contains //, and that would be my RewriteCond:
<IfModule mod_rewrite.c>
#Replace // with /
RewriteCond %{REQUEST_URI} // [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
#End Replace // with /
</IfModule>
I'm not sure why you're experiencing trouble with the multiple slashes, since it should be able to resolve the file either way. However, it is possible to check for and remove them with a redirect (I've combined this with your force-www so there's at most one external redirection):
RewriteCond %{THE_REQUEST} ^[A-Z]+\s[^\s]*/{2,} [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTP_HOST} ^(www\.)?(.*)$
RewriteRule ^ http://www.%2%{REQUEST_URI} [R=301,L]
Note that %{REQUEST_URI} has the duplicate slashes removed (only in mod_rewrite, this isn't true for scripts later on), so we can use it in the redirect to automatically take care of that issue for us. The original request will still have the multiple slashes though, so we check for them by examining %{THE_REQUEST}.

Tricky URL rewrite, regex .htaccess

I have a tricky issue redirecting some URLs internally for my site.
The situation is this, I currently have a URL like example.com/check/youtube.com which internally redirects to check.php?domain=youtube.com using the following mod_rewrite code:
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,NC,L]
RewriteRule ^offline offline.php [NC,L]
RewriteRule ^error error.php [NC,L]
RewriteRule ^check/(.*)$ check.php?domain=$1 [NC,L]
However I would also like to be able to redirect to check.php using a URL like example.com/youtube.com. Unfortunately it is just beyond me to figure it out.
I have a directory /assets/ with all the CSS, JS, etc. which shouldn't be affected.
Thanks
Try this rule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^[^/.]+\.[^/]+$ check.php?domain=$0 [L]
This rule rewrites any request with a URL path of the form [^/.]+\.[^/]+ (a string that contains at least one dot but no slashes at all) that cannot be mapped to an existing file to your check.php.
As you want to redirect "example.com/youtube.com" does that mean you wish to redirect pretty much anything? What is specifically allowed to be passed, e.g. would I be allowed to pass "example.com/youtube.com/foobar.php" for a redirect to check.php?