Restrict some url pattern in a apache redirect - apache

I am writing a redirect to match any url of the patter /message/* here.
RewriteRule ^/message/(.+)$ http://abet.in/message/$1 [NC,R=301,L]
Now I want to modify it by not allowing some string pattern in url.
RewriteCond to check /message/index.html in the url.
1. Check if the request url contains /message/index.html.
2. If the condition is not met then do a redirect.
I tried the following methods. But I am not sure whether they are correct or not.
RewriteCond %{THE_REQUEST} !^/message/index
RewriteCond %{REQUEST_URI} !^/message/index [NC]
Could some one tell how to do this.

%{THE_REQUEST} contains a string that looks like this for a regular page request:
GET /message/index.html HTTP/1.1
And %{REQUEST_URI} looks like this:
/message/index.html
So your 2nd option is almost correct. You don't need a / at the start of the Pattern for RewriteRules.
Additionally, these two rules will prevent all requests that start /message/index from being redirected):
RewriteCond %{REQUEST_URI} !^/message/index [NC]
RewriteRule ^message/(.+)$ http://abet.in/message/$1 [NC,R=301,L]
If you only want to prevent /message/index.html and not /message/index.php or /message/index-of-something-else then do:
RewriteCond %{REQUEST_URI} !^/message/index\.html [NC]
RewriteRule ^message/(.+)$ http://abet.in/message/$1 [NC,R=301,L]

Related

Both URL With PHP and Non-PHP Access after RewriteRule In Htaccess

Access Both URL With PHP and Non-PHP in PHP project after applying Htacces Rules
RewriteRule ^c/([a-zA-Z0-9-/]+)$ category.php?id=$1 [L]
RewriteRule ^p/([a-zA-Z0-9-/]+)$ detail.php?post=$1 [L]
Here I access both URLs like www.example.com/c/category-name and www.example.com/category.php?id=12 but I want only www.example.com/c/category-name URL. I don't Want Duplicate URLs both this page.
With your shown samples, attempts please try following htaccess rules. Make sure to clear your browser cache before testing your URLs.
RewriteEngine ON
##Internal rewrite rules.
RewriteCond %{HTTP_HOST} ^(?:www\.)?example.com$ [NC]
RewriteRule ^c/([\w-]+)/?$ category.php?id=$1 [QSA,NC,L]
##External redirect rules.
RewriteCond %{HTTP_HOST} ^(?:www\.)?example.com$ [NC]
RewriteCond %{THE_REQUEST} \s/category\.php?id=(\S+)\s [NC]
RewriteRule ^ /c/%1? [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^[^/]*/(.*)/?$ category.php?id=$1 [QSA,NC,L]
Unless you have changed an existing URL structure and category.php and/or detail.php have been indexed by search engines then you could simply force a 404 when either of these URLs are accessed directly.
For example, the following should go before your existing rewrites:
# Block direct access to "category.php" or "detail.php"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(category|detail)\.php$ - [R=404]
The check against the REDIRECT_STATUS env var ensures that we are only checking direct requests and not rewritten requests by the later rewrite.
Otherwise, if these "old" URLs have previously been indexed by search engines or linked to by third parties then you should redirect to the "new" (canonical) URLs instead. For example:
# Redirect "category.php" or "detail.php" to canonical URL
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^(?:id|post)=([a-zA-Z0-9/-]+)$
RewriteRule ^(?:(c)ategory\.php|detail\.(p)hp)$ /$1/%1 [R=301,L]
I've moved the hyphen to the end of the character class (ie. from [a-zA-Z0-9-/] to [a-zA-Z0-9/-]) to avoid a potential ambiguity since hyphens are naturally special characters inside a character class.
The $1 backreference contains either c or p, depending on the request, to form the first path segment. %1 is the value captured from the URL-parameter. Importantly, this is the same regex you are using the later rewrite to match the value.
NB: Test first with a 302 (temporary) redirect to avoid potential caching issues.

Pattern matching in htaccess rewrite condition

