Forum Moderators: phranque

Message Too Old, No Replies

htaccess rewritecond issue

         

phollaio

11:21 am on Mar 12, 2010 (gmt 0)

10+ Year Member



Hi guys,

I'm struggling trying to make an htaccess work.

GOALS:
  1. Any requests to the domain.com/ are mapped to /index.html > WORKS
  2. Any requests to domain.com/myform.php?c=VAR should be redirected to domain.com/VAR > DOESN'T WORK
  3. Any requests to domain.com/VAR should replace + or ' or <spaces> characters in VAR, and send the actual request to domain.com/myform.php?c= (transparently, so that the user still see domain.com/VAR on the browser URL) > WORKS


This is my .htaccess file:

Options +FollowSymlinks
RewriteEngine on

# Sends requests to domain.com/ to domain.com/index.html
RewriteRule ^$ /index.html [N]

# If the request comes from /myform.php, then remap the value of the C parameter to the domain root
# e.g.: domain.com/myform.php?c=VAR to domain.com/VAR
# The RewriteRule below, if uncommented, causes an Internal Server Error
RewriteCond %{REQUEST_URI} /myform.php$
RewriteCond %{QUERY_STRING} c=(.*)
#RewriteRule ^weather\.php$ /%1

# Replace + and ' with hyphens
# e.g.: domain.com/FOO+BAR to domain.com/FOO-BAR
RewriteRule ^([^+]*)\+(.*) $1-$2 [N]
RewriteRule ^([^+]*)\'(.*) $1-$2 [N]

# Replace spaces with hyphens
# e.g.: domain.com/FOO BAR to domain.com/FOO-BAR
RewriteRule ^([^\ ]*)\ (.*)$ $1-$2 [E=rspace:yes,N]

# Redirect to update URL in search engine listings and browsers
# e.g.: My URL becomes domain.com/A-VAR
RewriteCond %{ENV:rspace} yes
RewriteRule (.*) /$1 [R=301,L]

# Send the actual request (unless the name includes a . or a /)
RewriteRule ^([^/.]*)/?$ /myform.php?c=$1

Any suggestion to achieve goal #2 greatly appreciated :)

Thanks,

Ale

phollaio

11:22 am on Mar 12, 2010 (gmt 0)

10+ Year Member



My bad, line 9 of the .htaccess file should read
#RewriteRule ^myform\.php$ /%1

phollaio

2:57 pm on Mar 12, 2010 (gmt 0)

10+ Year Member



Managed to get somewhere with this:


Options +FollowSymlinks
RewriteEngine on

# Sends requests to domain.com/ to domain.com/index.html

RewriteRule ^$ /index.html [N]

# If the request comes from /myform.php, then remap the value of the C parameter to the domain root
# e.g.: domain.com/myform.php?c=VAR to domain.com/VAR

RewriteCond %{REQUEST_URI} /myform.php$
RewriteCond %{QUERY_STRING} ^c=(.+)
RewriteRule ^myform\.php$ /%1? [R=301,L]

# Replace + and ' with hyphens
# e.g.: domain.com/FOO+BAR to domain.com/FOO-BAR

RewriteRule ^([^+]*)\+(.*) $1-$2 [N]
RewriteRule ^([^+]*)\'(.*) $1-$2 [N]

# Replace spaces with hyphens
# e.g.: domain.com/FOO BAR to domain.com/FOO-BAR

RewriteRule ^([^\ ]*)\ (.*)$ $1-$2 [E=rspace:yes,N]

# Redirect to update URL in search engine listings and browsers
# e.g.: My URL becomes domain.com/A-VAR

RewriteCond %{ENV:rspace} yes
RewriteRule (.*) /$1 [R=301,L]

# Send the actual request (unless the name includes a . or a /)

RewriteRule ^([^/.]*)/?$ /myform.php?p=&c=$1


I'm left with 2 issues/questions:
  1. Notice the last RewriteRule: I had to add a "p=" parameter to make the request work, why I don't know..
  2. Also, noticed that now the following lines are not working anymore:

    RewriteRule ^([^+]*)\+(.*) $1-$2 [N]
    RewriteRule ^([^+]*)\'(.*) $1-$2 [N]


Thanks,

A

phollaio

