Calvin
Calvin

Reputation: 309

How to fix mod_rewrite regex from producing 500 and 404 errors

I have the following line in my .htaccess

RewriteRule ^folder/(.*)$ /folder/?value=$1 [L]

This always gives me a 500 internal error when I have anything at http://website.com/folder/value.

If I simply change it to

RewriteRule ^folder/(.*)\.html$ /folder/?value=$1 [L]

It sends me properly to http://website.com/folder/value.html with value.html being set in the $_GET.

I want to be able to accept anything such as value, value.com, value-4, otheritem.

Any ideas on why my regex is 500 Internal Server Error'ing everytime?

Upvotes: 1

Views: 181

Answers (3)

Salman Arshad
Salman Arshad

Reputation: 272246

Here is what happens with this rule:

RewriteRule ^folder/(.*)$ /folder/?value=$1 [L]
  • The requested URL /folder/test matches the pattern and rewritten as /folder/?value=test
  • Rewriting stops because of [L] flag

However, since the path/filename changed (/folder/test became /folder/), mod_rewrite will perform another iteration:

  • The rewritten URL /folder/?value=test matches the pattern and rewritten as /folder/?value=
  • Repeat

As mentioned in other comments/answers, change * to + and it should solve the problem. If /folder/ exists and contains index.php then one extra line is needed:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^folder/(.+)$ /folder/?value=$1 [L]

What happens is that after re-writing, Apache serves the default document for the existing directory which fires another iteration of rewriting. The condition prevents mod_rewrite from changing /folder/index.php?value=test back to /folder/?value=index.php.

Upvotes: 1

Felipe Alameda A
Felipe Alameda A

Reputation: 11809

You may try this approach that treats both /folder and value (The value of key "value") as dynamic strings, regardless of their format.

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI}  .*/([^/]+)/([^/]+)/?   [NC]
RewriteRule .*       %1/?value=%2      [L]

It maps internally a URL like this one:

http://website.com/anyfolder/anyvalue or

http://website.com/any/number/of/folders/anyfolder/anyvalue

To:

http://website.com/anyfolder/?value=anyvalue

Of course /anyfolder must exist in the mapped URL, otherwise there will be a 404 error.

This rule-set was tested in a real server without problems.

Upvotes: 1

Jon Lin
Jon Lin

Reputation: 143906

You're probably getting 500 errors, because your rules are looping. The target of your rule matches the pattern itself (/folder/?value=value matches ^folder/(.*)$ because the query string is stripped before matching). Try including conditions to apply to the rule, something like:

RewriteCond %{REQUEST_FILENAME !-f
RewriteCond %{REQUEST_FILENAME !-d
RewriteRule ^folder/(.*)$ /folder/?value=$1 [L]

Or:

RewriteCond %{REQUEST_URI} !^/folder/?$
RewriteRule ^folder/(.*)$ /folder/?value=$1 [L]

But technically what @Suku suggested should work:

RewriteRule ^folder/(.+)$ /folder/?value=$1 [L]

In my test apache instance, all of the above works while RewriteRule ^folder/(.*)$ /folder/?value=$1 [L] loops (and returns a 500).

Upvotes: 2

Related Questions