Forum Moderators: phranque

Message Too Old, No Replies

losing hair with mod_rewrite

         

bg011ca

7:04 pm on Apr 5, 2005 (gmt 0)

10+ Year Member



I have virtual hosts.
They are setup via vhost.conf on apache2

I need to add www subdomain on some of them.
So user who ask for http://sample.net end up on http://www.sample.net.

I have tried so many suggestions that I've found here, none of them worked.
As if .htaccess file, if used, is not read, or RewriteRule, under VirtualHost sections in vhost.conf file do not apply.

At the moment, I have, using vhost.conf this, and I have soem other VirtualHosts above, that I do not want to force to use www:

<VirtualHost 182.***.41:80>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^([a-z]+\.com) [NC]
RewriteRule (.*) http://www.%1$1 [R=301,L]
DocumentRoot /var/www/html/sample.net
ServerName www.sample.net
</VirtualHost>

[edited by: jdMorgan at 7:44 pm (utc) on April 5, 2005]
[edit reason] Obscured IP address. [/edit]

sitz

7:33 pm on Apr 5, 2005 (gmt 0)

10+ Year Member



In order to use Rewrite* directives in .htaccess files, the 'FileInfo' option must be in place for the AllowOverride directive applying to the directoryu containing the .htaccess file. That said, httpd.conf is, generally, the preferred method of configuring mod_rewrite. You can turn on logging in your <VirtualHost> container like so:

RewriteLog /path/to/rewrite.log
RewriteLogLevel 9

I would advise against configuring this for a VirtualHost which sees any significant traffic, as the logging is quite verbose. Note that you will (obviously) need to bounce apache for any changes to httpd.conf to take effect. Note also that the request will (again, obviously) not be processed by mod_rewrite if the request isn't passed to the VirtualHost configured to Rewrite.

To ensure that the proper <VirtualHost> block is reached, ensure that you have a proper NameVirtualHost directive, that the IP/port used in the NameVirtualHost directive matches that of the <VirtualHost>, and that the ServerName in the VirtualHost matches the hostname you're using to access the site.

bg011ca

8:02 pm on Apr 5, 2005 (gmt 0)

10+ Year Member



At the moment I am trying to configure this not using .htaccess file.

Section that I have addedd to VirtualHost is from
[webmasterworld.com...] I am hoping to somehow reuse that in more general scenario.

I do belive that all about VirtualHost, as it is configured at the moment, is configured properly, as everything is working like it should.

Also, the way Apache resolves visit to non-www request is to send all of those to default site, same as if you would access server only using IP address, according to first VirtualHost directive in vhost.conf file.

I am not in fawor of loging what mod_rewrite does, unless required for it to work properly.

sitz

8:28 pm on Apr 5, 2005 (gmt 0)

10+ Year Member



The use of the RewriteLog is not required for it to work (in fact, using it in production is not really advised). However, it's a VERY useful debugging tool, which can help you pinpoint the error; my apologies for not being more clear about this.

There are several steps to debugging this. The first is to determine whether mod_rewrite is refusing to process the request for some reason, or if it's simply never being invoked. Use of the Rewriteog directive is one way to accomplish this. Another would be to create a very simple (bogus) Rule, like this:


RewriteEngine on
RewriteRule ^/TESTING http://www.google.com/ [L,R]

...and bounce Apache. If requesting [yoursite.com...] redirects you to google, you at least know that mod_rewrite is being invoked, and then need ot figure out what's wrong with your particular rule. If the redirect doesn't happen, you need to determine why mod_rewrite isn't receiving the request for processing.

bg011ca

9:18 pm on Apr 5, 2005 (gmt 0)

10+ Year Member



So where exacly do I put those lines?

Somewhere in httpd.conf?