3:10 pm on Mar 12, 2010 (gmt 0)

10+ Year Member



Managed to make it work, although I'm still unsure why I need the extra p= in the last RewriteRule..


Options +FollowSymlinks
RewriteEngine on

# Sends requests to domain.com/ to domain.com/index.html
RewriteRule ^$ /index.html [N]

# If the request comes from /myform.php, then remap the value of the C parameter to the domain root
# e.g.: domain.com/myform.php?c=VAR to domain.com/VAR
RewriteCond %{REQUEST_URI} /myform.php$
RewriteCond %{QUERY_STRING} ^c=(.+)
RewriteRule ^myform\.php$ /%1? [R=301,L]

# Replace + and ' and <spaces> with hyphens
# e.g.: domain.com/FOO BAR+FOO'BAR to domain.com/FOO-BAR-FOO-BAR
RewriteRule ^([^+]*)\+(.*$) $1-$2 [E=rspace:yes,N]
RewriteRule ^([^+]*)\'(.*)$ $1-$2 [E=rspace:yes,N]
RewriteRule ^([^\ ]*)\ (.*)$ $1-$2 [E=rspace:yes,N]

# Redirect to update URL in search engine listings and browsers
RewriteCond %{ENV:rspace} yes
RewriteRule (.*) /$1 [R=301,L]

# Send the actual request (unless the name includes a . or a /)
# Still not sure why I need the extra p=
RewriteRule ^([^/.]*)/?$ /myform.php?p=&c=$1

# ErrorDocument 404 /404.html


A

jdMorgan

9:41 pm on Mar 14, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Getting rid of some redundancies, fixing the directive and rule order for both efficiency and correctness of operation, adding the protocol and domain to the redirects, and tweaking a few more things, I'd suggest:

# Declare custom 404 error page
# ErrorDocument 404 /404.html
#
# Map requests for URL domain.com/ to filepath /index.html
DirectoryIndex /index.html
#
Options +FollowSymlinks -MultiViews
RewriteEngine on
#
# Replace one "+", "'" or space with a hyphen and set "character replaced"
# flag, then restart mod_rewrite processing until all have been replaced
# e.g.: domain.com/FOO BAR+FOO'BAR to domain.com/FOO-BAR-FOO-BAR
RewriteRule ^([^+]*)[+'\ ](.*$) $1-$2 [E=rspace:yes,N]
#
# If the character replaced flag is set, redirect to update
# the URL in search engine listings and browsers
RewriteCond %{ENV:rspace} =yes
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
#
# If the request is for URL-path /myform.php, then redirect to root with the C
# parameter as a "filepath" e.g.: domain.com/myform.php?c=VAR to domain.com/VAR
RewriteCond %{QUERY_STRING} ^c=(.+)
RewriteRule ^myform\.php$ http://www.example.com/%1? [R=301,L]
#
# Internally rewrite the request to /myform.php (unless the name includes a . or a /)
# Still not sure why I need the extra p=
RewriteRule ^([^/.]*)/?$ /myform.php?p=&c=$1

Likely one of the most important changes is in the comments, which are now more accurate.

I can't answer your question about the "p=" parameter, except to say that either your script requires it, or it prevents the now-third rule from being re-invoked when you don't want it to be re-invoked. Since you did not indicate specifically what sort of trouble you had when "p=" was omitted, I cannot say.

Jim

phollaio

6:42 pm on Mar 15, 2010 (gmt 0)

10+ Year Member



Hi Jim,

Thank you for your detailed answer. Without the p= parameter I used to get "Internal Server Error", the issue seem to be solved now.

Your code is much cleaner, only thing is the:

<code>
DirectoryIndex /index.html
</code>

doesn't internally redirect to the index.html file, instead I get a 404 error. My script redirects you to a 404 if the value after the / is null, so it seems that line is not being evaluated.

Suggestions? :)

A

g1smd

6:51 pm on Mar 15, 2010 (gmt 0)

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



My script redirects you to a 404


When it is a 404 error, there should be no redirect of any sort whatsoever.

Use "Live HTTP Headers" to inspect the server responses. Make sure the 404 HTTP status code is directly returned for the originally requested URL. If there is any 3xx code present, you have additional problems to fix.