Forum Moderators: phranque

Message Too Old, No Replies

Mod rewrite Static Urls

         

jinxed

6:15 pm on Nov 4, 2009 (gmt 0)

10+ Year Member



Hi Everyone

I am having lots of troubles getting my .htaccess file to work with creating static urls.

I am trying to achieve the following file structure:

http://www.example.com/directory1/directory2/shot/2/

instead of:

http://www.example.com/directory1/directory2/shot_detail.php?shot_id=2

Here is my .htaccess code that I am trying to use (.htaccess file is located in the directory2 folder):

RewriteEngine On
RewriteRule ^shot/([^/]+)/$ /shot_detail.php?shot_id=$1 [L]

This gets a 404 error.

Having the "Options +FollowSymLinks" statement causes an 500 Internal Server Error.

I know very little about .htaccess coding (!) - could anyone offer any suggestions?

TheMadScientist

9:45 pm on Nov 4, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The best place to start is in the library...

There's a link under the bread crumbs, and this post addresses what you are trying to do specifically: Changing Dynamic URLs to Static [webmasterworld.com]

jdMorgan

12:36 am on Nov 5, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



> (.htaccess file is located in the directory2 folder)

You will need to add the full path to the script, even though/because this code is located in /directory2:


RewriteRule ^shot/([^/]+)/$ /directory1/directory2/shot_detail.php?shot_id=$1 [L]

Jim

jinxed

6:54 pm on Nov 5, 2009 (gmt 0)

10+ Year Member



jdMorgan - Thank you so much. The code now works just as I require it to. Your help is greatly appreciated.

jinxed

6:44 pm on Nov 8, 2009 (gmt 0)

10+ Year Member



Jim,

I am trying to get the 301 redirect code to work for this same folder (again without luck).

Here is the code I am attempting:

RewriteEngine on
RewriteRule ^shot/([^/]+)/$ /directory1/directory2/shot_detail.php?shot_id=$1 [L]

RewriteCond %{THE_REQUEST} ^[0-9]+\ /shot_detail.php?shot_id=([^&\ ]+)\ HTTP/
RewriteRule ^shot_detail.php /directory1/directory2/shot/%1/? [R=301,L]

Can you see any obvious faults in this?

Thank you in advance.

jdMorgan

9:54 pm on Nov 8, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



THE_REQUEST it the HTTP requests line, exactly as received from the client, and exactly as logged in your raw server access log file. The pattern for THE_REQUEST needs to match "GET", "HEAD", "POST", etc., a space, plus the full URL-path as requested by the client; only the URL-path examined by RewriteRule pattern is 'localised' to the current .htacess file's directory. Also, the literal question mark must be escaped in your pattern, unless it is to be taken as a regex "match zero or one" quantifier.

As the current pattern only matches numbers for the HTTP request method and does not match any of the directory path, it won't likely work. Taking a guess, I'd say try:

 RewriteCond %{THE_REQUEST} ^[A-Z]+\ /directory1/directory2/shot_detail\.php\?shot_id=([^&\ ]+)\ HTTP/

Jim

[edited by: jdMorgan at 11:03 pm (utc) on Nov. 8, 2009]

jinxed

10:57 pm on Nov 8, 2009 (gmt 0)

10+ Year Member



Jim,

Thank you for your code and explanation. Unfortunetely this still isnt having the desired effect.

I appreciate the time you have taken to have a look at this.

TheMadScientist

2:20 am on Nov 9, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I think the redirect is an infinite, external loop using the rule and condition together... It seems the .php URL should be redirected for an original (UA direct) request, and re-written to, for /shot/ requests.

RewriteEngine on
RewriteRule ^shot/([^/]+)/$ /directory1/directory2/shot_detail.php?shot_id=$1 [L]

RewriteCond %{THE_REQUEST} ^[0-9]+\ /directory1/directory2/shot_detail\.php\?shot_id=([^&\ ]+)\ HTTP/
RewriteRule ^directory1/directory2/shot_detail\.php$ http://www.example.com/shot/%1/? [R=301,L]

# OR

RewriteRule ^shot/([^/]+)/$ /shot_detail.php?shot_id=$1 [L]

RewriteCond %{THE_REQUEST} ^[0-9]+\ /shot_detail\.php\?shot_id=([^&\ ]+)\ HTTP/
RewriteRule ^shot_detail\.php$ http://www.example.com/shot/%1/? [R=301,L]

# Only one of the preceding should be correct and the left side of the first rule should be the rewrite for the right side of the 2nd rule. So, if the 'visited URL' people are supposed to see is: http://www.example.com/directory1/directory2/shot/%1/ the preceding should be the right side of the second rule with a trailing ? and the left side of the first rule should be: ^directory1/directory2/shot/([^/]+)/$

jdMorgan

2:32 pm on Nov 9, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Again, the RewriteCond pattern for THE_REQUEST won't ever match if it starts out with "^[0-9]+\ /" because 'real' client requests always start with an HTTP method (e.g. GET, HEAD, or POST) as an all-uppercase character string -- Please review my post above.

Jim

jinxed

6:29 pm on Nov 9, 2009 (gmt 0)

10+ Year Member



I have re-read and I am convinced this RewriteCond code is correct:

RewriteCond %{THE_REQUEST} ^[A-Z]+\ /directory-1/directory-2/shot_detail\.php\?shot_id=([^&\ ]+)\ HTTP/

But, as it is still not working - I believe my corresponding RewriteRule code must be invalid.

TheMadScientist - Thank you for looking at this, I am studying your advice/code further.

jdMorgan

