Forum Moderators: phranque

Message Too Old, No Replies

mod rewrite help needed :(

mod rewrite, domain to folder, users to folder

         

DVirus

5:31 pm on Nov 9, 2007 (gmt 0)

10+ Year Member


Dear experts,
I have a little (maybe!) problem about mod_rewrite...

I'll try to explain what I need...

I have 2 questions:
1) I have some subdomains such as a.domain.com , b.domain.com , etc..
And I'd like to handle all these subdomains in a folder, so I'd like to make them converted as:
a.domain.com --> domain.com/a
b.domain.com --> domain.com/b
etc...

2) I have some users who have own webpages, but I don't want to let them use ~user prefixes... So I'd like to convert:
domain.com/~user --> domain.com/user or user.domain.com

If someone do me a favor and tell what must I use in httpd.conf for all situations, I'll be appreciated...
Thanks..

sitz

6:55 pm on Nov 9, 2007 (gmt 0)

10+ Year Member



#1 has been addressed numerous times; check the archives

regarding #2, the problem is differentiating between a users' home directory and another directory you have in the document root. There's a non-mod_rewrite way to handle this; I generally place the users' websites directly in the document root and then place a 'www' symlink in their home directory; this will work whether the user ssh's to the webserver or FTP's in. So your setup would be something like:


/var/www/htdocs/example.com/user1
/var/www/htdocs/example.com/user2
/var/www/htdocs/example.com/user3


/home/user1/www -> /var/www/htdocs/example.com/user1
/home/user2/www -> /var/www/htdocs/example.com/user2
/home/user3/www -> /var/www/htdocs/example.com/user3

If this is not an option, the cheapest way I know of to handle this sanely is with a RewriteMap.

map.txt
=====================


user1 /var/www/htdocs/example.com/users/user1
user2 /var/www/htdocs/example.com/users/user2
user3 /var/www/htdocs/example.com/users/user3

httpd.conf
==========


RewriteEngine on

#
# define a map
RewriteMap usermap txt:/tmp/map.txt

#
# extract the text after the first '/' up to (but not including
# an optional second '/' and store it in the %1 backreference
RewriteCond %{REQUEST_URI} ^/([^/]+)

#
# Verify that the text extract above is in the map file; if it is,
# store it in the %1 backreference
RewriteCond ${usermap:%1} (.+)

#
# The LHS verifies that request has /some/ text after the first '/';
# this ensures the ruleset won't be evaluated for requests for '/'. It
# also captures any (optional) text after the second '/' and stores
# it in the $1 backreference. The RHS rewrites the request to the
# result of the map lookup above + any additional path data from the
# LHS of the rule. Query strings will be appended automatically.
RewriteRule ^/[^/]+(/.*)? %1$1 [L]

DVirus

8:11 pm on Nov 9, 2007 (gmt 0)

10+ Year Member


Thank you, i searched and find something about #1..
But, it's not working in my config...
I think I did something wrong: (could you please check this one if it's correct?)

RewriteEngine on
RewriteLogLevel 9
RewriteLog logs/virtuals.log
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST}!^www\. [NC]
RewriteCond %{HTTP_HOST}<>%{REQUEST_URI} ^([^.]+\.my\.domain\.com(:80)?<>/([^/]*) [NC]
RewriteRule ^(.*) /%1/$1 [L]

And there's a strange problem, apache getting in to the loop when i try http://my.domain.com only... (I can see from the logs, same page is continuously trying..) By the way, I don't use www.my.domain.com, just using my.domain.com...
I couldn't fix this :[smilestopper](

jdMorgan

9:21 pm on Nov 9, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



That code looks like a mash-up, and contains several unneeded pieces. There is also an error in your third RewriteCond pattern -- a missing parenthese.

Also, for the sake of future growth and flexibility of your site, I strongly recommend that you separate all these user accounts from your main (top-level) directory. Doing so will also help to prevent looping.

If you are putting the code in httpd.conf, conf,d, or some other server config file (and not in .htaccess), then the rule pattern should be modified as well:


RewriteEngine on
RewriteLogLevel 9
RewriteLog logs/virtuals.log
#
RewriteCond %{REQUEST_URI} !^/users/
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^([a-z][a-z0-9\-]+[a-z0-9])\.example\.com
RewriteRule ^/(.*)$ /users/%1/$1 [L]

Note that the subdomain pattern only accepts a limited subdomain-name format; Subdomains must start with a lowercase letter, be followed by one or more lowercase letters, numbers, or hyphens, and end with a lowercase letter or number. This forces compliance with the HTTP specifications and prevents your users from trying to create invalid subdomain names, and also prevents problems with mixed-case subdomains, which Apache would map to different subdirectories because it is case-sensitive.

Be sure to turn off rewrite logging as soon as you get this working -- RewriteLogLevel 9 puts quite an extra load on your server.

Also, flush your browser cache completely and restart your server before testing this or any new code.

Jim

DVirus

10:24 pm on Nov 9, 2007 (gmt 0)

10+ Year Member


Thank you very much... #1 process is done with your great help...

And now, i'm trying to make #2 :[smilestopper])
For this, I disabled Userdir, and trying something like that:

RewriteEngine on
RewriteLogLevel 9
RewriteLoglogs/virtuals.log

# Skip rewrite if no hostname or if domain is my.domain.com
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} ^my.domain.com$ [NC]
RewriteCond %{REQUEST_URI} ^/~([a-zA-Z0-9_]+)([^/?$])
RewriteRule (.*) /%1/$2 [L]

