1

I'm edditing my htaccess to internally redirects just about any URL to a php page handler:

RewriteRule ^images\/ - [L,NS]
RewriteRule ^docs\/ - [L,NS]
RewriteRule ^([A-Za-z0-9\_\-]+)\/?$ pages/pagehandler.php?page=$1 [L,QSA,NS]

this works fine accept that directories that are enteres in the address bar with no trailing slash for some reason get duplicate query strings, and for some reason the address bar of the browser changes for example, if I type the URL:

localhost/movies

if there's a directory called movies in the site root than the address changes to:

localhost/movies/?page=movies

I guess this is some collision with mod_dir but I don't know how to overcome it, if I use:

<IfModule mod_dir.c>
   DirectorySlash Off
</IfModule>

Than it works, but I don't want this, I think for some reason the url is rewritten than mod dir changes it and than it is rewritten again thus making duplicate query strings,

Any Ideas?

EDIT: I Add a relevant part of the Rewritelog, this is all from one request:

strip per-dir prefix: /opt/lampp/htdocs/movies -> movies
applying pattern '^images\/' to uri 'movies'
strip per-dir prefix: /opt/lampp/htdocs/movies -> movies
applying pattern '^docs\/' to uri 'movies'
strip per-dir prefix: /opt/lampp/htdocs/movies -> movies
applying pattern '^pages\/' to uri 'movies'
strip per-dir prefix: /opt/lampp/htdocs/movies -> movies
applying pattern '^([A-Za-z0-9\_\-]+)\/?$' to uri 'movies'
rewrite 'movies' -> 'pages/pagehandler.php?page=movies'
split uri=pages/pagehandler.php?page=movies -> uri=pages/pagehandler.php, args=page=movies
add per-dir prefix: pages/pagehandler.php -> /opt/lampp/htdocs/pages/pagehandler.php
trying to replace prefix /opt/lampp/htdocs/ with /
strip matching prefix: /opt/lampp/htdocs/pages/pagehandler.php -> pages/pagehandler.php
add subst prefix: pages/pagehandler.php -> /pages/pagehandler.php
internal redirect with /pages/pagehandler.php [INTERNAL REDIRECT]
strip per-dir prefix: /opt/lampp/htdocs/movies/ -> movies/
applying pattern '^images\/' to uri 'movies/'
strip per-dir prefix: /opt/lampp/htdocs/movies/ -> movies/
applying pattern '^docs\/' to uri 'movies/'
strip per-dir prefix: /opt/lampp/htdocs/movies/ -> movies/
applying pattern '^pages\/' to uri 'movies/'
strip per-dir prefix: /opt/lampp/htdocs/movies/ -> movies/
applying pattern '^([A-Za-z0-9\_\-]+)\/?$' to uri 'movies/'
rewrite 'movies/' -> 'pages/pagehandler.php?page=movies'
split uri=pages/pagehandler.php?page=movies -> uri=pages/pagehandler.php, args=page=movies&page=movies
add per-dir prefix: pages/pagehandler.php -> /opt/lampp/htdocs/pages/pagehandler.php
trying to replace prefix /opt/lampp/htdocs/ with /
strip matching prefix: /opt/lampp/htdocs/pages/pagehandler.php -> pages/pagehandler.php
add subst prefix: pages/pagehandler.php -> /pages/pagehandler.php
internal redirect with /pages/pagehandler.php [INTERNAL REDIRECT]

Also the relevant part from the access log:

"GET /movies HTTP/1.1" 301
"GET /movies/?page=movies HTTP/1.1" 200
fiftyeight
  • 393
  • 2
  • 15

3 Answers3

1

Can you change your rewrite rule to:

RewriteRule ^([A-Za-z0-9\_\-]+)/?$ /pages/pagehandler.php?page=$1 [L,QSA,NS]

Note the / before pages.

anubhava
  • 761,203
  • 64
  • 569
  • 643
  • Thanks for the effort, I added the relevant parts of the access_log and the Rewrite_log, there's nothing about this in the error_log. all the lines from the rewrite_log I've added are subsequent I didn't remove anything between lines. It seems like mod_rewrite rewrites the URL, than mod_dir redirects with the query string and than mod_rewrite adds the query string again, I guess I can add a rewrite condition that checks if the URL is a directory and doesn't add with a trailing slash and if so it won't add the query string, question is if there's a solution at the configuration level? – fiftyeight Jul 04 '11 at 22:43
1

For anyone having this problem, what I did ultimately in disable the Directory Slash:

<IfModule mod_dir.c>
   DirectorySlash Off
</IfModule>

And I used a RewriteRule to 301 Redirect all directory requests than do not end with a /

I guess this is some sort of collision between mod_rewrite and mod_dir as I primarily thought

fiftyeight
  • 393
  • 2
  • 15
0

And I used a RewriteRule to 301 Redirect all directory requests than do not end with a /

I had a similar problem but could not find a solution over mod_rewrite (did not know how to add this slash with a 301 redirect - tried everything).

What I did is to define:

<IfModule mod_dir.c>
   DirectorySlash Off
</IfModule>
ErrorDocument 404 404.php

If now the trailing slash is missed, 404.php is used redirecting the client if the url has no trailing slash now:

<?php 
$home="http://".$_SERVER['HTTP_HOST'];
$url=$home.$_SERVER['REQUEST_URI']; 
?><html>
<head>
<title><?php echo $_SERVER['REDIRECT_STATUS']; ?></title>
<?php if(!preg_match('/^.+\/$/', $url)) { ?>
<meta http-equiv="refresh" content="0; URL=<?php echo $url; ?>/">
<? } ?>
</head>
<body>
<h1><?php echo $_SERVER['REDIRECT_STATUS']; ?></h1>
</body>
</html>

It smells like hell but worksforme ...

user470370
  • 572
  • 1
  • 5
  • 17