htaccess, rewrite for specific subdirectory but not others below it - apache

I have a subdirectory /categories/stories/ that I want to rewrite to /books/ but I don't want to rewrite something like /categories/stories/horror. I'm doing the following but it has no effect:
RewriteCond ${REQUEST_URI} ^/categories/stories[/]?
RewriteCond ${REQUEST_URI} !^/categories/stories/+[/]?
RewriteRule ^(.*) /books/ [R=301,L]
The result being if a person goes to, for example, http://bookstore.com/categories/stories they go to http://bookstore.com/books but http://bookstore.com/categories/stories/horror there's not rewrite.

You can just use anchors in your regex pattern:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/categories/stories/?$ [NC]
RewriteRule ^ /books/ [R=301,L]
Pattern ^/categories/stories/?$ will match /categories/stories/ or /categories/stories but not /categories/stories/anything.
Also make sure to clear your browser cache or use a different browser for testing this change.

Related

.htaccess - mod-rewrite and redirecting profile URLs with parameters to clean ones

I have links to user profiles like:
https://example.com/chat/index.php?action=user&member=547
https://example.com/chat/index.php?action=user&member=11540
etc.
My goal is to mod-rewrite such URLs so that they look nicer, ie. they should look like:
https://example.com/chat/member-547/
https://example.com/chat/member-11540/
etc.
And URLs without a trailing slash, ie.
https://example.com/chat/member-547
should be 301-forwarded to one with slash, ie.
https://example.com/chat/member-547/
So in .htaccess I tried this, but only the first line seems to work and it's not complete:
RewriteRule ^chat/member-([0-9]+)/$ ./index.php?action=user&member=$1
RewriteRule ^chat/member-([0-9]+)$ /member-$1/ [R=301,L]
TO SUMMARIZE:
When someone enters URL like:
https://example.com/chat/index.php?action=user&member=547
it should be 301-redirected to:
https://example.com/chat/member-547/
When someone enters:
https://example.com/chat/member-547
it should also be 301-redirected to:
https://example.com/chat/member-547/
I hope there's an efficient way to do it right.
Starkeen's answer is correct, and will work. I'll just suggest an alternative, which acts on the raw request variable itself:
RewriteEngine On
RewriteCond %{THE_REQUEST} ^GET\ /chat/index\.php\?action=user&(member)=(\d+) [NC]
RewriteRule ^chat/index\.php$ /chat/%1-%2/? [R=301,L]
RewriteRule ^chat/member-([0-9]+)$ /member-$1/ [R=301,L]
RewriteRule ^chat/(member)-(\d+)/$ /chat/index.php?action=user&$1=$2 [L]
You can use the following rule :
RewriteEngine on
RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteCond %{QUERY_STRING} ^action=([^&]+)&member=(.+)$
RewriteRule /chat/index\.php$ /chat/member-%2/? [L,R=301]
RewriteRule ^chat/member-(.+)/?$ /chat/index.php?action=user&member=$1 [L]

Mod ReWrite to remove component of URL

I must be an idiot because I just can't work this bit out.
I've got a URL:
www.site.com.au/products/product-name.html
I need to redirect these to:
www.site.com.au/product-name.html
All the links are dynamic, the folder doesn't exist. What ReWrite rule do I use to accomplish this?
This is what I've got so far:
RewriteCond %{HTTP_HOST} ^(www|test)\.site\.com\.au
RewriteCond %{REQUEST_URI} ^(/products/)
RewriteCond %{REQUEST_URI} [A-Z]
RewriteRule ^.+\.html$ ${lc:%{REQUEST_URI}} [NC,R=301,L]
Just need to add the bit to remote /products
Thanks.
RewriteRule ^products(/.*)$ http://www.site.com.au$1 [L, R=301]
This replaces everything you listed, except for the first RewriteCond (to match the domain, though if your VirtualHost only answers on those two domains, you can exclude that RewriteCond to simplify it).
RewriteRules are matched first before Apache looks at the RewriteConds, so if you can do the match in the RewriteRule itself it greatly simplifies things. Just for your future reference, if you did need to match in the RewriteCond, it would look something like this:
RewriteCond %{REQUEST_URI} ^/products(/.*)$
RewriteRule ^.*$ http://www.site.com.au%1 [L, R=301]
Note the %1 for matching what's in the parentheses in the RewriteCond vs. the $1 for matching what's in the RewriteRule.
EDIT: Per your comment, the following modification should force lowercase. I haven't had to do that myself, but per this Apache documentation it's an internal function via RewriteMap. Based on your original code it looks like maybe you already have the RewriteMap definition elsewhere. If not, I've included it here.
RewriteMap lc int:tolower
RewriteCond %{REQUEST_URI} ^/products(/.*)$ [NC]
RewriteRule ^.*$ http://www.site.com.au${lc:%1} [L, R=301]
OK, I really don't know enough about Apache Rewrite to figure out the exact formatting. But after much ado these are the results that worked:
# Lowercase all /products/
RewriteCond %{HTTP_HOST} ^(www)\.site\.com\.au
RewriteCond %{REQUEST_URI} ^/products/.+\.html
RewriteCond %{REQUEST_URI} [A-Z]
RewriteRule ^ ${lc:%{REQUEST_URI}} [R=301,L]
# Lowercase all /products/ and strip products/ subfolder
RewriteCond %{HTTP_HOST} ^(www)\.site2\.com\.au
RewriteCond %{REQUEST_URI} ^/products/.+\.html
RewriteCond %{REQUEST_URI} [A-Z]
RewriteRule ^products/(.+\.html)$ /${lc:$1} [R=301,L]
Thanks,
Dom