I have a rewrite condition in an .htaccess file which is used to 'not' force specific URLs to use a HTTPS connection but it's matching erroneously on other URLs at present, here's the rewrite rule...
RewriteCond %{HTTPS} off
RewriteCond !/go/ [NC]
RewriteCond %{HTTP_HOST} ^app\.ihasco\.co\.uk [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
And here's an example of the URL I want to match on in the 2nd line:
http://app.ihasco.co.uk/training/MTMwfG5pbmVmb3Vy/go/ST/bmF0aGFuQG5pbmVmb3VyLmNvLnVr
However line 2 seems to be matching on URLs like the following also:
http://app.ihasco.co.uk/client/login
and is subsequently failing to force them to HTTPS. What am I missing? :?
You need to tell the RewriteCond what to match !/go/ against. Change the second line to:
RewriteCond %{REQUEST_URI} !/go/ [NC]

what is this htaccess rule actually doing

I have this condition and rule and want to know what actually is going on here
RewriteCond %{REQUEST_URI} ^/sitepages/newversion/
RewriteCond %{QUERY_STRING} ^(.*[?|&])page=dynamicpage
RewriteRule ^sitepages/newversion/(.*)$ /pages/oldversion/$1 [L]
Also very interested in a detail explaination of this line
RewriteRule ^sitepages/newversion/(.*)$ /pages/oldversion/$1 [L]
thanks
RewriteCond %{REQUEST_URI} ^/sitepages/newversion/
If the request URL starts with "/sitepages/newversion/",
RewriteCond %{QUERY_STRING} ^(.*[?|&])page=dynamicpage
and the query string contains "page=dynamicpage",
RewriteRule ^sitepages/newversion/(.*)$ /pages/oldversion/$1 [L]
then take the part of the URL after "sitepages/newversion/" and redirect the request to "/pages/oldversion/(the rest of the url)".
For example:
http://domain.com/sitepages/newversion/someleaf?page=dynamicpage
will get redirected to
http://domain.com/pages/oldversion/someleaf?page=dynamicpage
First of all your rule can be rewritten better as this:
RewriteCond %{QUERY_STRING} (?:^|&)page=dynamicpage(?:&|$) [NC]
RewriteRule ^sitepages/newversion/(.*)$ /pages/oldversion/$1 [L,NC]
Now for explanation part.
RewriteCond is matching a URI with query parameter page=dynamicpage
RewriteRule is matching a URI with pattern sitepages/newversion/(.*)$ which will match /sitepages/newversion/abc123 or /sitepages/newversion/foobar
(.*) is capturing group to populate $1 with the value abc123 in my first example.
In target we use /pages/oldversion/$1 that will become /pages/oldversion/abc123 for same example.
NC flag is for no case comparison.
L flag is for Last that makes mod_rewrite run the rewrite loop again.
Reference: Apache mod_rewrite Introduction
Apache mod_rewrite Technical Details

redirect url with query string to path, and url without query string must be internally rewritten

I've been trying and trying.
If one goes to:
www.domain.nl/vereniging
internally a page is requested from:
www.domain.nl/?p=vereniging
For that I use this:
RewriteCond %{QUERY_STRING} !(p=.*)$
RewriteRule ^(.+)$ ?p=$1 [NC]
If a users visits:
www.domain.nl/?p=vereniging
I want the users to be redirected to:
www.domain.nl/vereniging
For that I use:
RewriteCond %{QUERY_STRING} ^p=(.*)$ [NC]
RewriteRule ^$ http://www.domain.nl/%1? [NC,R=301]
(If I put RewriteCond %{REQUEST_FILENAME} !-d before this, it doesn't redirect anymore. That's strange because a query is not a directory right?)
Separately, these 2 chunks of code work.
However, if I put them together in 1 .htaccess it bitches about looping.I don't understand this, because the conditions should prevent looping.
Try applying the END flag to either the first or second RewriteRule.
Look at the END flag here: http://httpd.apache.org/docs/current/rewrite/flags.html
You need to check against the actual request:
RewriteCond %{THE_REQUEST} \?p=([^&\ ]+)
RewriteRule ^ /%1? [L,R=301]

Redirect home page only to another link

Say I want to redirect only http://example.com/ to http://example.com/main/, how do I do it?
Here's what I am doing right now:
RewriteEngine On
RewriteBase /
RewriteRule ^$ main/ [R=301,L]
The problem is, it's also redirecting query strings. For example: http://example.com/?channel=science is being redirected to http://example.com/main/?channel=science.
I don't want only the valid/specified non-empty (i.e. value is specified) query strings to be redirected. For example:
http://example.com/?channel
Should be redirected as well. How do I do this?
You can use (one or more) RewriteCond between your RewriteBase and RewriteRule to force rewrites only when querystring matches (or doesn't match with a !) what you want it to.
This will only redirect requests whose querystring matches cat or channel
RewriteCond %{QUERY_STRING} ^(.*)(channel|cat)(.*)$
You can also use multple RewriteCond combined with [OR] flags if you need one of the conditions, or without the [OR] flag if you need all conditions to be true at the same time. E.g.
RewriteCond %{QUERY_STRING} ^(.*)(channel)(.*)$ [OR]
RewriteCond %{QUERY_STRING} ^(.*)(cat)(.*)$
Also, if you want to remove the querystring from the redirected page, just add a ? to the end of your redirect url like this:
RewriteRule ^$ main/? [R=301,L]