When using a multisite setup creating the necessary redirects for the correct canonical hostnames becomes a bit of a chore. Each site requires it's own redirect setup with the user have to change the regexp rules to get them to work.

The attached patch reduces the users work to simply having to uncomment the necessary lines. The redirects have been rewritten to work with any domain name that they parse.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

cooperaj’s picture

Status: Active » Needs review

I figured that this status was perhaps more appropriate.

Morbus Iff’s picture

cooperaj - good idea. However, I'm a little confused about the patch.

Why is the first set of modifications so different from the original versions? Why are we (now) optionally testing against the existence of www (stored in %1) and then again testing to make sure that %1 doesn't exist? If this particular set of rules is meant to change "disobey.com" to "www.disobey.com", I'm not sure the need for this extraneous %1 check (especially since the original set boundaried "disobey.com" with ^.

As for the second set, I haven't tested it, but it looks proper to me.

cooperaj’s picture

Morbus,

The reason I did it like this is because AFAICT there is now way of doing non-greedy matching with mod_rewrite. I could not for the life of me figure out how to do it without impacting on it's ability to correct subdomains i.e. www.foo.bar.com.

My original attempt used:
RewriteCond %{HTTP_HOST} !^www\.(.+)$ [NC]

This works (i.e. picks up the missing 'www') but means that %1 is then not available for the RewriteRule (If a condition doesn't match then it returns no sub-patterns.)

My next attempt tried to use non-greedy matching (but failed miserably since mod_rewrite does not support it). I also tried look ahead and look behind (not supported) and all manor of things before stumbling across the method used in the patch in a forum post somewhere. Honestly, judging by the forum posts I found, the day they put non-greedy matching into mod_rewrite is the day a 1000 people jump up from their seats screaming YES!

Perhaps a mod_rewrite regexp expert can correct me?

rbowen’s picture

I've always been a little confused at the claim that mod_rewrite "doesn't support non-greedy matching." It always has done. ? makes a match non-greedy. .* is greedy, .*? is non-greedy. Just like in Perl, egrep, PHP, and so on.

rbowen’s picture

By the way, mod_rewrite also supports look-ahead and look-behind, in 2.2 and later. Folks still using Apache 1.3 tend to use a whole list of reasons for sticking with 1.3, and this isn't the forum for debating them. However, the move to the latest PCRE in mod_rewrite in 2.2 is one of the more compelling reasons to move into the new century.

cooperaj’s picture

By the way, mod_rewrite also supports look-ahead and look-behind, in 2.2 and later. Folks still using Apache 1.3 tend to use a whole list of reasons for sticking with 1.3, and this isn't the forum for debating them. However, the move to the latest PCRE in mod_rewrite in 2.2 is one of the more compelling reasons to move into the new century.

Granted, though for the vast majority of people this will be a long time coming so it can't be relied upon at all just yet.

If you can suggest a better Regexp for this that would be great. I spent about 1.5 hrs working on this and it was the only working combination I could come up with. I didn't blithely discount non-greedy expressions either. It just seemed that whenever I attempted to use them mod-rewrite failed to match at all. I tested this by using a dead simple expression that should match whether greedy or not. The addition of the '?' (creating '.+?') caused it to stop matching. It was only after googling that I came across claims that mod-rewrite doesn't support non-greedy. Since the claims fitted my results I assumed they were correct.

My only regret is that i didn't keep the expressions as I was testing them so I can't remember what the one that would have worked, had non-greedy worked, looked like.

cooperaj’s picture

FileSize
1.11 KB

I've been working on this and have managed to reduce it back down to two lines for each use case. Any better?

birdmanx35’s picture

Version: 6.x-dev » 7.x-dev

Feature requests -> 7.x-dev

lilou’s picture

Status: Needs review » Needs work

Patch no longer applied.

-1 for this issue : you can't redirect a domain to another.

Morbus Iff’s picture

lilou: of course you could. The only thing this patch does is removes the manual step for the most common situation: "i want my site to be accessible only AT www or non-www". The less likely situation: "I want to redirect my domain to another" now gets the manual step instead (ie., adding a specific Rewrite to handle it).

lilou’s picture

Title: Improve handling of htaccess canonical redirects. » Improve handling of htaccess redirects

Maybe we can add also :

  # To redirect all users to access the site from one or multiple
  # domaine alias to another adapt and uncomment the following:
  # RewriteCond %{HTTP_HOST} ^alias1\.com$ [NC]
  # RewriteCond %{HTTP_HOST} ^alias2\.com$ [NC]
  # RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]
lilou’s picture

lilou’s picture

Status: Needs work » Needs review
c960657’s picture

FWIW there is no reason to put parenthesis about the whole pattern, i.e. instead of
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
you can write
RewriteRule ^.*$ http://%1/$0 [R=301,L]
Not sure if it makes it a lot clearer, though.

1kenthomas’s picture

#12 v2 (at least) will direct subdomain.example.com to www.subdomain.example.com where subdomain != www. This is not a desired behavior given that www.subdomain.example.com will not be picked up by sites/subdomain.example.com. Looking for a solution...

Anonymous’s picture

1.kenthomas,

Just add a RewriteCond for each subdomain:

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

Then example.com would be redirected to www.example.com, but subdomain.example.com and subdomain2.example.com would not.

Gábor Hojtsy’s picture

This automated way of handling the domain looks like a great concept :)

Anonymous’s picture

Status: Needs review » Needs work

The last submitted patch failed testing.

scor’s picture