I need to redirect all requests from
https://example.com/*
to https://example.com/test/*
if the URL does not contain the test
substring.
So far I have these rewrite rules
RewriteBase /
RewriteCond %{THE_REQUEST} !^/test
RewriteRule ^/?$ /test/$1 [R=301,L] # if the url does not contain test, redirect to url with test
RewriteCond %{THE_REQUEST}% test
RewriteRule ^test?(.*)$ /$1 [L] # mask the fact that the url is not https://example.com/ and instead is https://example.com/test but apache serve the website like if it was on root
If I access https://example.com
it redirects to https://example.com/test
but gives infinite loop because of the second rule.
How can I combine it, so request to https://example.com/test*
do not get redirected but those request at https://example.com/*
do without having to change www root directory and so it will work for all URLs.
CodePudding user response:
UPDATE:
The test should be in url (for user experience), but the apache should route like if it was not in url and instead the request came to root url, so application routing is preserved internally without having to change the app itself.
Ah, Ok. However, you should be linking to the /test
URLs within your app (so you do still need to "change the app", despite your last comment), otherwise /test
isn't actually in the URLs that users and search engines see on the page (they will be redirected) and your users will experience an external redirect every time they click one of your links (bad for SEO and user experience).
The "redirect" implemented in .htaccess
to prefix "old" URLs with /test
is just for SEO - as with any "old" to "new" URL change. (It should not be required for your app to function - with /test
in the URL-path - since your internal URLs should already include /test
.)
Try it like this instead:
RewriteEngine On
# Insert "/test" at the start of the URL-path if absent in "direct" requests
RewriteRule %{ENV:REDIRECT_STATUS} ^$
RewriteRule !^test/ /test/$1 [R=301,L]
# Rewrite "/test" URLs back to root
RewriteRule ^test(?:$|/(.*)) /$1 [L]
The REDIRECT_STATUS
environment variable is used to prevent a redirect loop. This is empty on the initial request from the client and set to the HTTP response status after the rewrite (below).
Test first with 302 (temporary) redirects and only change to 301 (permanent) when you are sure this is working as intended.
You will need to clear your browser cache before testing.