Forum Moderators: phranque

Message Too Old, No Replies

Trailing slash problem.

There is a problem with the slash...

         

ZachH

2:07 pm on Sep 17, 2005 (gmt 0)

10+ Year Member



Hi

I don't understand regular expression so please be patient. I use mod_rewrite to avoid the ugly query string and it works just fine. There is only one problem.

If someone types:
www.mydomain.com/thedata

Instead of:
www.mydomain.com/thedata/

It will generate an error. The reason for the error is the missing slash(/) in the end. How do I fix this? I've been reading 2-3 threads on Webmaster World, but I still can't figure out what is wrong.

Here is the code in my .htaccess:
# Directory rewrite
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^([^/]+)/$/$1/ [R]
RewriteRule ^([^/]+)/$result.php5?domain=$1 [L]

I would really appreciate if someone could guide me a little bit.

Thanks.

-Zach

jdMorgan

3:38 pm on Sep 17, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Zach,

If I understand what you are trying to accomplish, then replacing your two rules with the following might work better:


# If request_filename does not exist as a directory
RewriteCond %{REQUEST_FILENAME} !-d
# and if request filename plus slash does not exist as a directory
RewriteCond %{REQUEST_FILENAME}[b]/[/b] !-d
# Rewrite to script
RewriteRule ^([^/]+)[b]/?$[/b] /result.php5?domain=$1 [L]

This uses negative logic, with the "!" NOT operator, to be sure that a directory is not being requested before rewriting to the script. It also avoids the external redirect used in the original code, so it should be faster for your visitors. The modified paatern in the rule uses the regex '?' operator to allow a trailing slash, but not require it.

Jim

ZachH

7:48 pm on Sep 17, 2005 (gmt 0)

10+ Year Member



Hi jdMorgan

Looks like you know your stuff :)

I did some minor changes to your code and it is very close, but there is still a minor bug.

Instead of using actual domain as a variable it uses result.php5. So the input is something like this:
result.php5?domain=result.php5

instead of:
result.php5?domain=www.test.com

I think it is a minor error, but I just can't find it.

Can you spot it?

Thanks.

-Zach

jdMorgan

8:26 pm on Sep 17, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The code you first posted has nothing to do with domains, so I don't understand your question.

Please describe what you are trying to do and provide example before-and-after URL-paths.

Jim

ZachH

8:51 pm on Sep 17, 2005 (gmt 0)

10+ Year Member



Ok thank you for your patience.

Lets take it from the beginning, here is what we want to happen.
Someone types:
www.mydomain.com/variable/

Behind de scenes the following happen:
www.mydomain.com/result.php5?domain=variable

Unfortunatly this does not work when someone types:
www.mydomain.com/variable

The changes you made seem to work, but for some reason the variable wasn't used correctly so the following happened behind the scenes:
www.mydomain.com/result.php5?domain=result.php5

So basically the input from the user isn't used at all.

Let me know if this helps, if not I will try again :)

Thanks.

jdMorgan

9:03 pm on Sep 17, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



It looks like the rewrite looped -- called itself, that is.
So, another RewriteCond will be required to stop the looping:

# Prevent recursion
RewriteCond %{REQUEST_URI} !^/result\.php5$
# If request_filename does not exist as a directory
RewriteCond %{REQUEST_FILENAME} !-d
# and if request filename plus slash does not exist as a directory
RewriteCond %{REQUEST_FILENAME}/ !-d
# Rewrite to script
RewriteRule ^([^/]+)/?$ /result.php5?domain=$1 [L]

Jim
[edit] Corrected spacing problem. [/edit]

[edited by: jdMorgan at 9:40 pm (utc) on Sep. 17, 2005]

ZachH

9:20 pm on Sep 17, 2005 (gmt 0)

10+ Year Member



Hi Jim

Still something wrong, now I get an Internal Server Error now.

I guess there must be a small bug somewhere....

-Zach

ZachH

9:23 pm on Sep 17, 2005 (gmt 0)

10+ Year Member



One more thing...

I think the / in front of result.php5 should be removed so that it looks like this:
RewriteRule ^([^/]+)/?$ result.php5?domain=$1 [L] ¨

It does not fix the Internal Server Error, but I think that is how it is supposed yo be.

Regards,

-Zach

jdMorgan

9:40 pm on Sep 17, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Make sure there are spaces between "}" and "!". Posting on this forum removes them (corrected above).

> but I think that is how it is supposed yo be.
If you are modifying the code I post before testing, I cannot help much.

Jim

ZachH

10:15 pm on Sep 17, 2005 (gmt 0)

10+ Year Member



Hi Jim

The Internal Server Error was fixed, great.

After I put in the last piece of code it just said:
Not Found
The requested URL /result.php5 was not found on this server.

This comes up no matter what page is requested, so even if I go for the frontpage that doesn't call result.php5.

Does that help a little bit?

Thanks.

-Zach

jdMorgan

10:28 pm on Sep 17, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Where is the php file located with respect to the root directory of the site?

I assumed that it would be in your 'root' directory. If not, add its path to the substitution in the RewriteRule. You can use the 'relative' path by omitting the slash, but this can result in unexpected problems as well, which is why I prefer to use a server-relative URL-path.

Jim

ZachH

