Forum Moderators: phranque

Message Too Old, No Replies

.htaccess redirect - Which is a better code?

Which is a better code to use in .htaccess file to redirect host & IP?

         

Dinkar

7:44 pm on Oct 19, 2011 (gmt 0)

10+ Year Member



Hello,

Which one is a better code to use in .htaccess file for redirect?


1.
RewriteCond %{HTTP_HOST} ^webmasterworld.com [NC]
RewriteRule ^(.*) http://www.webmasterworld.com/$1 [L,R=301]


2.
RewriteCond %{HTTP_HOST} ^webmasterworld.com [NC]
RewriteRule ^(.*)$ http://www.webmasterworld.com/$1 [L,R=301]

Note: '$' in 2nd example.


Why? Please explain the difference.

Also which code is better to redirect IP request to domain.



1.
RewriteCond %{HTTP_HOST} ^111.111.1.2 [NC]
RewriteRule ^(.*) http://www.webmasterworld.com/ [L,R=301]

2.
RewriteCond %{HTTP_HOST} ^111.111.1.2 [NC]
RewriteRule ^(.*)$ http://www.webmasterworld.com/ [L,R=301]


Please note, there is no $1 at the end of the URL.


Thanks :)


PS: There may be related threads; but I would like to get clear answer here, if possible.

g1smd

8:29 pm on Oct 19, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Both pieces of code have serious flaws:

There is missing escaping on literal periods.

Another error, www URLs with port number are not redirected.

This fixes it:

RewriteCond %{HTTP_HOST} !^(www\.example\.com)?$
RewriteRule (.*) http://www.example.com/$1 [R=301,L]


For the IP redirect you should redirect to the correct page, not mass redirect to the root.

[edited by: g1smd at 9:21 pm (utc) on Oct 19, 2011]

Dinkar

8:57 pm on Oct 19, 2011 (gmt 0)

10+ Year Member



Thank you for your reply. But can you please explain what are those serious flaws? And what is 'missing escaping on literal periods'?

BTW, your code is not working. It keeps redirecting in a loop.

Dinkar

9:36 pm on Oct 19, 2011 (gmt 0)

10+ Year Member



Alright, what about the following code? It also redirect IP based request. The only problem - it doesn't redirect url with port number.

RewriteCond %{HTTP_HOST} !^www.webmasterworld.com [NC]
RewriteRule ^(.*) http://www.webmasterworld.com/$1 [L,R=301]

g1smd

10:07 pm on Oct 19, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



It will infinite redirect all HTTP/1.0 requests.

It redirects non-www with port number but not www with port number.

You still have not escaped the literal periods in the RegEx pattern.

The [NC] flag means that casing errors are not fixed.

How about instead redirecting all requests where host name is not "exactly" www.example.com or blank (the latter caters for HTTP/1.0 requests)?

Dinkar

10:33 pm on Oct 19, 2011 (gmt 0)

10+ Year Member



How to do that? I am not expert in .htacess so please help.

Why do we need to escaped the literal periods? What benefit it provide?

Dinkar

10:42 pm on Oct 19, 2011 (gmt 0)

10+ Year Member



I tried your code:

RewriteCond %{HTTP_HOST} !^(site\.com)?$
RewriteRule (.*) http://site.com/$1 [R=301,L]

It works but doesn't redirect urls with port number. any solution?

lucy24

11:18 pm on Oct 19, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



To answer your original question:
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]

Note: '$' in 2nd example.

Why? Please explain the difference.

Now that you have drawn my attention to it, I also note the ^ in both examples. Since you are capturing the entire text without constraints or limitations, the anchors make no difference whatsoever. By default, Regular Expressions will start as soon as they can, and continue as long as they can.

You only need an anchor when you are looking for specific text in a specific location. For example, to look only at the first directory in the request:
^([^/]+/)
or only at requests for a particular filetype:
\.html$

g1smd

12:09 am on Oct 20, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



It works but doesn't redirect URLs with port number. Any solution?

