mod_rewrite rules, how to test for 'not a string'? - apache

I have a blog installed in www.foo.com/wp/ and would like all requests that go to any page that doesn't start with /wp/ to be redirected to www.foo.com/wp/ (without preservation of the URL).
E.g.:
www.foo.com/bar/baz/hello.gif > www.foo.com/wp/
Also, at the same time, I need the URL to have www. added if it doesn't (which might be where my rules are getting confused)
At the moment, I have:
RewriteCond %{HTTP_HOST} !^www.foo.com [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.*) http://www.foo.com/$1 [R=permanent]
RewriteRule ^(?!wp)/(.*)$ http://%{HTTP_HOST}/wp/($2) [R=permanent]
But I think this is currently completely broken.
Help much appreciated.

RewriteCond %{HTTP_HOST} !^www.foo.com [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule (.*) http://www.foo.com/$1 [R=permanent,L]
RewriteRule ^(?!wp/)(.*) http://%{HTTP_HOST}/wp/$1 [R=permanent]
The path portion of the URL being matched never has a leading slash, and you don't need to anchor a .*.
L modified prevents rewriting from continuing after you arrive at your first redirect.
Negative-lookbehind (?!) is not a capturing construct, and you substitute in captured patterns by writing $1, not ($1).
Edit: Apparently for OP the last rule doesn't work, failing to exclude the cases that begin with /wp/, which makes no sense to me but whatever. Here's an attempt at a workaround:
RewriteCond %{HTTP_HOST} !^www.foo.com [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule (.*) http://www.foo.com/$1 [R=permanent,L]
RewriteCond %{REQUEST_URI} !^/wp/
RewriteRule (.*) http://%{HTTP_HOST}/wp/$1 [R=permanent]

Try these rules:
RewriteCond %{HTTP_HOST} !^www.exmaple.com [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^ http://www.example.com%{REQUEST_URI} [R=301,L]
RewriteCond %{THE_REQUEST} ^GET\ /wp/
RewriteRule ^wp/(.*) /$1 [R=301,L]
RewriteRule !^wp/ wp%{REQUEST_URI} [L]
The first rule is for the host name. The second is to remove the /wp path prefix externally. And the third is to add the prefix again for internal redirection.

Related

Mod_rewrite combine default path with www. and https redirect

I'm trying to reduce the number of redirects on our website. I already managed to combine some of our redirect code (forcing www. and https://), but I also need to add a default path (/en/) in case there is none.
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule (.*) https://www.example.com%{REQUEST_URI} [R=301,L]
The other bit of code I want to implement is this:
RewriteRule "^/$" /en/
So if there's no path or arguments given, it needs to redirect to /en/. (Now I do this in PHP, meaning almost every person typing "example.com" gets two redirects, where one should really be enough)
My goal is to combine these rules into one single redirect. Is that possible?
Finally, I also have an internal rewrite rule, which is likely irrelevant for the question above, but I'll add it for completeness:
RewriteRule "(^|/)\." - [F]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$/? index.php?rewrite=$1 [QSA]
You can use (in this order):
RewriteRule ^$ /en/
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule (.*) https://www.example.com/$1 [R=301,L]
If this is a language test, you can also test the values (ex with: en, fr or de) and change the first line in
RewriteRule !^(en|fr|de)/ /en/ [NC]
Should work:
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{REQUEST_URI} ^/$
RewriteRule (.*) https://www.example.com/en%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule (.*) https://www.example.com%{REQUEST_URI} [R=301,L]

htaccess replace characters in query parameter

I have a url like http://www.example.com/?product=test&retailer=test&site=test
In this instance (where product parameter is present) I remove &site=test but leave the rest of the url untouched.
If product parameter isn't present, e.g. http://www.example.com/?retailer=test&site=test
I remove &site=test and change ?retailer=test to /retailer/test so the full url would be http://www.example.com/retailer/test. I also only make this happen on the root domain.
I do this using these rules
# first condition
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{QUERY_STRING} ^product=([^&\s]+)&retailer=([^&\s]+)&site=test$ [NC]
RewriteRule ^$ /?product=%1&retailer=%2 [R=301,L]
# second condition
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{QUERY_STRING} ^retailer=([^&\s]+)&site=test$ [NC]
RewriteRule ^$ /retailer/%1? [R=301,L]
on the second rule when the url is rewritten to /reatiler/test there is the possibility for this to be /retailer/test+test in this instance I need to change it to /retailer/test-test could also be /retailer/test+test+test which would need to be /retailer/test-test-test
help on this would be much appreciated
You could use the N flag (more info here):
RewriteRule ^retailer/(.*)\+(.*)$ /retailer/$1-$2 [N,R=301]
Note that this is actually equivalent, since a redirect is involved here:
RewriteRule ^retailer/(.*)\+(.*)$ /retailer/$1-$2 [R=301,L]
So finally your htaccess should look like this
# first condition
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{QUERY_STRING} ^product=([^&\s]+)&retailer=([^&\s]+)&site=test$ [NC]
RewriteRule ^$ /?product=%1&retailer=%2 [R=301,L]
# second condition
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{QUERY_STRING} ^retailer=([^&\s]+)&site=test$ [NC]
RewriteRule ^$ /retailer/%1? [R=301,L]
RewriteRule ^retailer/(.*)\+(.*)$ /retailer/$1-$2 [R=301,L]

RewriteRule ssl conf combining various

I need to Rewrite every Dir to https, www and trailing slash and for SEO i need every redirect with only one 301.
The first twoo are solved, but the third doesn't work if de URW comes with www (it returns a 302 if a URL exist, and then write de trailing slash), but i've a rule to handle that case, can you see something wrong?
ssl.conf:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{REQUEST_URI} !^/(.*)\.(.*)
RewriteCond %{REQUEST_URI} !^(.*)/$
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI}/ [L,R=301]
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{REQUEST_URI} ^/(.*)\.(.*)
RewriteCond %{REQUEST_URI} ^(.*)/$
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} ^www\.
RewriteCond %{REQUEST_URI} !^/(.*)\.(.*)
RewriteCond %{REQUEST_URI} !^(.*)/$
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI}/ [L,R=301]
It was my fault, the rules above works fine, the problem was with my hosts file that hadn't the www entry to test.
I leave the Rule for help anyone if needed.

