1

I am trying to write a simple rewrite rule that will change:

https://example.com/index.php?shortened_url=value

to

https://example.com/value

To acheive this, I am using the following rewrite rule:

RewriteEngine On
RewriteRule ^([^/]*)$ /index.php?shortened_url=$1 [L]

But I receive the error:

Request exceeded the limit of 10 internal redirects due to probable configuration error.

Clearly this suggests there is a looping issue somewhere but as far as I can tell my rule is quite straight forward and shouldn't cause any looping?

2
1

First of all you misplaced the arguments for the RewriteRule command, the order is

RewriteRule WHAT WHERE [OPTIONS] (shortcut to simplify things - refer to the documentation)

There's more about RewriteRule here http://httpd.apache.org/docs/current/mod/mod_rewrite.html

And what your rule actually does is rewriting any number of slashes / to the /index.php?shortened_url=$1 if I'm not mistaken.

So your https://example.com/ is redirected to the long URL as well as https://example.com/////////

You need to brush up with your regexp skills - try this link to help you https://regexr.com/

And finally the rule that you are looking for should be something like :

RewriteRule ^/index.php\?shortened_url=(.*)$ https://example.com/$1 [L]

4
  • Isn't it RewriteRule PATTERN SUBSTITUTION [FLAGS] ? – Syn Oct 4 '17 at 13:13
  • I just wanted to make a simple explanation, yours is more technical, however still, the order You have used initially is totally reversed – bocian85 Oct 4 '17 at 13:19
  • "rewriting any number of slashes /" - That's not what the ([^/]*) regex says. [^/] is a negated character class, so it matches anything except a slash, 0 or more times. So, it effectively matches the first path segment. You also can't use the RewriteRule pattern to match the query string. In order to match the query string, you must use a RewriteCond directive and check against the QUERY_STRING server variable. – MrWhite Oct 4 '17 at 13:34
  • Yes, correct, I guess I need to brush up on my regex instead – bocian85 Oct 4 '17 at 13:44
1
RewriteRule ^([^/]*)$ /index.php?shortened_url=$1 [L]

This will result in a rewrite loop because /index.php?shortened_url=value will get further rewritten to /index.php?shortened_url=index.php (again and again).

One way to prevent this rewrite loop is to only rewrite when there is no query string (providing you aren't using the query string for other purposes on this URL). For example:

RewriteCond %{QUERY_STRING) ^$
RewriteRule ^([^/]*)$ /index.php?shortened_url=$1 [L]

Or, exclude dots from the RewriteRule pattern. For example:

RewriteRule ^([^/.]*)$ /index.php?shortened_url=$1 [L]

The important thing to note here is that the L (last) flag does not stop all processing when used in per-directory .htaccess files. It simply stops the current round of processing. The rewriting process effectively starts over until the URL passes through unchanged. You need to prevent the rewritten URL from being further rewritten.

that will change:

https://example.com/index.php?shortened_url=value

to

https://example.com/value

bocian85 certainly has a point regarding your description, as your code is doing the complete opposite. Your code rewrites https://example.com/value to https://example.com/index.php?shortened_url=value. (Presumably you have already changed the URLs in your application to be of the form https://example.com/value?)

However, the code looks like it's doing the correct thing, so I think it's just your description that is back to front. (?) (Curious... people often describe this as you have done - in the reverse order - as if they are describing the net result in the application, rather than what the directive actually does.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.