#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2012
    Posts
    3
    Rep Power
    0

    Complicated rewrite rule help


    I have a rather complicated request. I managed to get most of it with help from the mod_rewrite faq thread, but now I have an even more complicated desire so I'm pretty stuck.

    This is my current rewrite configuration:
    Code:
    RewriteEngine On
    
    RewriteCond %{QUERY_STRING} ^$
    RewriteRule ^(res/.+)$ $1 [QSA,L]
    
    RewriteCond %{QUERY_STRING} ^$
    RewriteRule ^([^/\.\?&=]+)([=&]{0,1}[^/]*)/{0,1}?$ router.php?$1
    
    RewriteCond %{QUERY_STRING} ^$
    RewriteRule ^(.+)/([^/=&]+)(/{0}[=&]{0,1}[^/]*)$ $1?$2 [QSA,E=TEST:$1]
    
    RewriteCond %{ENV:TEST} ^(.+)/([^/=&]+)(/{0}[=&]{0,1}[^/]*)$
    RewriteRule ^.*$ %1?%2 [QSA,E=TEST:%1,N]
    
    RewriteCond %{ENV:TEST} ^([^/=&]+)(/{0}[=&]{0,1}[^/]*)/(.+)$ [OR]
    RewriteCond %{REQUEST_URI} ^/([^/=&]+)/(.+)$
    RewriteRule ^.*$ router.php?%1=%3 [QSA,L]
    Basically, this is what it accomplishes:
    • /hello internally becomes /router.php?hello
    • /foo/bar/.../... and so on is /router.php?foo&bar&...
    • /res/ and anything in the /res directory are not rewritten

    And just a note, the regex in there like this "[^/=&]+" is there to prevent someone entering a url like /foo&abc/bar or /foo=hello/bar.

    However, now I also want it to be able to handle GET requests which currently don't work correctly. There's something wrong with this part:
    Code:
    RewriteCond %{QUERY_STRING} ^$ 
    RewriteRule ^([^/\.\?&=]+)([=&]{0,1}[^/]*)/{0,1}?$ router.php?$1
    The problem here is that the GET part causes the regex match to fail, so any single level request fails to be rewritten. ("/foo?stuff" or "/bar/?stuff"). I keep trying different regex patterns, but none fix it.

    Then with the rest, the get request is recognized, but the last part of the normal url gets ignored. So, "/foo/bar/abc?test=true" results in "router.php?foo&bar&test=true"

    I figure most of this is just a matter of fixing errors with my regex, but any help would be greatly appreciated.
  2. #2
  3. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2012
    Posts
    3
    Rep Power
    0
    Okay, I've decided to do a similar approach, however, it's still not working for me.

    This is what I'm trying now:
    Code:
    RewriteEngine On
    
    RewriteCond %{QUERY_STRING} ^$
    RewriteRule ^(res/.+)$ $1 [QSA,L]
    
    RewriteCond %{QUERY_STRING} ^$
    RewriteRule ^((?:[/a-zA-Z0-9-_])+)(?:[^?]*?)?(?:$|\?(.*)?$) router.php?path=$1&$2
    This should turn something like "/foo/bar?test=true" to "router.php?path=foo/bar&test=true. My regex tests show that the expression is correct and matches what I want it to, but for some reason it's not working once it's applied to the server rules.

    "/foo/bar" and "/foo/bar?" correctly rewrite, but as soon as I add anything past the question mark the rewrite fails and I just get a 404 error for "/foo/bar" was not found. Anyone have any idea why this is happening, or some sort of debugging tool that could help me figure out why it's not matching correctly?
  4. #3
  5. Transforming Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,119
    Rep Power
    9398
    RewriteRule does not look at the query string. Only the path component. Add in your Cond that says the query string has to be empty and naturally you'll end up with a 404.

    If you want to copy the query string to the new URL then all you need is the [QSA] flag. Like
    Code:
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule .* router.php?path=$0 [L,QSA]
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2012
    Posts
    3
    Rep Power
    0
    Originally Posted by requinix
    RewriteRule does not look at the query string. Only the path component. Add in your Cond that says the query string has to be empty and naturally you'll end up with a 404.

    If you want to copy the query string to the new URL then all you need is the [QSA] flag. Like
    Code:
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule .* router.php?path=$0 [L,QSA]
    Awesome, it works! Thanks so much!

IMN logo majestic logo threadwatch logo seochat tools logo