Friday, January 28, 2011

Apache URL Mod_Rewrite

Why does the following .htaccess file generate 300 errors, when this URL is called?

The website redirects to the correct php page, but 300 is returned 2 times

URL: hxxp://subdomain.domainame.com/keyword/

IndexIgnore *

RewriteEngine on
RewriteRule ^([a-z]+)/?$ /index.php?p=$1

Error log: (300)
File does not exist: /home/admin/public_html/subdomain/keyword (no trailing slash)


Additional Questions

Do I need to expand the rewrite rule to pick up the following in the URL:

/index.php?p=keyword 

The URL being called is /keyword/ . Is it returning 300 - Multiple choices status because the following are possible?

 /index.php?p=keyword
 /keyword
 /keyword/ 
  • try

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

    you need the L flag to stop rewriting once the rule has hit. (otherwise you get an endless loop)

    rrrfusco : I've tried out what you've suggested, but it continues to return 300. I also added a little to the question above.
  • I believe the problem is actually the lack of a forward slash at the beginning of your regular expression. Still, c10k Consulting's suggestion to use the "Last" flag is a great idea. Try this:

    RewriteRule ^/([a-z]+)/?$ /index.php?p=$1 [L]
    

    Depending upon the rest of your Apache configuration and url patterns, you may want to expand on your rewrite rules a bit, like so:

    RewriteEngine on
    RewriteRule %{REQUEST_URI} !.php
    RewriteRule ^/(\w+)/?$ /index.php?p=$1 [L]
    

    The first rule prevents rewriting of requests to PHP files, and the second uses the "word" regular expression token. Again, it requires the REQUEST_URI to start with a forward slash, followed by a word, which is then concluded, or followed by a forward slash, then concluded.

    Hope that helps! Good luck and be persistent with mod_rewrite. Its a reliable and thoughtfully crafted tool.

    rrrfusco : I've tried out what you've suggested, but it continues to return 300. I also added a little to the question above.
    From Docunext
  • This works for me on apache 2.2.16:

    RewriteRule ^([a-z]+)/?$ /index.php?p=$1 
    

    Here is the rewrite log:

    init rewrite engine with requested uri /keyword/
    pass through /keyword/
    [perdir /var/www/html/] add path info postfix: /var/www/html/keyword -> /var/www/html/keyword/
    [perdir /var/www/html/] strip per-dir prefix: /var/www/html/keyword/ -> keyword/
    [perdir /var/www/html/] applying pattern '^([a-z]+)/?$' to uri 'keyword/'
    [perdir /var/www/html/] rewrite 'keyword/' -> '/index.php?p=keyword'
    split uri=/index.php?p=keyword -> uri=/index.php, args=p=keyword
    [perdir /var/www/html/] internal redirect with /index.php [INTERNAL REDIRECT]
    

    I'll take this opportunity to correct some of the other answers.

    you need the L flag to stop rewriting once the rule has hit. (otherwise you get an endless loop)

    This is wrong for two reasons: (1) index.php does not match '^([a-z]+)/?$' and (2) even if it did [L] wouldn't stop the processing because this per-dir rewrite results in an internal redirect (see log) (as they often do) which [L] doesn't stop.

    I believe the problem is actually the lack of a forward slash at the beginning of your regular expression.

    No, the per-dir rewrite in strips of the initial slash (see log).

    RewriteRule %{REQUEST_URI} !.php

    This is probably a typo and should be RewriteCond %{REQUEST_URI} !.php

    I have no solution but I recommend cranking up the RewriteLogLevel until you can see what is going on.

    Edit: I don't think it is mod_rewrite. There is something else in your apache config causing the problem.

    From embobo

0 comments:

Post a Comment