views:

859

answers:

3

I'm trying to write a set of mod_rewrite rules that allow my users to utilize a single folder for doing development on different projects, and not have to mess with adding vhosts for every single project.

My idea to accomplish this, is to set up a "Global VHost" for every single user who needs this ability (only 3-4), the vhost would be something like: .my-domain.com. From there, I want to promote my users to write code as if it were on a domain, and not in a sub folder. For example, if bob was working on a project named 'gnome,' I'd like the URL bob (and anyone else on our internal network) loads to get to this project to be: http://gnome.bob.my-domain.com. But, what I'd like Apache to do, is recognize that "gnome" is a "project" and thus map the request, internally, to bob.my-domain.com/gnome/.

I've got what I thought would work, and it's quite simple, but..it doesn't work! The request just goes into an infinite loop and keeps prefixing the sub domain onto the re-written request URI.

The mod rewrite code i have is:

RewriteEngine On

RewriteCond %{HTTP_HOST} ^([^.]+)\.bob\.my-domain\.com
RewriteCond %{REQUEST_URI} !^/%1.*
RewriteRule ^(.*)$  /%1/$1 [L]

I've googled around a bit about this, but I've yet to find any real solutions that work. Has anyone tried this - or maybe, does anyone have a better idea? One that doesn't involve making a virtual host for every project (I've got designers..I think everyone would agree that a designer shouldn't be making virtual hosts..)

Thanks!

Here is a snippet from the rewrite_log:

[rid#838dc88/initial] (3) [perdir /home/bob/http/] strip per-dir prefix: /home/bob/http/index.html -> index.html
[rid#838dc88/initial] (3) [perdir /home/bob/http/] applying pattern '^(.*)$' to uri 'index.html'
[rid#838dc88/initial] (4) [perdir /home/bob/http/] RewriteCond: input='gnome.bob.my-domain.com' pattern='^([^.]+)\.bob\.my-domain\.com' => matched
[rid#838dc88/initial] (4) [perdir /home/bob/http/] RewriteCond: input='/index.html' pattern='!^/%1.*' => matched
[rid#838dc88/initial] (2) [perdir /home/bob/http/] rewrite 'index.html' -> '/gnome/index.html'
[rid#838dc88/initial] (1) [perdir /home/bob/http/] internal redirect with /gnome/index.html [INTERNAL REDIRECT]
[rid#8392f30/initial/redir#1] (3) [perdir /home/bob/http/] strip per-dir prefix: /home/bob/http/gnome/index.html -> gnome/index.html
[rid#8392f30/initial/redir#1] (3) [perdir /home/bob/http/] applying pattern '^(.*)$' to uri 'gnome/index.html'
[rid#8392f30/initial/redir#1] (4) [perdir /home/bob/http/] RewriteCond: input='gnome.bob.my-domain.com' pattern='^([^\.]+)\.bob\.my-domain\.com' => matched
[rid#8392f30/initial/redir#1] (4) [perdir /home/bob/http/] RewriteCond: input='/gnome/index.html' pattern='!^/%1.*' => matched
[rid#8392f30/initial/redir#1] (2) [perdir /home/bob/http/] rewrite 'gnome/index.html' -> '/gnome/gnome/index.html'
[rid#8392f30/initial/redir#1] (1) [perdir /home/bob/http/] internal redirect with /gnome/gnome/index.html [INTERNAL REDIRECT]
[rid#8397970/initial/redir#2] (3) [perdir /home/bob/http/] add path info postfix: /home/bob/http/gnome/gnome -> /home/bob/http/gnome/gnome/index.html

This is just a snippet, there are a few 10s or 100 or so lines of apache basically rewriting /gnome/index.html to /gnome/gnome/gnome/gnome/gnome/index.html, etc before apache hits its rewrite limit, gives up, and throws error 500

A: 

Some Questions:

You said "map internally" -- do you NOT want to use a redirect?

Are you using the same VirtualHost for gnome.bob.mysite.com and bob.mysite.com

Did you remember to create a ServerAlias for *.bob.mysite.com?


Here is a rough version that you could modify to work. It will capture the subdomain and requested URL, and do a redirect to the main domain with the subdomain as the first part of the path, followed by the requested path, followed by the query string.

ServerName www.mysite.com
ServerAlias *.mysite.com

RewriteCond %{HTTP_HOST} ^([a-zA-Z0-9-]+)\\.mysite.com$
RewriteRule ^/(.*)       http://www.mysite.com/%1/$1        [R=301,L]',
gahooa
I definitely want an internal redirect. the whole purpose of this is to be able to use absolute paths on links, css, img srcs, etc.There is/will be a virtual host for <username>.my-site.com with an alias for *.<username>.my-site.com, so any requested domain of <username>.my-site.com or below will get picked up by that vhost
JimR
A: 

Have you tried using another rewrite rule to process the one before it?

RewriteEngine On

RewriteCond %{HTTP_HOST}                       ^([^.]+)\.bob\.my-domain\.com
RewriteCond %{REQUEST_URI}                     !^/%1.*
RewriteRule ^(.*)$                             /%1/$1 [C]    
RewriteRule ^/(.*)\.bob\.my-domain\.com/(.*)   /$1/$2 [L]

But I think your bigger problem is the fact that your server doesn't understand it is getting served under a different name.

It thinks it is running in the /gnome/ directory while the browser things it is running in the / directory. So any relative URL's that you have are going to cause issues.

What you need is a filter that will run all the URL's in your page through a processor and change them from /gnome/ to /.

Nick Berardi
the idea is to discourage relative urls, but under this structure, they should also work.
JimR
also, I'm fairly sure that the HTTP host isn't used in the RewriteRule, just the URI
JimR
A: 

You might want to check

http://httpd.apache.org/docs/2.2/vhosts/mass.html

it deals with the DocumentRoot problem that you were experiencing.

Rule goes something like this

VirtualDocumentRoot /var/www/%1/

You can change the %1 for whatever suits you (http://httpd.apache.org/docs/2.0/mod/mod_vhost_alias.html)

Cheers

Federico Jaramillo