Search code examples
phpapache.htaccessmod-rewriteurl-rewriting

htcaccess Rewrite Rule not working in any way


I am working on a project and I’m trying to do a URL rewrite in the root of my website. The .htaccess as it is now is as follows

RewriteEngine On 
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L]

RewriteRule ^screenshot-of-the-week/screenshot/([^/]+) /screenshot-of-the-week/screenshot/index.php?id=$1

Rewrite is enabled on my site. I have checked the code through htaccess tester and it shows the correct values.

Yet when I visit screenshot-of-the-week/screenshot/123 for an example, I get a 404 page. When I visit screenshot-of-the-week/screenshot/ it works just fine.

Also, when going to the "real" URL manually, it also works as expected: screenshot-of-the-week/screenshot/index.php?id=123

I can’t seem to figure out where the problem is and have tried moving the .htaccess to other folders and of course also editing the path, yet no success.

Any other troubleshooting tips anyone can give? How can I check what the redirect actually is doing in the background?


Solution

  • RewriteRule ^screenshot-of-the-week/screenshot/([^/]+) /screenshot-of-the-week/screenshot/index.php?id=$1
    

    The "problem" with this rule is that is also matches the rewritten URL (specifically, [^/]+ matches index.php) so gets rewritten a second time to /screenshot-of-the-week/screenshot/index.php?id=index.php (the id=123 parameter is overwritten). So, I would expect your script to be generating the 404 response (not Apache)?

    To resolve this, you should make the regex more specific and/or use the END flag (Apache 2.4) to prevent an additional loop (and second rewrite) by the rewrite engine.

    In your example you are passing a numeric value - so if you are only expecting a numeric value then match digits only.

    For example:

    RewriteRule ^screenshot-of-the-week/screenshot/(\d+)$ /screenshot-of-the-week/screenshot/index.php?id=$1 [END]
    

    Note that I also included the trailing $ on the regex, otherwise your site is open to abuse since anything could be appended to the URL and the same resource would be served. (In your original rule appending /<anything> would result in the same response.)

    (I'm assuming your .htaccess file is located in the document root.)


    I have checked the code through htaccess tester and it shows the correct values.

    The MWL tester only makes a single pass through the file. This is not how a real Apache server works. Consequently the MWL tester is unable to detect rewrite/redirect loops.

    When I visit screenshot-of-the-week/screenshot/ it works just fine.

    When you visit screenshot-of-the-week/screenshot/ then the rule is not processed (the regex does not match). mod_dir serves the DirectoryIndex document (index.php), but without the id parameter.