mod redirect rule

I just want to redirect the URL through the mod rewrite ruls. I have applied this rule excluding (R=301)
Example :
from http:///webapp/wcs/stores/servlet/en/marksandspencer to http:///en/marksandspencer
I am using this rules for the mod redirect rules.
RewriteEngine on
RewriteCond %{REQUEST_URI} !^(/)?$
RewriteCond %{REQUEST_URI} !^/webapp.*$
RewriteCond %{REQUEST_URI} !^/wcsstore.*$
RewriteRule ^/(.*)$ /webapp/wcs/stores/servlet/$1 [PT,NC,L,QSA]
RewriteRule ^/webapp/wcs/stores/servlet/(.*) /$1 [NE,L,QSA]
RewriteRule ^(/)?$ /webapp/wcs/stores/servlet/en/marksandspencer [PT,NC,L]
No idea what you're trying to do, but if you're using Apache 2.0 or higher, the leading slash is stripped off of URI's when matching is done within a RewriteRule. Also, you have a rule that looks like you're adding a /webapp/wcs/stores/servlet/ to the beginning of a URI, then the very next rule it looks like you are removing it. This will probably cause a loop.
Taking a wild guess at what you are trying to do, I think you need to add a condition to the 2nd rule, and remove the leading slashes:
# internally rewrite URI by appending "/webapp/wcs/stores/servlet/" to the front
RewriteCond %{REQUEST_URI} !^(/)?$
RewriteCond %{REQUEST_URI} !^/webapp.*$
RewriteCond %{REQUEST_URI} !^/wcsstore.*$
RewriteRule ^(.*)$ /webapp/wcs/stores/servlet/$1 [PT,NC,L,QSA]
# if a request is made with "/webapp/wcs/stores/servlet/" in it, redirect to a URI with it stripped
RewriteCond %{THE_REQUEST} ^(GET/POST)\ /webapp/wcs/stores/servlet/
RewriteRule ^webapp/wcs/stores/servlet/(.*) /$1 [R=301,L,QSA]
RewriteRule ^$ /webapp/wcs/stores/servlet/en/marksandspencer [PT,NC,L]

How to ignore a URL in a redirect?

I have the following redirect in my store:
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.mydomain.net$ [NC]
RewriteRule ^(.*)$ http://www.mydomain.com/$1 [R=301,L]
However, I want to ignore the redirection for
www.mydomain.net/admin
because its my backend to manage my store and now I cant access my admin because of the URL redirection I set.
Any idea how to do this?
Should be easy enough to just reverse your line to a negation statement so that it applies to everything that does not match the paths you don't want to rewrite:
RewriteRule !^(admin/.*)$ http://www.mydomain.com/$1 [R=301,L]
or more preferably just add another rewrite conditional to exclude the admin directory:
RewriteCond %{REQUEST_URI} !^/admin [NC]
They both should work but the second one looks nicer.

Redirect www.domain.com/uk to www.domain.co.uk/uk

I'm no .htaccess expert, but I've tried a few different things to redirect a domain to no avail.
I've got a UK and US domain...some US pages have uk extension, and need to be pointed to the proper UK domain:
www.domain.com/uk needs to be rewritten to www.domain.co.uk/uk
Ex. If someone types in www.domain.com/uk/about it will be rewritten as www.domain.co.uk/uk/about
Edit: Paths with /uk should be rewritten
So www.domain.com/uk and www.domain.co.uk should be rewritten to www.domain.co.uk/uk/
You can try something like this:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.com$ [NC]
RewriteRule (.*) http://www.domain.co.uk/$1 [L,R=301]
The important point is to use a RewriteCondition that works on the HTTP Host header. Simply speaking, if a RewriteCond is placed before a normal RewriteRule then the rule is only used if the the condition matches.
The code excerpt above redirects all requests from the .COM to the .CO.UK domain, so if you only need to redirect certain directory, then you need to adjust the rule accordingly, e.g.:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.com$
RewriteRule uk(.*) http://www.domain.co.uk/uk$1 [L,R=301]
Edit: I hope that this will work for you according to your edit.
The first rule rewrites http://www.domain.com/uk and http://www.domain.com/uk/anything to http://www.domain.co.uk/uk/anything.
The second rule rewrites http://www.domain.co.uk to http://www.domain.co.uk/uk/.
Edit 2: I changed the rule (modified the last one and added another one) to reflect the demand for rewrites on .co.uk/something. If the path starts with uk/ then it just passes through, otherwise it gets rewritten to uk/something.
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.com$ [NC]
RewriteRule uk($|/.*) http://www.domain.co.uk/uk$1 [L,R=301]
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.co\.uk$ [NC]
RewriteRule ^uk/(.*) - [PT,L]
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.co\.uk$ [NC]
RewriteRule (.*) http://www.domain.co.uk/uk/$1 [L,R=301]