Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does RewriteRule . work the same as ^(.*)$?

Consider the following:

RewriteRule ^(.*)$ index.php/$1

Based on the fledgling noob knowledge I have of mod_rewrite, this should match the entire URL part between example.com/ and ?query=string, and then prepend it with index.php/, and generally, that's exactly what happens.

http://example.com/some/stuff -> http://example.com/index.php/some/stuff

Now, consider:

RewriteRule . index.php

According to the developers of the current update to the Concrete5 CMS, this does the exact same thing. And indeed, it appears to do just that on my server as well.

My question is, why does the second RewriteRule yeild the same result instead of something like

http://example.com/some/stuff -> http://example.com/index.phpome/stuff

Shouldn't the . match one character and then be replaced with the index.php string? This is on Apache 2.2.

like image 200
NReilingh Avatar asked Sep 30 '12 01:09

NReilingh


People also ask

What is RewriteRule * F?

F|forbidden The following rule will forbid .exe files from being downloaded from your server. RewriteRule "\.exe" "-" [F] This example uses the "-" syntax for the rewrite target, which means that the requested URI is not modified. There's no reason to rewrite to another URI, if you're going to forbid the request.

What is RewriteCond and RewriteRule?

There are two main directive of this module: RewriteCond & RewriteRule . RewriteRule is used to rewrite the url as the name signifies if all the conditions defined in RewriteCond are matching. One or more RewriteCond can precede a RewriteRule directive.

What does Mod rewrite do?

mod_rewrite provides a flexible and powerful way to manipulate URLs using an unlimited number of rules. Each rule can have an unlimited number of attached rule conditions, to allow you to rewrite URL based on server variables, environment variables, HTTP headers, or time stamps.

What is $1 Apache?

$1 represents the match from the first set of parentheses in the RewriteRule regex, not in the RewriteCond regex.


1 Answers

RewriteRule ^(.*)$ index.php/$1 will match and use the captured text to create a new path with whatever was originally requested added to the end where the $1 is.

RewriteRule . index.php matches because it is an unanchored regex. The previous regex uses ^ and $ to anchor the match which means that the pattern must match entirely while this one does not which means that it will match anywhere in the string, so any string with any character will match. Because mod_rewrite treats each test as a running predicate, this rule will be applied as long as it matches.

When the rule is matched the substitution takes place. The substitution is a complete substitution, so if you don't use backreferences like $1 then whatever was in the original pattern is lost. In this case the new path just becomes index.php.

There is therefore a slight difference between the 2, in that the second just goes directly to index.php without adding the originally requested path on to the end. Most likely Concrete5 CMS is using a front controller which dispatches according to information it pulls from the request directly. Since this isn't a redirect rewrite, the original request will be perserved so that is just used instead: shifting some responsibility from Apache and into the hands of the application code, pursuing less dependence on the hosting environment.

like image 200
Matt Whipple Avatar answered Sep 20 '22 17:09

Matt Whipple