1

I want something very specific to happen with my .htaccess file, but I'm not sure if it's possible. I want links like example.com/ExampleFile.txt to be forwarded to example.com/Other/ExampleFile.txt (as I'm about to move everything into the "Other" directory to do a cleanup of the root directory.) Then if no file is detected in the "Other" directory, I'd like the path that the user originally typed (example.com/ExampleFile.txt) to be sent through to subdomain.example.com/ExampleFile.txt.

Please let me know if this is possible, and if so, what code do I need to add to my .htaccess file? Note that I use LiteSpeed, not Apache.

I can already do the last part with the following piece of code:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ https://subdomain.example.com%{REQUEST_URI} [R=302,L]
MrWhite
  • 43,179
  • 8
  • 60
  • 84
Ryder Cragie
  • 145
  • 1
  • 9

1 Answers1

1

Add the following rewrite before your existing redirect to test whether the request maps to a file in the /Other subdirectory before rewriting the request if it is:

# Rewrite request to the "/Other" subdirectory
#  - only if the request maps to a file or directory there
RewriteCond %{DOCUMENT_ROOT}/Other/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/Other/$1 -d
RewriteRule (.+) Other/$1 [L]

NB: If the same file exists in both the root (or rather, outside of the "/Other" subdirectory) then the one inside the /Other subdirectory wins.

If you only want to rewrite actual files and not directories then remove the second condition and OR flag.

Presumably all requests to the root should be rewritten to /Other/ (since this exists as a directory) so this should be performed unconditionally:

# Rewrite root to "/Other/"
RewriteRule ^$ /Other/ [L]

And your existing redirect to subdomain.example.com follows these rewrites.


UPDATE:

But I did notice that I can't access files without the file extensions using this method. [...] Any ideas why I can't access files without the extension when using this method? I have a file called ExampleFile.txt in /Other which can be seen at example.com/ExampleFile.txt but not example.com/ExampleFile.

Because we are having to check whether the requested URL maps to a file (or directory) in the subdirectory before rewriting the URL.

If you insist on having extensionless URLs for different types of resources (.txt, .html, images, etc.) then you will need to manually check each file extension for which you permit to be extensionless (in much the same way as you have already done for requests outside of the stated subdirectory).

For example:

# For files that already have an extension OR directories...
# NB: Directories could be requested initially with or without the trailing slash
# Rewrite request to the "/Other" subdirectory
#  - only if the request maps directly to a file or directory there
RewriteCond %{DOCUMENT_ROOT}/Other/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/Other/$1 -d
RewriteRule (.+) Other/$1 [L]

# Check for ".txt" files...
RewriteCond %{REQUEST_URI} !(\.\w{2,4}|/)$
RewriteCond %{DOCUMENT_ROOT}/Other/$1.txt -f
RewriteRule (.+) Other/$1.txt [L]

# Check for ".html" files...
RewriteCond %{REQUEST_URI} !(\.\w{2,4}|/)$
RewriteCond %{DOCUMENT_ROOT}/Other/$1.html -f
RewriteRule (.+) Other/$1.html [L]

# Check for ".php" files...
RewriteCond %{REQUEST_URI} !(\.\w{2,4}|/)$
RewriteCond %{DOCUMENT_ROOT}/Other/$1.php -f
RewriteRule (.+) Other/$1.php [L]

# Check for ".jpg" files...
RewriteCond %{REQUEST_URI} !(\.\w{2,4}|/)$
RewriteCond %{DOCUMENT_ROOT}/Other/$1.jpg -f
RewriteRule (.+) Other/$1.jpg [L]

# etc.
MrWhite
  • 43,179
  • 8
  • 60
  • 84
  • That seems to have worked without adding the 2nd bit of code you sent (is there any major reason to add the last block?). But I did notice that I can't access files without the file extensions using this method. I've copied my .htaccess file into a TXT file so you can see: RyderCragie.com/htaccess.txt. Any ideas why I can't access files without the extension when using this method? I have a file called ExampleFile.txt in /Other which can be seen at RyderCragie.com/ExampleFile.txt but not RyderCragie.com/ExampleFile. Note: I do not use any type of file hosting on the subdomain - I use short.io. – Ryder Cragie Jan 18 '22 at 10:26
  • @RyderCragie Without the 2nd bit of code then requests for the document root are not rewritten to the subdirectory (they remain in the document root). I've updated my answer with regards to extensionless URLs. – MrWhite Jan 18 '22 at 12:11
  • But I can access files in my /Temporary directory without the extension. I have no .htaccess file in there and I have no code in my top level .htaccess file which specific the /Temporary directory. – Ryder Cragie Jan 18 '22 at 14:29
  • *specify‎‎‎‎‏‏‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎ – Ryder Cragie Jan 18 '22 at 14:40
  • @RyderCragie Yes, the rules in the top level `.htaccess` apply to all directories, not just the root. In the same way you could request `/Other/ExampleFile` directly without any additional directives. But what you are wanting to do now is request `/ExampleFile` but serve `/Other/ExampleFile.txt` (in a **different** directory). – MrWhite Jan 18 '22 at 14:41
  • I'd rather not manually add each file extension all over again, considering I may want to do this multiple times in the future. The .htaccess file will get very large. Accessing them with the file extension will do. Thanks. – Ryder Cragie Jan 18 '22 at 14:52
  • Update: I would like this to happen for any folder, not just /Other. Would "*" work? – Ryder Cragie Feb 28 '22 at 20:17
  • 1
    @RyderCragie There is no wildcard-like mechanism to express "any" directory, unfortunately. You would need to hardcode each directory you want to check. – MrWhite Mar 02 '22 at 14:22
  • I noticed that https://RyderCragie.com/Wallpapers/ (with trailing slash) gets **rewritten**, but https://RyderCragie.com/Wallpapers gets **redirected** to https://RyderCragie.com/Other/Wallpapers/. Do you know why it is **redirected** rather than **rewritten** if I do not add the trailing slash please? I've uploaded a copy of my .htaccess file at https://RyderCragie.com/htaccess.txt. – Ryder Cragie May 22 '22 at 19:12
  • 1
    @RyderCragie That's because mod_dir will append the trailing slash with a 301 redirect (in order to "fix" the URL) _after_ the URL has been rewritten to the `/Other` subdirectory. If a URL maps to a filesystem directory it should have a trailing slash. If you are unable to ensure a trailing slash is present on the requested URL then you'll need to "fix it" manually. See [my answer](https://stackoverflow.com/a/70994418/369434) to the following question that deals with this: [URL masking not working for URLs that omit the trailing slash](https://stackoverflow.com/q/70990152/369434) – MrWhite May 22 '22 at 21:07
  • How could I have this work across all directories? – Ryder Cragie Jul 09 '22 at 20:16