views:

515

answers:

1
RewriteEngine on
RewriteRule ^page/?$ page.php [L]

This ends up matching the url www.site.com/page// but internally it acts differently than www.site.com/page/ because the stylesheets and images no longer appear properly. Am I doing something wrong or is this just something I need to deal with if I don't want to go through a lot of trouble?

To me it looks like it should only match www.site.com/page or www.site.com/page/

+4  A: 

Apache strips the empty path segment. So /path// is treated as /path/. But your browser doesn’t so relative URLs are resolved using /path//.

If you want to remove the multiple slashes, you can use the following rule:

RewriteCond %{THE_REQUEST} ^[A-Z]+\ /(([^/\ ]+/)*)/+([^\ ]*)
RewriteRule ^ /%1%3 [L,R=301]


Explaination

Despite Apache removes empty path segments internal, the THE_REQUEST environment variable (holding the HTTP request line) stays untouched. So we can use this value to check for multiple slashes.

  • ^[A-Z]+\ / matches the request method, the following space and the first slash character of the URI path.
  • (([^/\ ]+/)*) matches all following non-empty path segments (foo/, foo/bar/, foo/bar/baz/, etc.) or nothing, if there are none.
  • /+ matches the empty path segments as the character before this slash is always another slash (see the expressions before).
  • ([^\ ]*) matches the rest of the URI (that may contain further empty path segments).

Example: Let’s say we request http://example.com/foo/bar//baz, the request line will look like this:

GET /foo/bar//baz HTTP/1.1

The pattern would then match as follows:

0: GET /foo/bar//baz
1: foo/bar/
2: bar/
3: baz

So the requested path /foo/bar//baz would be redirected to /foo/bar/baz (/%1%3).

Gumbo
Brilliant. Can you possibly explain a little bit what each of those lines do?
Joe Philllips