The port number has to resolve to your site, so it's likely that only port :80 or :8080 will be redirected.

If other port numbers result in 'request timeout' or a 'forbidden' response, then that is also a useful and valid outcome.

The idea of the redirect is to prevent duplicate content.

Dinkar

6:41 am on Oct 20, 2011 (gmt 0)

10+ Year Member



Thanks lucy, very helpful :)

g1smd, I tried with port :80 and it's NOT redirecting. I tried something like this:


http://site.com:80/d.html


It return '200 OK' with content.

Dinkar

6:54 am on Oct 20, 2011 (gmt 0)

10+ Year Member



One more question.

What is the effect of g1smd's code on sub-domain?

g1smd

7:19 am on Oct 20, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



It depends where you put the code. Every site configuration is differrent.

Test it.

Dinkar

7:54 am on Oct 20, 2011 (gmt 0)

10+ Year Member



It's not working. It redirect the sub-domain to the related folder.

OK, here is what I want to do (final requrement):

1. non-www should redirect to www version.
2. www version with port 80 number should be redirect to www version.
3. non-www sub-domain should be redirect to www version of that sub-domain
4. www version of sub-domain with port 80 number should be redirect to www version of sub-domain.
5. All IP based request should be redirect to www version of root domain. Example: [111.111.2.1...] should be redirect to [webmasterworld.com...]

Dinkar

10:27 pm on Oct 20, 2011 (gmt 0)

10+ Year Member



Alright, I cooked some code and it's working (not 100%). Here it is:

.htaccess - location example.com/

RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.com [OR]
RewriteCond %{HTTP_HOST} ^([1-2][0-9][0-9])\.* [OR]
RewriteCond %{HTTP_HOST} ^([1-9][0-9])\.*
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]

RedirectMatch 301 /subdomain/(.*) http://www.subdomain.example.com/$1


.htaccess - location example.com/subdomain/

RewriteEngine on
RewriteCond %{HTTP_HOST} ^subdomain\.example\.com
RewriteRule ^(.*)$ http://www.subdomain.example.com/$1 [L,R=301]


The above code -
-- redirect non-www to www version of main domain and sub-domain.
-- redirect almost all IP request to www version of main domain.
-- redirect all request for sub-domain folder location (sub-domain's physical web location) to www version of sub-domain.
-- BUT, it doesn't redirect request with port number.
Example: http ://www.example.com:80/ will not get redirected to http ://www.example.com/
I think I can live without this redirect.

g1smd

10:57 pm on Oct 20, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



^([1-9][0-9])\.* matches the "literal" 10................. with as many dots as you like.

\. is a "literal dot".

* means "as many as you like".

I guess you meant \. not \.* here.

If you use RewriteRule for any of your rules, use RewriteRule for all of your rules. Do not use RedirectMatch here.

lucy24

1:33 am on Oct 21, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



RewriteCond %{HTTP_HOST} ^([1-2][0-9][0-9])\.* [OR]
RewriteCond %{HTTP_HOST} ^([1-9][0-9])\.*

Is this part intended to capture any and all numerical address? If so, you forgot about the ones that start with a single digit. No parentheses needed, since you're not using pipes and not capturing for later use.

^[12]?\d?\d\.
or, more precisely,
^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(\.\d{1,3}\.\d{1,3})?$
or, if you want to be hair-splittingly accurate, express each piece as
^(2[0-4]\d|25[0-5]|1\d\d|[1-9]\d?)\.
replacing \d with [0-9] if you have to.

Exact wording depends on whether there is a possibility of something other than an IP string showing up in this location. And whether you have to allow for those long-rumored six-piece addresses. (I have yet to meet one in the flesh, but I'm told they have been authorized.) Even if your server uses floating IP addresses, they don't float all over the entire IANA map.

[1-2] and [12] mean exactly the same thing, but the first version takes up an extra byte and uses more processing time as the server has to stop every single time and figure out what digits are in the "1-2" range.