Second Rewriterule not working correctly

I am trying to do two things here..
redirect http://site.com.au/brand.php?pBrand=THENORTHFACE to http://site.com.au/brand/the-north-face (this works fine)
redirect http://site.com.au/listingbrand.php?pBrand=THENORTHFACE to http://site.com.au/brand/the-north-face (this does not work, when redirecting listingbrand.php?pBrand=DOSH or pBrand=ATKM, they both point back to the first rewrite the-north-face).
How do i make the second rewrite work for each brand? Also, is it correct to repeat the rewrites for each brand?
RewriteCond %{QUERY_STRING} ^pBrand=THENORTHFACE$ [NC]
RewriteRule ^brand\.php$ /brand/the-north-face/? [R=301,L]
RewriteRule ^listingbrand\.php$ /brand/the-north-face/ [R=301,L]
RewriteCond %{QUERY_STRING} ^pBrand=DOSH$ [NC]
RewriteRule ^brand\.php$ /brand/dosh/? [R=301,L]
RewriteRule ^listingbrand\.php$ /brand/dosh/ [R=301,L]
RewriteCond %{QUERY_STRING} ^pBrand=ATKM$ [NC]
RewriteRule ^brand\.php$ /brand/all-the-kings-men/? [R=301,L]
RewriteRule ^listingbrand\.php$ /brand/all-the-kings-men/ [R=301,L]
You have this rule 3 times:
RewriteRule ^listingbrand\.php$ ...
Which is not using RewriteCond since RewriteCond is only applicable to very next RewriteRule. Actually you don't even need a separate rule since earlier RewriteRule can handle both brand.php and listingbrand.php using OR in regex.
Change your code to this:
RewriteCond %{QUERY_STRING} ^pBrand=THENORTHFACE$ [NC]
RewriteRule ^(brand|listingbrand)\.php$ /brand/the-north-face/? [R=301,L,NC]
RewriteCond %{QUERY_STRING} ^pBrand=DOSH$ [NC]
RewriteRule ^(brand|listingbrand)\.php$ /brand/dosh/? [R=301,L,NC]
RewriteCond %{QUERY_STRING} ^pBrand=ATKM$ [NC]
RewriteRule ^(brand|listingbrand)\.php$ /brand/all-the-kings-men/? [R=301,L,NC]

