These rewrite rules work really well. I am wondering if the fact that I don't enforce the www first that I am causing needless overhead as it needs to switch from domain 1 to domain 2 before enforcing the www?

<font color='"#0000FF"'>RewriteEngine on
# Get in the habit of starting with this (technique)</font>
<font color='"#800080"'>RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# This will only affect the following RewriteRule block so this is totally irrelevant.</font>
# Redirect old_domain.com to new_domain.com with 301 and...
RewriteCond %{HTTP_HOST} <font color='"#FF0000"'>^</font>old_domain.com$ [NC]
<font color='"#FF0000"'># You only care about the domain redirection</font>
RewriteRule ^([a-zA-Z0-9]+)$ http://<font color='"#0000FF"'>www.</font>new_domain.com/$1 [R=301,L]
<font color='"#A9A9A9"'># Well either that or RewriteRule ^([a-zA-Z0-9]+)$ http://new_domain.com%{REQUEST_URI} [R=301,L]</font>
<font color='"#0000FF"'># If you're going to enforce www, start with making the redirection correctly</font>
# Ensure www with 301
RewriteCond %{HTTP_HOST} !^www\\. [NC]
RewriteRule <font color='"#FF0000"'>^</font> http<font color='"#FF0000"'>%1</font>://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
<font color='"#FF0000"'># You've specified a null {REQUEST_URI} (okay, just a start anchor); I'd use .? as "correct regex"
# You've not created %1 so this is clearly in error.</font>
# remove .php ONLY if requested directly
RewriteCond %{THE_REQUEST} <font color='"#FF0000"'>(</font>\\.php<font color='"#FF0000"'>\\sHTTP/1)</font>
<font color='"#FF0000"'># You don't need to create an atom here nor do you need anything after \\.php
# You could also use the {IS_SUBREQ} variable, too.</font>
RewriteRule ^([a-zA-Z]+)\\.php$ /$1 [R=301,L<font color='"#FF0000"'>,QSA</font>]
<font color='"#FF0000"'># Because you're not altering/adding a query string, you don't need the QSA flag</font>
# Redirect extensionless version to .php version
RewriteRule ^([a-z]+)$ $1.php <font color='"#0000FF"'>[L]
# Not required but it's technique to close this code.</font>

# This will only affect the following RewriteRule block so this is totally irrelevant.

# Redirect old_domain.com to new_domain.com with 301 and...RewriteCond %{HTTP_HOST} ^old_domain.com$ [NC]# You only care about the domain redirectionRewriteRule ^([a-zA-Z0-9]+)$ http://www.new_domain.com/$1 [R=301,L]# Well either that or RewriteRule ^([a-zA-Z0-9]+)$ http://new_domain.com%{REQUEST_URI} [R=301,L]# If you're going to enforce www, start with making the redirection correctly