Someplace in vhost.conf? vhost.conf is used by
Include conf.d/*.conf statement in httpd.conf file.

In .htaccess file? And where that file should be placed?

On the same token, lines to activate log files. WHere is a proper place for them?

Thanks

sitz

11:00 pm on Apr 5, 2005 (gmt 0)

10+ Year Member



In the VirtualHost container you're trying to access.

bg011ca

11:20 pm on Apr 5, 2005 (gmt 0)

10+ Year Member



So far so good. That worked.
Used another VirtualHost though.
Now that container looks like:

<VirtualHost 192.168.0.41:80>
ServerAdmin webmaster@test.com
DocumentRoot /var/www/html/test.com
ServerName www.test.com
RewriteEngine on
RewriteRule ^/testing [google.com...] [L,R]
</VirtualHost>

Just for reference, in my hosts file, for every VirtualHost, I do create stuff like:

192.168.0.41 test.com
192.168.0.41 www.test.com

Thanks and what next?

bg011ca

12:22 am on Apr 6, 2005 (gmt 0)

10+ Year Member



Aha.
You actualy did give me a clue which way to look.

Here it is.
Being that first one of VirtualHost is also defaulf one, one that end up answering to everything that does not get resolved by all other VirtualHost directives, that one is supposed manage adding www.

So, first VirtualHost directive looks like this:

<VirtualHost 192.168.0.41:80>
ServerAdmin webmaster@generic
DocumentRoot /var/www/html/generic
ServerName byIP
RewriteEngine On
RewriteCond %{HTTP_HOST} ^([a-z]+\.com) [NC]
RewriteRule (.*) [%1$1...] [R=301,L]
</VirtualHost>

All other VirtualHost directives are same as before.

Now I have two options:

How to manage all posible combinations of allowed characters, letters and numbers, in domain name, and any tld, nit just .com? But, then that will then work for any http request, not only domains hosted by my server.

More secure will be that only VirtualHosts, actualy hosted by me are the only ones that endup being forced to use www.
So somehow RewrireCond in first VirtualHost should do the job only if requested URL is one of alowed, served by same server.

sitz

5:02 am on Apr 6, 2005 (gmt 0)

10+ Year Member



Just for reference, in my hosts file, for every VirtualHost, I do create stuff like:

192.168.0.41 test.com
192.168.0.41 www.test.com

Entries like this are only needed if a) you need to access the site by hostname *and* b) the hostname is not in DNS. Even then, the entries *only* need to be made in the hosts file of the computer you're making the request *from*, which is (usually) not the server.

How to manage all posible combinations of allowed characters, letters and numbers, in domain name, and any tld, nit just .com? But, then that will then work for any http request, not only domains hosted by my server.

Yeah, that's likely overkill; you only really need to worry about the ones you actually host. Any requests for sites you don't host aren't your concern (and shouldn't wind up at your server anyway).

More secure will be that only VirtualHosts, actualy hosted by me are the only ones that endup being forced to use www.
So somehow RewrireCond in first VirtualHost should do the job only if requested URL is one of alowed, served by same server.

Right, however note that:


RewriteCond %{HTTP_HOST} ^([a-z]+\.com) [NC]

...while close, missing a few cases; such as:

my-site.com
subdomain.mysite.com

Do you want to redirect subdomain.mysite.com to www.subdomain.mysite.com?

A better solution might be:


RewriteEngine on
#
# if it doesn't start with 'www.', rewrite. No need
# to use parentheses and backreferences if we don't
# have to
RewriteCond %{HTTP_HOST}!^www\. [NC]
RewriteRule ^/(.*) http://www.%{HTTP_HOST}/$1 [L,R=301]

This handles the subdomain case as well as hypenated domain names. If you explicitly do NOT want to handle the subdomain case, a better solution might be:

RewriteEngine on
#
# If the Host: header is a string of non-'.' characters
# followed by a dot, followed by another string of
# non-'.' characters (such as "foo.com" or
# "foo-bar.com (but not "foo.bar.com", as that has two
# '.' characters)), Rewrite. We use the optional port
# number on the end so that can use the '$' to indicate
# the end of the string.
RewriteCond %{HTTP_HOST} ^[^.]+\.[^.]+(:80)$ [NC]
RewriteRule ^/(.*) http://www.%{HTTP_HOST}/$1 [L,R=301]

Make sense?

bg011ca

3:34 pm on Apr 6, 2005 (gmt 0)

10+ Year Member



Your comments do make sense.
I like explanation for the last peace of code a lot.
But...

My first, "default", virtual host section looks like this:

<VirtualHost 192.168.0.41:80>
ServerAdmin webmaster@generic
DocumentRoot /var/www/html/generic
ServerName byIP
RewriteEngine On
#
# RewriteCond %{HTTP_HOST} ^([a-z]+\.com) [NC]
# RewriteRule (.*) [%1$1...] [R=301,L]

# RewriteCond %{HTTP_HOST}!^www\. [NC]
# RewriteRule ^/(.*) [%{HTTP_HOST}...] [L,R=301]

RewriteCond %{HTTP_HOST} ^[^.]+\.[^.]+(:80)$ [NC]
RewriteRule ^/(.*) [%{HTTP_HOST}...] [L,R=301]

</VirtualHost>

From code, I would say that I am trying to apply your suggested solution.
Off all three sections, RewriteCond and RewriteRule, only first one works, www suffix is added and in address bar redirected URL appears.

Other two, when applied, do not affect anything, asked URL stays same, user gets generic site, as if it asking for [192.168.0.41...]

In any of those three cases, sites with www in URL appear properly.

I do restart apache after comment / uncomment lines in vhost.conf.
I do clear IE, so I do not get cached sites.

IS there something that I am missing?

And if I would like to handle only two virtual hosts, how would RewriteCond RewriteRule line look like, if needs to be applied only when URL asked are [site1.com...] or [site2.net...]

I have tried all kinds of syntax, manage to lose characters in .tld, manage to add \ characters, manage to prevent Apache loading because compile/syntax error in vhost.conf, etc.

bg011ca

4:31 pm on Apr 6, 2005 (gmt 0)

10+ Year Member



I got it.
Here are the three lines of code that will handle non www requests, but only for some of virtual hosts, site1.com, site2.net and site3.org in this case:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^(site1\.com¦site2\.net¦site3\.org) [NC]
RewriteRule (.*) [%1$1...] [R=301,L]

Replace all broken pipe "¦" characters with solid pipe characters.

This goes in first, default, VirtualHost section.
Somewhere below, VirtualHost sections for those three sites are setup as required.

Thanks a ton.