redirecting file request for subdomain and main site with certain arguments?

I am running wildcard subdomains. the aim of the site is to run a virtual subdomain. what the functionality should be is that when the files
from the main site are called they will be rewritten for the clean URLs. But when i am calling the same files form the subdomain
like xyz.doamin.com/my-file.php then this should be rewritten like it is calling that file with an argument of subdoamin like
domain.com/my-file.php?var=xyz. Currently what i have done for the file call is this
Options +FollowSymLinks
RewriteEngine on
## Redirecting all non-www domains to www.domain.com
RewriteCond %{HTTP_HOST} ^domain.com [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301,NC,L]
RewriteCond %{HTTP_HOST} !^www\.domain\.com$ [NC]
RewriteCond %{HTTP_HOST} ^(.*)\.domain\.com$ [NC]
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^(.*)$ http://www.domain.com%{REQUEST_URI}?var=%1 [L]
RewriteCond %{HTTP_HOST} !^www\.domain\.com$ [NC]
RewriteCond %{HTTP_HOST} ^(.*)\.domain\.com$ [NC]
RewriteCond %{QUERY_STRING} !^$
RewriteRule ^(.*)$ http://www.domain.com%{REQUEST_URI}?%{QUERY_STRING}&var=%1 [L]
RewriteCond %{HTTP_HOST} !^www\.domain\.com$ [NC]
RewriteCond %{HTTP_HOST} ^(.*)\.domain\.com$ [NC]
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^(.*)$ http://www.domain.com/index.php?subdomain=%1 [L]
RewriteCond %{HTTP_HOST} !^www\.domain\.com$ [NC]
RewriteCond %{HTTP_HOST} ^(.*)\.domain\.com$ [NC]
RewriteCond %{QUERY_STRING} !^$
RewriteRule ^(.*)$ http://www.domain.com%{REQUEST_URI}?%{QUERY_STRING}&subdomain=%1 [L]
This is throwing a 500 internal error for the file call.
Rule set 4 will overlap with rule set 1 and 2. I suspect this is causing the issue.
So I think all 3 need an extra RewriteCond check on REQUEST_URI.
Really you shouldn't need rule set 4. Just including index.php as a default should do the trick. Unless of course you don't want URL's like http://www.domain.com/?var=xyz, in this case you need rule 4, but you need to split it into 2 - one with a QUERY_STRING and one without, just like rule 1 and 2
Also, isn't %1 from the regex in the rewriteRule itself and not the preceeding rewriteConds? If so then your regex is wrong, because it'll be setting the var= to the entire original URL.
Looking in the error log is a good idea as it will give you the reason for the 500 error.
Edit: Ok, try something like this (not tested)
## Redirecting all non-www domains to www.domain.com
RewriteCond %{HTTP_HOST} ^domain.com [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301,L,QSA]
## Redirecting / requests to index.php
# Note: Use the QSA flag for handling with or without query string
RewriteCond %{REQUEST_URI} ^/$
RewriteCond %{HTTP_HOST} !^www\.domain\.com$ [NC]
RewriteCond %{HTTP_HOST} ^(.*)\.domain\.com$ [NC]
RewriteRule ^(.*)$ http://www.domain.com/index.php?var=%1 [L,QSA]
## Redirecting /something requests to index.php
# Note: Use the QSA flag for handling with or without query string
RewriteCond %{REQUEST_URI} ^/.+$
RewriteCond %{HTTP_HOST} !^www\.domain\.com$ [NC]
RewriteCond %{HTTP_HOST} ^(.*)\.domain\.com$ [NC]
RewriteRule ^(.*)$ http://www.domain.com%{REQUEST_URI}?var=%1 [L,QSA]