-1

I am new to apache rewrite rules; I am writing the rules for 301 redirects for redirecting an old site's pages to new site. Please find below the rules --

#1
RewriteCond %{HTTP_HOST} ^(www-stage\.)?newsite\.com.au$ [NC]
RewriteCond %{REQUEST_URI} ^/a/b/c.html$ [NC,OR]
RewriteCond %{REQUEST_URI} ^/x/y/z.html$ [NC,OR]
RewriteCond %{REQUEST_URI} ^/p/q/r.html$ [NC]
RewriteRule (.*) /f/g/h.html [L,R=301]

#2
RewriteCond %{HTTP_HOST} ^(www-stage\.)?newsite\.com.au$ [NC]
RewriteCond %{REQUEST_URI} ^/q/w.html$ [NC,OR]
RewriteCond %{REQUEST_URI} ^/i/n/s.html$ [NC]
RewriteRule (.*) /s/d/f/g.html [L,R=301]

for every new page; I am first matching the domain; and matching all the old pages' URL and redirecting to the new page's URL. There are around 120-130 urls that need to be redirected

Is this the correct way; or the rules can be made more optimized ?

1 Answers1

0

Is this the correct way ...?

Well, it might be, but you've not really explained precisely what you are doing and why you are doing it the way you are.

  • Why do you need to check the HTTP_HOST; do you have multiple domains?
  • Redirecting multiple (seeming unrelated) URLs to a single URL looks a bit odd. Did the old site not have canonical URLs?
  • Do you need the case-insensitive matching?

  • You are not escaping all the dots in the regex.
  • You are not using the captured group in the RewriteRule pattern; so no need for a capturing group. ie. (.*) should just be .*. (Capturing groups / parenthesised-sub-patterns need to be stored by the regex parser, so it's a waste if they are not used.)

  • Your example has short URLs, but it would be more efficient to match as much as you can in the RewriteRule pattern, rather than matching REQUEST_URI in conditions. The RewriteRule pattern is processed first, only if this matches do the preceding RewriteCond directives get processed. With using a match-everything wildcard (ie. (.*)) in the RewriteRule pattern results in every rule being processed.

So, the above redirects could be rewritten (optimized) as (ignoring the domain check for the moment and assuming NS is not required):

#1
RewriteRule ^/(a/b/c|x/y/z|p/q/r)\.html$ /f/g/h.html [R=301,L]

#2
RewriteRule ^/(q/w|i/n/s)\.html$ /s/d/f/g.html [R=301,L]

Then again, if you aren't already using mod_rewrite for other things then it would be "more optimized" to use mod_alias Redirect and/or RewriteMatch instead. However, don't mix redirects from both modules as you can get unexpected results. (Different modules run at different times during the request, despite their apparent order in the config file.)

MrWhite
  • 12,647
  • 4
  • 29
  • 41
  • Thanks for the post @w3dk .. appreciate it.. To answer your questions -- – cqsapientuser Dec 01 '16 at 09:40
  • 1- yes; we have multiple domains; as in;serving two different sites from the same server ; 2- we are redirecting multiple URLs to a single page since in the new website; the content of 4-5 pages has been collated in a single page.. 3- case insensitive match is not explicitly required but have kept it as standard practice. I have used the suggested way -- 1-RewriteCond %{HTTP_HOST} ^(www-stage\.)?newsite\.com.au$ [NC] RewriteRule ^/(a/b/c|x/y/z|p/q/r)\.html$ /f/g/h.html [R=301,L] it decreases readability but improves performance which is a better trade-off between the two. – cqsapientuser Dec 01 '16 at 10:01
  • I tried using Redirect and/or RewriteMatch but it did not provide the desired results in case of two domains.. Since I am using two domains; I am inclined to ponder over using two virtualhosts contexts for two domains and using server aliases if required. In this way we won't need to match each URL for host and will be matched by the virtualhost tag. Please let me know your thoughts/suggestions..Also; how can I escape all dots in the regex ? - is this correct - ^(www-stage\.)?newsite\.com\.au$ [NC] – cqsapientuser Dec 01 '16 at 10:09
  • "...as standard practise" - The `NC` flag is often copy/pasted without thinking through the implications. The `NC` might be required on the `HTTP_HOST` check in order to safeguard against malformed requests. If you wish to keep the case-insensitive URL matching then you'll need to add the `NC` flag to the `RewriteRule`. Yes, with multiple domains `Redirect[Match]` may not be applicable. But using two VirtualHosts would be preferable - clear separation of "old" and "new" - and then mod_alias might be OK. Also helps readability (and performance) - which is indeed important. – MrWhite Dec 01 '16 at 10:51
  • Yes, just backslash escape the dots in regex - otherwise the dot matches any character (ambiguous) and "could" match too much. – MrWhite Dec 01 '16 at 10:52