Search code examples
apache.htaccesshttp-redirectrequestrelative-path

Apache .htaccess relative request URI redirection


First of all, I have following directory structure:

  • /project_directory/rewriting_experimentation_directory
    • htaccess File
    • realfile.txt

What I am trying to do is following:

When the user requests http://domain.xts/.../rewriting_experimentation_directory/falsename, realfile.txt should be displayed. That I have already achieved, with the following expression in the .htaccess file:

RewriteEngine On
RewriteRule   ^falsename$  realfile.txt

However, I am also trying to achieve that when the user requests this url http://domain.xts/.../rewriting_experimentation_directory/realfile.txt, that he be redirected to http://domain.xts/.../rewriting_experimentation_directory/falsename and then, naturally, be displayed the content fo realfile.txt.

I have encountered two issues, however:

  1. Firstly, Redirect 301, RedirectMatch, Alias etc. all require absolute pathes, and not those relative to the directory the .htaccessfile is in. This is completely inacceptable, since the path before the directory rewriting_experimentation_directory differs from that on localhost when I upload it to domain.xts (or anywhere else)
  2. Secondly, it does not match the requested URL, but the URL that I shall henceforth refer to as the "response" URL, namely the name of the file whose content Apache is returning to the client. Thus, if I try to redirect from realfile.txt to falsename, I get an infinite loop. (Which takes a bit long to load, sadly).

Is there any way to achieve this?

Also, as an answer to the question, 'Why would you need that?' – to learn, for once, and secondly, for future reference (which may still count as learning). I hope that does not invalidate my question.


Solution

  • Try adding this before your RewriteRule:

    RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ (.*)/realfile.txt\ HTTP
    RewriteRule ^realfile.txt$ %2/falsename [R=301,L]
    

    There's a couple of things that this does, if you simply redirect using RewriteRule (the R in the bracket), it will cause a rewrite loop and you'd get an error. You need to check that the actual request is for "realfile.txt". The regular expression, (.*)/realfile.txt tries to extract the relative URI, it will be where the .htaccess file resides in (otherwise these conditions/rules won't be exectuted at all), and since we don't know what it is, we can just backreference it using %2 in the RewriteRule.

    So if you place the .htaccess file in /test/ and request for http://yourdomain/test/realfile.txt you will be 301 redirected to http://yourdomain/test/falsename and your rewrite rule will serve realfile.txt. If you place the .htaccess file in /deploy/ and request for http://yourdomain/deploy/realfile.txt you will be 301 redirected to http://yourdomain/deploy/falsename, etc.