Search code examples
debuggingmod-rewritemod-proxy

how to properly mod_rewrite


I am using apache2 + tomcat on ubuntu 10.4. I am running on tomcat server that has webapps listening on 8080

"http://internal:8080/dir/name-privatewebapp/"
"http://internal:8080/dir/name-publicwebapp/"

External facing Apache server is proxying requests for the domain.

I would like to remap "subdomain" to "domain.com/subdomain" , so any other requests would be proxied to the appropriate path / webapp

web.john-doe.domain.com  --->  www.domain.com/web/john-doe 


http://www.john-doe.com  --->   www.domain.com/web/john-doe
http://www.foo-bar.com  --->  www.domain.com/web/foo-bar

I couldnt make it work with mod_rewrite alone. I have been looking into mod_proxy, mod_proxy_ajp, and mod_rewrite

I would like the server to

  1. Grab the subdomain from the domain
  2. Make sure the subdomain is not www, w or ww
  3. Check if the directory actually exists on "www.domain.com" before rewrite
  4. if the directory doesnt exist it stays as wild domain
  5. Finally, if the directory exist the actual rewrite

I checked several links and studied tutorials on http://www.askapache.com/htaccess/crazy-advanced-mod_rewrite-tutorial.html

It is without success.

I followed this illumin-it.servehttp.com/wordpress/2012/01/redirecting-to-as-using-apache/ with a bit of success.

However, I would like to the server to do it on the fly through rewrites and proxies without editing the vhost for every subdomain.

here is my updated vhost file

<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName www.domain.com
ServerAlias www.domain.com domain.com *.domain.com
RedirectPermanent / http://www.domain.com
DocumentRoot /var/www
<Directory />
    Options FollowSymLinks
    AllowOverride None
</Directory>
<Directory /var/www/>
    Options Indexes FollowSymLinks MultiViews
    AllowOverride None
    Order allow,deny
    allow from all
<IfModule mod_rewrite.c>    
    Options +FollowSymLinks
    Options +Indexes

    RewriteEngine On
    RewriteBase /

    # Prevent looping this rule
#       RewriteCond %{ENV:REDIRECT_STATUS} !200
#       RewriteCond %{HTTP_HOST} !www.domain.com$ [NC]
#       RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9.-]+).domain.com$ [NC]
#       RewriteRule (.*) /%2/$1 [L]

    # change the "." in the path to "/"
#       RewriteRule ^(.*)\.(.*)/(.*)$ /$1/$2/$3 [L]

    #redirect domain.com to www.domain.com
    RewriteCond %{HTTP_HOST} !^domain\.com$ [NC]
    RewriteRule ^ http://www.domain.com%{REQUEST_URI} [R=301,NC]
</IfModule> 
</Directory>

ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
    AllowOverride None
    Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
    Order allow,deny
    Allow from all
</Directory>

ErrorLog /var/log/apache2/error.log

# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn

CustomLog /var/log/apache2/access.log combined

Alias /doc/ "/usr/share/doc/"
<Directory "/usr/share/doc/">
    Options Indexes MultiViews FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all
    Allow from 127.0.0.0/255.0.0.0 ::1/128
</Directory>
<Proxy *>
Order deny,allow
Allow from all
</Proxy>

#   ErrorLog /var/log/apache2/webapp_error.log
#   LogLevel warn
#   CustomLog /var/log/apache2/webapp_access.log combined

ProxyPass / ajp://localhost:8009/
ProxyPassReverse / ajp://localhost:8009/

#   ProxyPass        /user/ http://localhost:8080/user/privatewebapp/
#   ProxyPassReverse /user/ http://localhost:8080/user/privatewebapp/
#
#   ProxyPass        /publicweb/ http://localhost:8080/dir/publicwebapp/
#   ProxyPassReverse /publicweb/ http://localhost:8080/dir/publicwebapp/
#
#   ProxyPass        / http://localhost:8080/dir/publicwebapp/
#   ProxyPassReverse / http://localhost:8080/dir/publicwebapp/

ServerName www.domain2.com
ProxyRequests Off
ProxyPreserveHost On

RewriteEngine On
RewriteCond %{HTTP_HOST} ^dir/publicwebapp$ [NC]
RewriteRule ^(.*)$ http://www.domain2.com/$1 [R=301,L]
<Location / >
Order deny,allow
Allow from all
RedirectMatch ^/$ /dir/publicwebapp/
ProxyPass ajp://localhost:8009/
ProxyPassReverse ajp://localhost:8009/
</Location>
</VirtualHost>

I also tried... http://httpd.apache.org/docs/2.0/rewrite/rewrite_guide.html

assuming www.username.host.com/anypath internally maps to www.host.com/home/username/anypath

As the site's applications created with Java servers, I believe mod_rewrite alone doesnt work.

Virtual User Hosts

RewriteCond   %{HTTP_HOST}                 ^www\.[^.]+\.host\.com$
RewriteRule   ^(.+)                        %{HTTP_HOST}$1          [C]
RewriteRule   ^www\.([^.]+)\.host\.com(.*) /home/$1$2

Solution

  • Your first set of rules:

    #redirect domain.com to www.domain.com
    RewriteCond %{HTTP_HOST} !^www\.domain\.com$ [NC]
    RewriteRule .+ http://www.domain.com%{REQUEST_URI} [R=301,NC]
    

    Is superceding any subdomain you have if you don't have an empty request. The second set of rules comes close to what you want. But they loop and they don't turn multiple subdomain entries into directory paths, so try putting this set of rules first:

    # Prevent looping this rule
    RewriteCond %{ENV:REDIRECT_STATUS} !200
    RewriteCond %{HTTP_HOST} !www.domain.com$ [NC]
    RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9.-]+).domain.com$ [NC]
    RewriteRule (.*) /%2/$1 [L]
    
    # change the "." in the path to "/"
    RewriteRule ^(.*)\.(.*)/(.*)$ /$1/$2/$3 [L] 
    

    Then change your "non-www to www" rule to this (and place after the above rules):

    #redirect domain.com to www.domain.com
    RewriteCond %{HTTP_HOST} !^domain\.com$ [NC]
    RewriteRule ^ http://www.domain.com%{REQUEST_URI} [R=301,NC]