Fundamentally the rewrite from old to new domain is the most important as it will be common for search links and bookmarks to have [www.old_domain.com](http://www.old_domain.com) or old_domain.com.

Thanks for your teaching on this!

Regards,Steve

ServerStorm
—
2013-01-21T20:04:39Z —
#4

Well, after digging in the apache tutorials, I lifted this off their example and it works

<font color='#0000ff'># Using the NULL means that I don't have to explicitly check if it is
# the old domain It matches if it isn't what I specify. Their example
# escaped the periods in the domain name.</font>
RewriteCond %{HTTP_HOST} !^www\\.new_domain\\.com [NC]
<font color='#0000ff'># I think this means don't match line breaks, so I don't think I need it,
# but kept it to preserve their example</font>
RewriteCond %{HTTP_HOST} !^$
<font color='#0000ff'># Option use of the /, match anything (surprised they recommend this)
# Probably the noescape (NE) flag is not required as the domain URLs have only [a-zA-Z0-9_]</font>
RewriteRule ^/?(.*)$ http://www.new_domain.com/$1 [L,R=301,NE]
# Ensure www with 301
RewriteCond %{HTTP_HOST} !^www\\. [NC]
RewriteCond %{HTTP_HOST} ^(.+)$ [NC]
RewriteRule ^(.+)$ http://www\\.%1/$1 [R=301,L]
# remove .php ONLY if requested directly
RewriteCond %{THE_REQUEST} (\\.php)
RewriteRule ^([a-zA-Z]+)\\.php$ /$1 [R=301,L]
# Redirect extensionless version to .php version
RewriteRule ^([a-z]+)$ $1.php [L]

Now I believe that I'm moving forward again

Regards,Steve

dklynn
—
2013-01-22T04:39:06Z —
#5

Hi Steve!

RewriteEngine on
# redirect from old to new domain will have guaranteed www
RewriteCond %{HTTP_HOST} !^www\\. [NC]
RewriteCond %{HTTP_HOST} ^(.+)$ [NC]
RewriteRule ^(.+)$ http://www<font color='"#FF0000"'>\\</font>.%1/$1 [R=301,L]
<font color='"#FF0000"'>[B]# You do NOT escape anything in the redirection - it is NOT regex![/B]</font>
[indent]I prefer:
RewriteRule .? http://www.%1%{REQUEST_URI} [R=301,L]
because your :kaioken: EVERYTHING :kaioken: atom is already available as {REQUEST_URI} (and it handles ^/? on its own).[/indent]
# Redirect old_domain.com to new_domain.com with 301
<font color='#800080'># Changed regex to (.+), (.?) throws a 500 error?
[B]# Then WHY did you make an atom of it and not use {REQUEST_URI}?[/B]</font>
RewriteCond %{HTTP_HOST} ^www<font color='"#0000FF"'>\\</font>.old_domain\\.com$<font color='"#0000FF"'> [NC]</font>
<font color='"#0000FF"'><font color='"#0000FF"'># You need to escape the dot character(s) in regex AND
# {HTTP_HOST} is NOT case sensitive so you need the No Case flag</font></font>
RewriteRule ^(.+)$ http://www.new_domain.com/$1 [R=301]
[indent]Again, no need to capture {REQUEST_UIRI} this way! Instead, use
[B]RewriteRule .? http://www.new_domain.com%{REQUEST_URI} [R=301,L][/B]
[/indent]
# remove .php ONLY if requested directly
<font color='#ff0000'># removed the superfluous atom</font>
RewriteCond %{THE_REQUEST} (\\.php)
RewriteRule ^([a-zA-Z]+)\\.php$ /$1 [R=301,L]
[indent]If you feel that you need to ensure nothing after .php, i.e.,
something.php/something_else.php, then use \\{space} (NOTE: replace
{space} with a space - too pedantic?).[/indent]
# Redirect extensionless version to .php version
<font color='"#0000FF"'>[indent]I'd first check that $1.php exists as a file with
[B]RewriteCond %{REQUEST_FILENAME}.php -f[/B]</font>[/indent]
RewriteRule ^([a-z]+)$ $1.php [L<font color='"#FF0000"'>}</font>
# SYNTAX ERROR/TYPO - we know it's actually ]

SS said:

I am now finding some problems that I did not initially see:

[LIST=a][*] I can't figure out why typing old_domain.com as a URL I get 403 Forbidden when the rewrite code first ensures that all requests have www enforced and a straight forward redirect?[*] I also get a 500 error if I use the ^(.?)$ as the regex for the redirect RewriteRule?[*] If I use www.old_domain.com/home then the redirect works. So why does this but the root domain give forbidden?[*] Clicking search engine links to new_domain.com do not append www?[/LIST]

I can only guess that it had something to do with requiring something in the URI in your code - which is precisely why I use any optional character and the {REQUEST_URI} variable.

It shouldn't ... but no need to use the anchors or create an atom if you use the optional character and {REQUEST_URI} variable.

Same answer as the first one - you've required at least one character and home is providing four where the simple domain request CANNOT match the requirement for at least one character.

I suspect it's because {IS_SUBREQ} is only created when it becomes true, i.e., it's returning null. Change the false to !true as, logically, that's the same thing (except for null) and not true is what you're looking for.

ServerStorm said:

Well, after digging in the apache tutorials, I lifted this off their example and it works

`

# Using the NULL means that I don't have to explicitly check if it is

# the old domain It matches if it isn't what I specify. Their example

# escaped the periods in the domain name.

RewriteCond %{HTTP_HOST} !^www\.new_domain\.com [NC]# I think this means don't match line breaks, so I don't think I need it,

If {HTTP_HOST} is not www.new_domain.com and is not empty(you have a misconfigured server?), optional leading / (Apache 1.x must be a /; Apache 2.x must NOT be a /; you should know which you're using!), capture the{REQUEST_URI} as $1 (why duplicate this?) and redirect WITHOUT escaping characters (?!?). OMG! What happened?

Well, moving forward but you've discovered a few new stumbling blocks as the above indented comments have discussed.

BTW, I am not trying to abuse you! I am simply being my pedantic (and, probably, PITA) self by making sure that you (and anyone else reading this thread) get the full story.

I'm rather surprised, though, that you have not recognized the benefit of .? and %{REQUEST_URI}. .? will always evaluate to TRUE and you have already captured your ^(.*)$ in Apache's {REQUEST_URI} variable. Since Apache handles the leading / problem (between the two major versions of Apache), there is no sense in doing that yourself - an additional benefit. With less work for Apache to do (parse, copy and create a new variable), .? and %{REQUEST_URI} will also be marginally faster because it is far more efficient.

If you're old_domain is a .com and your new_domain is another .com, it would make your handling of {HTTP_HOST} a little easier - at least the part where you could combine the www and non-www treatments and simply capture the new or old domain name and redirect to their www'd versions. Fine as is, though, as the general case should help everyone.

Please ask any questions about any of the above.

Regards,

DK

ServerStorm
—
2013-01-22T16:58:15Z —
#6

dklynn said:

Hi Steve!...

BTW, I am not trying to abuse you! I am simply being my pedantic (and, probably, PITA) self by making sure that you (and anyone else reading this thread) get the full story.

I'm rather surprised, though, that you have not recognized the benefit of .? and %{REQUEST_URI}. .? will always evaluate to TRUE and you have already captured your ^(.*)$ in Apache's {REQUEST_URI} variable. Since Apache handles the leading / problem (between the two major versions of Apache), there is no sense in doing that yourself - an additional benefit. With less work for Apache to do (parse, copy and create a new variable), .? and %{REQUEST_URI} will also be marginally faster because it is far more efficient.

If you're old_domain is a .com and your new_domain is another .com, it would make your handling of {HTTP_HOST} a little easier - at least the part where you could combine the www and non-www treatments and simply capture the new or old domain name and redirect to their www'd versions. Fine as is, though, as the general case should help everyone.

Please ask any questions about any of the above.

Regards,

DK

Hi Dk,

No worries about hard on me, I'm late to the party and I'm drinking the diluted punch, so it takes a little longer for me to get drunk

To your surprise about not finding the benefit of the %REQUEST_URI, remember that the Apache docs are massive. Recently I've shied away from reading most blogs about rewrite as I see most of them enforcing greedy practices which you have aggressively identified as a scourge, so it takes a little longer to crawl through a get how to effectively use each variable and how not to be greedy

I've incorporated and worked to understand your many recommendations in this last thread and have for the most part improved (simplified and caused less overhead processing) the rewrites:

RewriteEngine on
# Redirect old_domain.com to new_domain.com with 301
RewriteCond %{HTTP_HOST} !^www\\.new_domain\\.com
RewriteCond %{HTTP_HOST} !^$
<font color='#0000FF'># Nice %{REQUEST_URI} is great to use!
</font><font color='#0000FF'># Interestingly using RewriteRule .? http://www.%1%{REQUEST_URI} [R=301,L] fails while the shown RewriteRule .? http://www.new_domain.com%{REQUEST_URI} [</font><font color='#0000FF'>R=301</font><font color='#0000FF'>,</font><font color='#0000FF'>L] works; </font><font color='#0000FF'>they're almost the same thing?</font>
RewriteRule .? http://www.new_domain.com%{REQUEST_URI} [<font color='#000000'>R=301,L</font>]
# Ensure www with 301
RewriteCond %{HTTP_HOST} !^www. [NC]
<font color='#000000'>RewriteCond %{HTTP_HOST} ^(.+)$ [NC]</font><font color='#0000cd'>
</font><font color='#0000ff'># Made use of your recommended .? and %{REQUEST_URI}, it works well here</font>
RewriteRule .? http://www.%1%{REQUEST_URI} [R=301,L]
# remove .php ONLY if requested directly
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{THE_REQUEST} (\\.php)
<font color='#0000ff'># I tried to figure out how I could get away from creating an atom when we already have the request_uri. The main sticking point is how to remove the explicit filename.php match in the RegEx</font>
RewriteRule ^([a-zA-Z]+)\\.php$ /$1 [R=301,L]
# Redirect extensionless version to .php version
RewriteRule ^([a-z]+)$ $1.php [L]

I'm not sure why

RewriteRule .? http://www.%1%{REQUEST_URI} [R=301,L]

fails? As I understand, this translates to :[INDENT]Match everything and redirect to http://www. + RewriteCondition Match plus the query parameter(s)

[/INDENT]Your a champ for all you help! I greatly appreciate it!

Regards,Steve

dklynn
—
2013-01-23T22:20:22Z —
#7

Hi Steve!

You're holding a drinking party and didn't invite me? Bummer! I'll have to go a lot easier on you from now on. :drink:

Too true about the Apache docs but they're really quite good (if you can translate the highly technical details into something intelligible). No worries, I've done that for you and most of the translation is in the Article linked in my signature.

Yes, I've seen some of those recommending using the :kaioken: EVERYTHING :kaioken: atom for matching, well, everything; that's the red flag that tells me the author doesn't have a clue! (StommePoes actually posted a PHP article, http://perlmonks.org/?node=Death%20to%20Dot%20Star!, but he should have known how to kill those UGLY %20's! Note that (.*) does have it's uses but NOT as most try to use it! I'm glad that you're aware of its pitfalls and know to define exactly what you want to accept in your match/redirection sets. Kudos for that!

RewriteEngine on
# Redirect old_domain.com to new_domain.com with 301
RewriteCond %{HTTP_HOST} !^www\\.new_domain\\.com
RewriteCond %{HTTP_HOST} !^$
<font color='#0000FF'># Nice %{REQUEST_URI} is great to use!
</font><font color='#0000FF'># Interestingly using RewriteRule .? http://www.%1%{REQUEST_URI} [R=301,L] fails while the shown RewriteRule .? http://www.new_domain.com%{REQUEST_URI} [</font><font color='#0000FF'>R=301</font><font color='#0000FF'>,</font><font color='#0000FF'>L] works; </font><font color='#0000FF'>they're almost the same thing?</font>
<font color='"#FF0000"'># Duh? Did I ***REALLY*** do that? Of course you're at old_domain.com and need
# to redirect to new_domain.com so %1 would not work. It (%1) was supposed to retain
# the existing domain name and simply allow adding the www subdomain. MY ERROR!</font>
RewriteRule .? http://www.new_domain.com%{REQUEST_URI} [R=301,L]
# Ensure www with 301
RewriteCond %{HTTP_HOST} !^www. [NC]
<font color='#000000'>RewriteCond %{HTTP_HOST} ^(.+)$ [NC]</font><font color='#0000cd'>
</font><font color='#0000ff'># Made use of your recommended .? and %{REQUEST_URI}, it works well here</font>
<font color='"#FF0000"'># As above, that's what it was supposed to do</font>
RewriteRule .? http://www.%1%{REQUEST_URI} [R=301,L]
# remove .php ONLY if requested directly
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{THE_REQUEST} (\\.php)
<font color='#0000ff'># I tried to figure out how I could get away from creating an atom when we already have the request_uri. The main sticking point is how to remove the explicit filename.php match in the RegEx</font>
<font color='"#FF0000"'># {THE_REQUEST} will not change so it retains the ORIGINAL request but
# you don't need the parentheses, though, as you're not using this value for anything
# (except to see that a PHP script had been requested). The regex below specifies
# a filename (parameter?) request in the DocumentRoot - more valuable information
# for the code. You do need the atom below, not above.</font>
RewriteRule ^([a-zA-Z]+)\\.php$ /$1 [R=301,L]
# Redirect extensionless version to .php version
RewriteRule ^([a-z]+)$ $1.php [L]

As for "RewriteRule .? http://www.%1%{REQUEST_URI} [R=301,L]", it REQUIRES an exit strategy as it's regex is designed to ALWAYS BE TRUE (as is the ^(.*)$ you were using). Its preceding RewriteCond statement(s) provide the false option. You're only slightly off in your translation (probably semantics rather than an error) as %1 represents the non-www {HTTP_HOST} and %{REQUEST_URI} is the URI. "query parameters"? No, it simply copies the existing URI whether it's a file, directory or something you'll handle later in your mod_rewrite code ... like query parameters).

Thanks for the "Brownie Button" (or is that expression too dated for anyone to understand these days?)!

Regards,

DK

ServerStorm
—
2013-01-23T22:46:01Z —
#8

Hi DK,

If I have another Digital drinking party I'll be sure to invite you! I should have mentioned that I faked my way into a Mensa party and tried not too look like a fraud but it was hard

Thanks for your excellent descriptions as to what was happening!

I plan to continue with the Apache docs; once you get used to them, they have very valuable information. I will filter out the gratuitous usage of (.*).

Well to finish this thread unless you have any further critiques here is what I ended-up with:

I'm old enough to get the Brownie Button comment but I'm sure that likely it misses 80% of the crowd here. No problems you deserve it!

Steve

dklynn
—
2013-01-23T23:27:08Z —
#9

Hi Steve!

Mensa party? Did they drink Mensa's there? I'm supposed to be eligible but never saw the need nor had the interest as it seems like self-aggrandizement.

The descriptions were as much for the SP members as for you as I'm sure you grasp these (regex) concepts very easily.

Good! I think PHP.net's documentation is superior but, if you use the search on Apache.org's Home page, you can usually find what you want. Just don't eliminate (.*) from your bag of tricks as it does have its uses (especially for the non-English speakers who must use encoded characters).

are using a "handler file" to read the .php script names to fetch the contents to display.

Yeah, not my problem but it's a thought (the multiple file extensions to remove could open a new can of worms).

Thanks!

Regards,

DK

ServerStorm
—
2013-01-24T15:48:15Z —
#10

dklynn said:

Hi Steve!Mensa party? Did they drink Mensa's there? I'm supposed to be eligible but never saw the need nor had the interest as it seems like self-aggrandizement.The descriptions were as much for the SP members as for you as I'm sure you grasp these (regex) concepts very easily.

Well glad you wasted your talents here instead

dklynn said:

Good! I think PHP.net's documentation is superior but, if you use the search on Apache.org's Home page, you can usually find what you want. Just don't eliminate (.*) from your bag of tricks as it does have its uses (especially for the non-English speakers who must use encoded characters).

Yes PHP's documentation is great as will help a broader cross-section of people than Apache's but alas the Apache mod-rewrite in PHP.net's documentation is not comprehensive enough

are using a "handler file" to read the .php script names to fetch the contents to display.

Yeah, not my problem but it's a thought (the multiple file extensions to remove could open a new can of worms).Thanks!Regards,DK

Yes to 1 & 2. I'm killing these extensions because I only need it actually rewritten to a php file and I was thinking that by stripping common extensions a user that was trying to find out your server side language would not be able to use the " Let's try .aspx - no that failed, Ok lets try .php not that gets stripped too...'. Dare I ask what can of worm this opens :eek:

dklynn
—
2013-01-26T00:17:24Z —
#11

SS,

Thanks.

Yeah, that's what my wife said (and not in a nice way).

Documentation quality varies but both PHP.net and Apache.org are great (Apache's is just difficult to get to and highly technical).

Killing #1 and #2 are fine if you're not going to reinstate them with those extensions (and have replaced the original file extensions with a .php extension). The can of worms is when you want to reinstate more than one file extension on extensionless filenames (as some members have wanted to do). My usual response is that Apache isn't clairvoyant and can't guess which file extension to use (so it just picks the first one in the mod_rewrite).

Regards,

DK

ServerStorm
—
2013-01-26T04:25:08Z —
#12

dklynn said:

SS,

Thanks.

Yeah, that's what my wife said (and not in a nice way).

Documentation quality varies but both PHP.net and Apache.org are great (Apache's is just difficult to get to and highly technical).

Killing #1 and #2 are fine if you're not going to reinstate them with those extensions (and have replaced the original file extensions with a .php extension). The can of worms is when you want to reinstate more than one file extension on extensionless filenames (as some members have wanted to do). My usual response is that Apache isn't clairvoyant and can't guess which file extension to use (so it just picks the first one in the mod_rewrite).

Regards,

DK

Hi DK

Thanks again! I see the worms that could wiggle and boar into the wood of one's website. Lucky for me, this site is a small replacement site that is being redone starting next week. I'll opt not to do this when the site is large as it becomes more likely that this would happen.