is it possible? In this manner, in http://my.domain.com/~user/...
format, ~user acts as a standart folder and not user..
So, I think it should possible to forward them to another folder or domain?

By the way, if I use $1 instead $2, in the logs, it converts path to /user/~user/ and it's not available.. if I use $2, nothing happens and pattern doesn't match...

If you have time and patient, could you please check this?
Thank you...

jdMorgan

10:36 pm on Nov 9, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



If you are trying to disable ~user directories, just use:

UserDir disabled

You can even enable or disable specific ~users -- See mod_userdir [httpd.apache.org] for more info.

Jim

DVirus

10:55 pm on Nov 9, 2007 (gmt 0)

10+ Year Member


No, I actually want to convert ~user/.... to /user/... format..
To do this, I disabled Userdir from http.conf..
~ is a problem for me at the moment...

I'd like to have virtual users, and we have several users that have own webpages, so I'd like to remove real users from the system..
But they use ~user usually, so I have to find a solution for that..

I tried this one:

RewriteEngine on
RewriteLogLevel 9
RewriteLoglogs/virtuals.log
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} ^my.domain.com$ [NC]
RewriteCond %{REQUEST_URI} ^/~([a-zA-Z0-9_]+)/[(.*)]?$
RewriteRule (.*) /%1/$2 [L]

It's working (and shows indexes while Option has +Indexes) if URL is just http://my.domain.com/~user ...

But if there's a file next to this path like http://my.domain.com/~user/index.php , it doesn't convert and search for /~user/index.php from the folder... So it's not working :[smilestopper](

Could you please check where's wrong in that rules?
If you need, Apache rewrite logs are similar to this:

(2) init rewrite engine with requested uri /~user/
(3) applying pattern '(.*)' to uri '/~user/'
(4) RewriteCond: input='my.domain.com' pattern='.' => matched
(4) RewriteCond: input='my.domain.com' pattern='^my.domain.com$' [NC] => matched
(4) RewriteCond: input='/~user/' pattern='^/~([a-zA-Z0-9_]+)/[(.*)]?$' => matched
(2) rewrite '/~user/' -> '/user/'
(2) local path result: /user/
(2) prefixed with document_root to C:/Internet/xampp/htdocs/user/
(1) go-ahead with C:/Internet/xampp/htdocs/user/ [OK]
(2) init rewrite engine with requested uri /~user/index.php
(3) applying pattern '(.*)' to uri '/~user/index.php'
(4) RewriteCond: input='my.domain.com' pattern='.' => matched
(4) RewriteCond: input='my.domain.com' pattern='^my.domain.com$' [NC] => matched
(4) RewriteCond: input='/~user/index.php' pattern='^/~([a-zA-Z0-9_]+)/[(.*)]?$' => not-matched
(1) pass through /~user/index.php
(2) init rewrite engine with requested uri /~user/index.html
(3) applying pattern '(.*)' to uri '/~user/index.html'
(4) RewriteCond: input='my.domain.com' pattern='.' => matched
(4) RewriteCond: input='my.domain.com' pattern='^my.domain.com$' [NC] => matched
(4) RewriteCond: input='/~user/index.html' pattern='^/~([a-zA-Z0-9_]+)/[(.*)]?$' => not-matched
(1) pass through /~user/index.html
(2) init rewrite engine with requested uri /error/HTTP_FORBIDDEN.html.var
(3) applying pattern '(.*)' to uri '/error/HTTP_FORBIDDEN.html.var'
(4) RewriteCond: input='my.domain.com' pattern='.' => matched
(4) RewriteCond: input='my.domain.com' pattern='^my.domain.com$' [NC] => matched
(4) RewriteCond: input='/error/HTTP_FORBIDDEN.html.var' pattern='^/~([a-zA-Z0-9_]+)/[(.*)]?$' => not-matched
(1) pass through /error/HTTP_FORBIDDEN.html.var

[1][[b]edited by[/b]: DVirus at 10:58 pm (utc) on Nov. 9, 2007][/1]

jdMorgan

11:16 pm on Nov 9, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Simplify!

RewriteEngine on
RewriteLogLevel 9
RewriteLoglogs/virtuals.log
#
RewriteCond %{HTTP_HOST} ^example\.com
RewriteRule ^/~([a-z0-9_]+/.*)$ /users/$1 [NC,L]

You never need to check for a non-blank host using
RewriteCond %{HTTP_HOST} .
if there is a following positive-match pattern for a hostname. You only need to do this if there is a negative-match pattern like
RewriteCond %{HTTP+HOST} !^www\.example.com
because the negative-match pattern would otherwise match a blank hostname.

Also, do not end-anchor ($) hostnames unless you end the pattern with "(:80)?$" or "(:[0-9]+)?$". Otherwise, any client that appends a port number (and this is valid) to its request will break your RewriteRules!

Again, I strongly recommend storing your users' files in a separate subdirectory, such as /users/ and have written the rule above to support that.

Jim

DVirus

9:10 pm on Nov 11, 2007 (gmt 0)

10+ Year Member


Thank you very much for your great help..
I'm a bit late because I could check at the moment...
It's done completely...

I'll take care about the rules according to your suggestions..
Thanks again..