10:31 pm on Sep 17, 2005 (gmt 0)

10+ Year Member



That is correct it is all in the root directery. I'm not sure I understand what the consequences of that are.

-Zach

jd01

7:04 pm on Sep 18, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Could you post your entire .htaccess file? -- examplified of course

Justin

ZachH

7:28 pm on Sep 18, 2005 (gmt 0)

10+ Year Member



Here is the full .htaccess:
# Begin php5 rewrites
RewriteEngine On

# encounter php4? stop
RewriteRule \.php4 - [L]

# handle /~user
RewriteCond %{SERVER_PORT} !81
RewriteCond %{REQUEST_URI} ^/~testdir
RewriteRule \.php [localhost:81%{REQUEST_URI}...] [P,L]

# handle subdomains
RewriteCond %{SERVER_PORT} !81
RewriteCond %{REQUEST_URI} \.php
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.mydomain.com$ [NC]
RewriteRule .* %{HTTP_HOST}%{REQUEST_URI} [C]
RewriteRule ^([^.]+)\. [localhost:81...] [P,L]

# catchall
RewriteCond %{SERVER_PORT} !81
RewriteRule \.php [localhost:81...] [P,L]
# End php5 rewrites

# Directory rewrite
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^([^/]+)/$/$1/ [R]
RewriteRule ^([^/]+)/$result.php5?domain=$1 [L]

jd01

8:12 pm on Sep 18, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I think I would use some different logic...

1st Make sure everything that does not contain a .(dot) or end in a / is permanently redirected to the / version to avoid any content duplication.
RewriteCond %{REQUEST_URI} !(\.¦/$)
RewriteRule ^(.*) http://yourdomain.com/$1/ [R=301,L]

2nd Rewrite everything up to the first / that is not a true directory, does not contain a .(dot) and ends in a / to the php script. (Can be adjusted to fit your needs if you are using the script for deeper locations EG /variable/variable2/)
RewriteCond %{REQUEST_URI} !-d
RewriteRule ^([^/.]+)/$ /~testdir/result.php5?domain=$1 [L]

/~testdir/ appears to be where the script is located -- remove or adjust if necessary.

For live use the right side of the second rule should be the full server relative (not http://yoursite.com -- canonical) path to the php script, or you will receive the same 404 error. EG If you script is in /myscripts/ you will need to make the right side of the rule /myscripts/result.php5?domain=$1

You may need to use the full canonical path for testing purposes though:
RewriteCond %{REQUEST_URI} !-d
RewriteRule ^([^/.]+)/$ http://localhost:81/~testdir/result.php5?domain=$1 [P,L]

Let us know how this goes...

Justin

BTW The ¦ should not be a broken bar -- changed by the forum software, so you will need to adjust any copy/paste to avoid an error.

ZachH

8:45 pm on Sep 18, 2005 (gmt 0)

10+ Year Member



Hi Justin

I'm a bit insecure about how to do these changes, could you do me a big favor and let me know what lines to change.

Thanks,

-Zach

jd01

8:55 pm on Sep 18, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Change the directory rewrite section of your .htaccess, this:

# Directory rewrite
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^([^/]+) /$/$1/ [R]
RewriteRule ^([^/]+) /$result.php5?domain=$1 [L]

to this:

RewriteCond %{REQUEST_URI}!(\.¦/$)
RewriteRule ^(.*) http://localhost:81/$1/ [R=301,L]

RewriteCond %{REQUEST_URI}!-d
RewriteRule ^([^/.]+)/$ /~testdir/result.php5?domain=$1 [L]

Justin

ZachH

9:03 pm on Sep 18, 2005 (gmt 0)

10+ Year Member



Very strange things happen. When I go into a "directory" it jumps back to the root. Pretty weird.

Any suggestions?

ZachH

9:06 pm on Sep 18, 2005 (gmt 0)

10+ Year Member



I also had a look at the log files to see what actually happens. It looks like it goes into a cycle where it keeps on adding slashes(/).

So it goes like this in my log:
www.mydomain.com/variable/
www.mydomain.com/variable//
www.mydomain.com/variable///
www.mydomain.com/variable////
www.mydomain.com/variable/////
www.mydomain.com/variable//////

And it keeps on going like that.

jd01

9:44 pm on Sep 18, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



If you deleted your original rules, I don't see how it's looping, maybe jdMorgan will see something I am missing, but the only way I can see the loop is if this:

RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^([^/]+) /$/$1/ [R]
RewriteRule ^([^/]+) /$result.php5?domain=$1 [L]

is still present in the file.

Sorry.

Justin

Maybe you should try it on another server instead of your local machine?

ZachH

10:12 pm on Sep 18, 2005 (gmt 0)

10+ Year Member



Did another test just to make sure that nothing was left of the old code. Still the same problem.

I don't run it on my local machine. It is live online on a Linux machine.

-Zach

jdMorgan

3:39 am on Sep 19, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



A review of all issues discussed in this thread would be in order. The code has now changed such that the trailing-slash-directory-exists test and recursion prevention added earlier have been removed.

Jim

ZachH

8:01 pm on Sep 19, 2005 (gmt 0)

10+ Year Member



Hi jdMorgan

I don't think I understand your last post.

Regards,

-Zach