Forum Moderators: phranque

Message Too Old, No Replies

Error Log reveals Mod_rewrite error

         

creaturecorp

1:46 am on Aug 15, 2005 (gmt 0)

10+ Year Member



Hello All!

I posted here a while ago, because I was having problems getting wildcard dns and mod_rewrite to play nicely together. It turned out that putting my code in the main httpd.conf did the trick.

I was able to make the subdomains work, mapping *.mydomain to user/user.php?user=*, but when I try to change the code so more than one page can be accessed, my error log says:

RewriteRule: bad flag delimiters

This is when using the code found in [webmasterworld.com...]

RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST}!^www\. [NC]
RewriteCond %{HTTP_HOST}<>%{REQUEST_URI} ^([^.]+)\.example\.com(:80)?<>/([^/]*) [NC]
RewriteCond %1<>%3!^(.*)<>\1$ [NC]
RewriteRule ^(.*) /%1/$1 [L]

however if i replace the last line with
RewriteRule ^(.*) user/user.php?user=%1 [L]
it works fine.

Is there something I'm doing wrong or missing? My goal is to have something like:

RewriteRule ^(.*) user/<filename>.php?user=%1 [L]

~Creaturecorp

jdMorgan

4:25 pm on Aug 15, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



"Bad flag delimiters" usually means an extra or unescaped space in a regex pattern, or a missing "[" or "]".

That fur-ball of code you copied is much more complex than what you need if you're putting the code in httpd.conf. The added complexity is only needed to work in the .htaccess enviroment, preventing an "infinite" loop for internal requests which have already been rewritten to the subdomain-subdirectory. You don't need that complexity in httpd.conf.

In addition, the code will only work on a server running an OS that supports POSIX 1003.2 regular expressions -- a minority. This is because is uses POSIX 1003.2 "atomic back-references" in the fourth line of code to do a "compare" of the requested subdomain and the requested top-level subdirectory. If they are already the same, then the rewrite is not performed, preventing a loop.

For httpd.conf, all you should need is something like this:


RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com [NC]
RewriteRule (.*) /%1/$1 [L]

Note that you may want to do case-conversion on the subdomains, so as to avoid the problem where someone requests "http:SHOUT.example.com" -- If you don't convert the case, then the subdirectory request will fail.

An example of case-conversion using RewriteMap and the system tolower command is given in the mod_rewrite documentation. That and other reference documents are cited in our forum charter.

Also, note that I can criticize the code you found because I wrote it. :)

Jim

creaturecorp

6:51 pm on Aug 15, 2005 (gmt 0)

10+ Year Member



I can't believe I did that.

I said httpd.conf instead of .htaccess. I have the code I showed you in .htaccess.

Sorry for making you write all that: I do understand the idea of putting it in httpd.conf. Is there any advantage to doing this?

jdMorgan

10:09 pm on Aug 15, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Does your server support POSIX 1003.2 regex?
Can you put the code in httpd.conf?
It's much more efficient there, and that's the only option if the answer to question #1 is "no."

Jim

creaturecorp

2:19 am on Aug 16, 2005 (gmt 0)

10+ Year Member



I put exactly what you said into the file, but restarting apache fails. Is there any specific place where I have to put it?

I have a virtualhost setup so my domain responds to subdomain requests.

<VirtualHost 69.9.xx.#*$!>

DocumentRoot /home/xxx/public_html/
ServerAlias *.example.com
ServerName www.example.com

</VirtualHost>

RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST}!^www\. [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com [NC]
RewriteRule (.*) /%1/$1 [L]

jdMorgan

12:43 pm on Aug 16, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Please answer my questions, so that I can (possibly) answer yours...

Jim

creaturecorp

1:27 am on Aug 17, 2005 (gmt 0)

10+ Year Member



I can put it in httpd.conf, so that seems to make the posix .htaccess thing irrelevant, doesn't it?

I don't think that my server supports it, because that would be the only reason for the error.

jdMorgan

1:39 am on Aug 17, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



In httpd.conf, you'll need a leading slash on the RewriteRule pattern:

RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com [NC]
RewriteRule [b]^/([/b].*) /%1/$1 [L]

Also, you don't need the blank-check on HTTP_HOST, because the second remaining RewriteCond would fail if it were blank.

Jim

creaturecorp

2:17 am on Aug 18, 2005 (gmt 0)

10+ Year Member



When I put this is httpd.conf, apache still fails on restart.

In light of this problem, perhaps it would be better to keep it in htaccess. I'm not truly doing subdomains: but rather something like this:

RewriteCond %{HTTP_HOST}!^www\. [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com [NC]
RewriteRule ^journal/(.*) user/journal.php?user=%1 [L]
RewriteRule ^gallery/(.*) user/gallery.php?user=%1 [L]
RewriteRule ^activity/(.*) user/activity.php?user=%1 [L]
RewriteRule ^(.*) user/user.php?user=%1 [L]

The ^<inser_page_name_here>/(.*) doesn't seem to work. Any suggestions?

Could something like this be done instead? I think it will be better to have specific rewrites to keep things secure.

Thanks for your help and patience.

jdMorgan

2:27 am on Aug 18, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Well, it's a bit hard to figure out what your goal is.

One thing that I should point out is that a RewriteCond applies only to the first (single) RewriteRule that follows it. Therefore, %1 is undefined for all but your first rule. You could use user-defined envars to overcome this, though.

Do you have FollowSymLinks enabled?
How about RewriteEngine on?

I have to ask, because you don't show them.

Jim

jdMorgan

2:48 am on Aug 18, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Here's one way to write what I think you may be trying to do:

Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com [NC]
RewriteRule .* - [E=userID:%1]
RewriteRule ^(journal¦gallery¦activity)/ /user/$1.php?user=%{ENV:userID} [L]
RewriteRule .* /user/user.php?user=%{ENV:userID} [L]

For use in httpd.conf, each RewriteRule pattern should start with "^/"

The variable name "userID" is arbitrary, except that it must not conflict with any system-defined variable.

Replace the broken pipe "¦" characters above with solid pipes from your keyboard; Posting on this board modifies them.

Jim

creaturecorp

3:33 am on Aug 18, 2005 (gmt 0)

10+ Year Member



RewriteRule .* /user/user.php?user=%{ENV:userID} [L]

For some reason that line is giving me trouble.

Also, I've got another pile of rewrites in the file. Because of this, something like the following may occur:

http://example.com/view/1
and
[username.example.com...]

will bring up the same url. The latter url shouldn't bring up anything.

#################

RewriteEngine On
Options +FollowSymLinks

RewriteCond %{HTTP_HOST}!^www\. [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com [NC]
RewriteRule .* - [E=userID:%1]
RewriteRule ^(journal¦gallery¦activity)/ /user/$1.php?user=%{ENV:userID} [L]
#RewriteRule ^ /user/user.php?user=%{ENV:userID} [L]

RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^([a-z]+)[/]?$ /$1.php [L]

RewriteRule ^fav/([0-9]+)[/]?$ /fav.php?id=$1 [L]
RewriteRule ^view/([0-9]+)[/]?$ /view.php?id=$1 [L]
RewriteRule ^full/([0-9]+)[/]?$ /view.php?id=$1&full=1 [L]
RewriteRule ^comments/([0-9]+)[/]?$ /reply.php?id=$1 [L]

#################

Thanks so much for your help, It's truly appreciated.

jdMorgan

2:04 pm on Aug 18, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Yes, sorry, missed that:

RewriteCond %{HTTP_HOST}!^www\. [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com [NC]
RewriteRule .* - [E=userID:%1]
#
RewriteCond %{ENV:userID} .
RewriteRule ^(journal¦gallery¦activity)/ /user/$1.php?user=%{ENV:userID} [L]
#
RewriteCond %{ENV:userID} .
RewriteRule .* /user/user.php?user=%{ENV:userID} [L]

Also, it would be more "standard" if you were to move your RewriteBase directive to the top of the rules, under RewriteEngine on.

If you end up with more that just a few rules based on userID, then you could use a [S]kip construct to eliminate multiple checks of the userID for non-blank.

Jim

creaturecorp

4:55 pm on Aug 18, 2005 (gmt 0)

10+ Year Member



Absolutely spot on.

RewriteRule .* user/user.php?user=%{ENV:userID} [L]
(the slash before user was causing an error)

In my post above, you saw how I have some conditions that follow the subdomain user rewrite. Would it be possible to change

RewriteCond %{REQUEST_FILENAME} !-d

to cancel all the following rewrites if the %{ENV:userID} is set? This would mean that nothing except the subdomain rewrite would execute, therefore preventing any conflicts. (eg http://example.com/view/1/ being accessible at [username.example.com...] shouldn't occur)

Your help has really been great, just what the doctor ordered. :)

jdMorgan

6:22 pm on Aug 18, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Sure, just follow the last rule I posted in msg #13 with :

RewriteCond %{ENV:userID} .
RewriteRule .* - [L]

Which says, "If userID is non-blank, then leave the URL alone and quit here."

I'll refer you to the documentation now, to analyze the code line-by line so that you can understand it and modify it to suit your changing needs over time. Several good links are posted in our charter, and there are also some good threads in the WebmasterWorld library [webmasterworld.com].

Jim

creaturecorp

12:54 am on Aug 19, 2005 (gmt 0)

10+ Year Member



Thanks so much, now that I understand everything a bit more I can probably manage without any trouble. All the advice was very helpful.

~Creaturecorp