6:51 pm on Nov 9, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Just to be sure we're all on the same page, your code should look exactly like this (or very close).

In /directory-1/directory-2/.htaccess :


# Externally redirect (only) direct client requests for internal filepath back to canonical URL
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /directory-1/directory-2/shot_detail\.php\?shot_id=([^&\ ]+)\ HTTP/
RewriteRule ^shot_detail\.php http://www.example.com/directory-1/directory-2/shot/%1/? [R=301,L]
#
# Internally rewrite canonical URL requests to script filepath with query string
RewriteRule ^shot/([^/]+)/$ /directory-1/directory-2/shot_detail.php?shot_id=$1 [L]

Make sure you're completely flushing (deleting) your browser cache after any change to your server-side code.

These two rules, in the context of /directory-1/directory-2/.htaccess are now mirror images of each other, with the qualification that the first rule is only invoked by direct client requests -- as is required to prevent an 'infinite' redirect/rewrite loop. But if you still have a problem, please try to be *very* descriptive about it: "It doesn't work" tells us almost nothing in addition to the fact that you likely wouldn't be posting if it did work.

Please be specific about what URL you tested, what you expected to happen, what actually happened, and how those differ. Any other info, such as relevant server access and error log entries, and HTTP header traces --when useful-- can/should be added.

In particular here, we need to know if both rules now fail, or only one.

Jim

jinxed

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

10+ Year Member



From double checking the access log once again, I have noticed that the GET request has HTTP/1.1 instead of HTTP/

i.e.

"GET /directory1/directory2/shot_detail.php?shot_id=2 HTTP/1.1"

Does this mean that HTTP/ would need to be substituted with HTTP/1\.1& ?

jinxed

7:11 pm on Nov 9, 2009 (gmt 0)

10+ Year Member



I posted my last post before reading your latest.

Yes, the code being used in In /directory-1/directory-2/.htaccess is exactly the same as your previous code. In the same order.

The request in the access log is exactly as pasted in my previous post.

The URL I am typing into the browser (after clearing the cache) is:

http://www.example.co.uk/directory-1/director-2/shot_detail.php?shot_id=1

Thank you

TheMadScientist

10:19 pm on Nov 9, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



These are not the same directory1 and directory-1 are different.

"GET /directory1/directory2/shot_detail.php?shot_id=2 HTTP/1.1"

http://www.example.co.uk/directory-1/director-2/shot_detail.php?shot_id=1

Sorry about not noticing the 0-9 rather than A-Z in the match for THE_REQUEST... Lil copy / paste error.

Does this mean that HTTP/ would need to be substituted with HTTP/1\.1& ? No, the posted condition will 'implicitly' match /1.1 or /1.0 since it's not 'end anchored'.

jinxed

10:22 pm on Nov 9, 2009 (gmt 0)

10+ Year Member



Sorry, my fault - yes I realise directory-1/directory1 need to be the same, I just typed them differently on here when giving the examples. I should have kept the example folder names consistent.

jdMorgan

10:26 pm on Nov 9, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



"GET /directory1/directory2/shot_detail.php?shot_id=2 HTTP/1.1"

Does this mean that HTTP/ would need to be substituted with HTTP/1\.1& ?

No, because the RewriteCond pattern is not end-anchored. Therefore, after "HTTP/", *anything* will match.

Jim

jdMorgan

10:34 pm on Nov 9, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Time to ask... Do you use MultiViews/content-negotiation? Is it enabled?

If it's enabled but you don't use it, try adding


Options -MultiViews

ahead of the "RewriteEngine on" line.

Assuming you've made no transcription errors in URL-path patterns, the code is fine. You'll need to be looking for other rules in higher-level .htaccess and config files and/or other directives that rewrite URLs -- mod_alias, mod_proxy, mod_dir, mod_negotiation, etc. *Something* is grabbing that URL before your code in /directory-1/directory-2/.htaccess gets a chance to act on it.

Jim

jinxed

11:02 pm on Nov 9, 2009 (gmt 0)

10+ Year Member



Jim

Adding Options -MultiViews unfortunately causes a 500 Internal Server Error.

I have already been in contact with my hosting provider and asked them if there are 'any restrictions' that would mean the code in the .htaccess would not function, and their answer has always been no.

I am not sure where to go next with this.

jdMorgan

11:49 pm on Nov 9, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



What's in your server error log when you get the 500-Server Error? What else can you tell us, as previously requested?

This code is quite trivial and very common, and I'm suspicious of your server set-up if the code has been correctly-adapted to your real URLs and still doesn't work.

Jim

jinxed

7:35 pm on Nov 10, 2009 (gmt 0)

10+ Year Member



Jim

I have contacted my hosting provider for details of how to gain access to the server error logs. I will post an update when I have more information.

Thanks

jinxed

5:31 pm on Nov 13, 2009 (gmt 0)

10+ Year Member



[Thu Nov 12 19:04:38 2009] [alert] [client xx.#*$!.#*$!.#*$!] /home/user20311/website/directory1/directory2/.htaccess: Option multiviews not allowed here, referer: [website.co.uk...]

This is the error message in the error log when Options multiviews is inserted.

I am thinking this must be an server configuration issue that is stopping this code from working.

I will be contacting my hosting company AGAIN to request more information on this.

My hosting does not allow me to view my own error logs, I have had to request them. I am now considering moving hosts.

jdMorgan

6:32 pm on Nov 13, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Note that that should read "Options -MultiViews" - The "minus sign" is critical.

You may get the same error anyway if "AllowOverride Options" isn't set in your server config, but I thought I'd better point that out anyway, just in case...

Jim