Apache mod_rewrite from a folder to a different domain doesn't work with trailing slash - apache

I'm trying to rewrite URLs from old.domain.tld/project to domain.tld/subfolder/project using .htaccess in the project directory on the old server. I think I need to check for the host name so the rule only applies to the old server, even if the .htaccess file is also put on the new server.
I've tried the following .htaccess file:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^old\.domain\.tld$ [NC]
RewriteRule ^(.*)$ https://domain.tld/subfolder/project/$1 [R=301,L]
This works fine for URLs like https://old.domain.tld/project/index.php?p=q (redirects to https://domain.tld/subfolder/project/index.php?p=q) but not for the URL without the trailing slash—https://old.domain.tld/project ends up being redirected to https://domain.tld. Very odd! How do I make this work for both types of URL?
I tried a rather different method to make this a generic redirect, that could be included even if the folder name wasn't project, but this has the same problem:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^old\.domain\.tld$ [NC]
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteRule . https://domain.tld/subfolder/%1 [R=301,L]
In a server-wide configuration, a slash is appended to all requests for index files, e.g. old.domain.tld/project is redirected to old.domain.tld/project/. Could this be causing a problem?

Related

htaccess - Redirect to subfolder without changing browser URL

I've a domain that contains a subfolder with the web app structure. I added a .htaccess on my root domain to point the public folder on my subfolder web app. It works fine, but when I type www.example.com the browser URL changes to www.example.com/subfolder/public, but I would like that it doesn't change.
This is my .htaccess:
RewriteEngine On
RewriteRule ^.*$ subfolder/public [NC,L]
EDIT
This first .htaccess is used to redirect on subfolder/public, where there is an other .htaccess that makes all the works.
Here the code of the second .htaccess located on www.example.com/subfolder/public/:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
Sorry, just realised what is happening. It has nothing to do with the second .htaccess file in the subdirectory, as mentioned in comments.
RewriteRule ^.*$ subfolder/public [NC,L]
Since public is a physical directory on the file system, you need to include a trailing slash when internally rewriting to that directory. Otherwise, mod_dir is going to try to "fix" the URL by appending a slash - that is where the external redirect is coming from. (mod_dir implicitly triggers an external redirect from subfolder/public to subfolder/public/.)
So, try the following instead in your root .htaccess file:
RewriteRule .* subfolder/public/ [L]
The important thing is the trailing slash. The anchors (^ and $) on the RewriteRule pattern are not required, since you are matching everything. And the NC flag is also not required for the same reason.
As always, make sure the browser cache is clear before testing.
UPDATE#1: The single directive above rewrites everything, including static resources, to the directory subfolder/public/ which then relies on the second .htaccess file in the subdirectory to correctly route the request. In order to allow static resources to be rewritten correctly (represented in the HTML as root-relative URL-paths, of the form "/js/myjs.js") then you will need additional directives in order to rewrite these.
For example, to specifically rewrite all .js and .css files to the real location in /subfolder/public/...
# Rewrite static resources
RewriteRule (.+\.(?:js|css))$ subfolder/public/$1 [L]
# Rewrite everything else to the "public" directory
RewriteRule .* subfolder/public/ [L]
UPDATE#2: To make the above more general, and to rewrite any static resource (images, PDFs, .txt, etc...) we can check for the existence of the file before rewriting, something like:
# Rewrite static resources
RewriteCond %{DOCUMENT_ROOT}/subfolder/public/$1 -f
RewriteRule (.+) subfolder/public/$1 [L]
# Rewrite everything else to the "public" directory
RewriteRule .* subfolder/public/ [L]
This will mean that if any .css does not exist it will be passed through to subfolder/public/.

Redirect all pages in direcory except one subdirectory .htaccess

I want to have one URL still being served from a subdirectory on the old domain but redirect all others from the parent directory to the new domain.
www.olddomain.co.uk/directorya/directoryb -> no redirect
www.olddomain.co.uk/directorya -> www.newdomain.co.uk/directorya
This works if the URL is typed with a trailing slash
RewriteCond %{REQUEST_URI} !^/directorya\/directoryb [NC]
RewriteRule ^(.*)$ http://www.newdomain.co.uk/ [L,R=301]
So http://www.olddomain.co.uk/directorya/directoryb/ works but http://www.olddomain.co.uk/directorya/directoryb fails.
Tried added $ at the end and other connotations and tried
RewriteEngine on
RewriteRule !^myspecialdirectory/mynextdirectory($|/) http://newdomain.example%{REQUEST_URI} [L,R=301]
from Redirect entire site except one directory to a new site - apache .htaccess
What do I need to do to get http://www.olddomain.co.uk/directorya/directoryb/ or http://www.olddomain.co.uk/directorya/directoryb to redirect? (while all other http://www.olddomain.co.uk pages go to http://www.newdomain.co.uk
For reasons I don't understand http://www.olddomain.co.uk/directorya/directoryb goes to Google and doesn't redirect
Try using THE_REQUEST variable and make sure this this very first rule:
RewriteCond %{THE_REQUEST} !\s+/+directorya/directoryb [NC]
RewriteRule ^ http://www.newdomain.co.uk/? [L,R=301]
Test it after clearing your browser cache.

Disguising URL by rewriting htaccess

I have a site built for a client located on my server (ie http://www.myserver.com/clientsite). Can I disguise the URL by modifying the .htaccess file on my client's host (http://www.clientsite.com) to read as his domain, but display my content and keep the subdirectories in tact?
So: http://www.myserver.com/clientsite would read http://www.clientsite.com
and http://www.myserver.com/clientsite/about would read http://www.clientsite.com/about
I tried the following, but it was directing me to a 404 error.
RewriteEngine On
RewriteCond %{HTTP_HOST} ^clientsite.com
RewriteRule ^(.*) http://www.myserver.com/clientsite/$1 [P]
Try this:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?clientsite.com
RewriteRule ^(.*) http://www.myserver.com/clientsite/$1 [P]
Since you mentioned that your client's site is http://www.clientsite.com and Rewrite condition was applied only to clientsite.com , I changed it to support both with and without www.
If it doesn't work, put your rewrite log and I'll check that.

htaccess adding WWW and changing filename in subdirectory

I know similar questions have come up, though often without a working answer. I'm hoping to have better luck!
I have an .htaccess file in my root directory adding "www" to everything:
RewriteEngine on
RewriteCond %{SERVER_NAME} ^mysite.org
RewriteRule ^(.*)$ http://www.mysite.org/$1 [R=permanent,L]
This generally works fine. I have a subfolder (/myquiz/) in which the old index.html file has been replaced with index.php. I know there are external links to /myquiz/index.html, so I want to make sure those redirect. Leaving index.html in place and trying to redirect from that led to some odd behavior, but adding an .htaccess in that directory works for that:
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html?$ /myquiz/index\.php [NC,R]
Trying to load index.html redirects to index.php as hoped for, and the WWW gets added if needed. But requesting mysite.org/myquiz/index.php directly does not add the WWW.
I tried adding "RewriteEngine inherit", but that resulted in calls getting redirected to my root folder instead. A great trick if I want to make a subfolder inaccessible, but not helping here. I also tried just adding the code from my root .htaccess into the beginning of my subfolder's .htaccess, but that worked no better.
Any ideas?
You shouldn't need to add another htaccess file in the myquiz folder. This should work in the htaccess file in the root of the site. Remove the htaccess file in myquiz and try this.
RewriteEngine On
RewriteCond %{HTTP_HOST} ^mysite\.org
RewriteRule ^(.*)$ http://www.mysite.org/$1 [R=301,L]
RewriteRule ^myquiz/index\.html$ /myquiz/index.php [R=301,L]
Also I wouldn't use %{SERVER_NAME} unless your are sure the name is set properly in the config file. Then it can be more reliable than HTTP_HOST, otherwise I would instead use %{HTTP_HOST}.
I think inherit would work if you add an L flag to the rule that you have in your myquiz folder:
RewriteRule ^index\.html?$ /myquiz/index\.php [NC,R,L]
So that it redirects first, then the inherited rule (the www) gets applied after.
You could also just put both rules in the same file:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^mysite.org$ [NC]
RewriteRule ^(.*)$ http://www.mysite.org/$1 [R=permanent,L]
RewriteRule ^myquiz/index\.html$ http://www.mysite.org/myquiz/index.php [R=permanent,L]

apache .htaccess file https:// redirect ---- rewrite it for subdirectory?

here is my code:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
This will successfully rewrite everything to https (it will "force" https), if I put it in my home directory's .htaccess file. However, what about if I only want my subdirectory of /support to force https? How to rewrite the above code?
The intent is with regards to forcing https in WHMCS
Thanks in advance!
If you want to redirect only a subfolder and not a subdomain, that is even easier. To redirect the subfolder /support/ you would use the following code:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^/support/(.*)$ https://%{HTTP_HOST}/support/$1 [QSA]
I added a QSA flag, which will force any query string that was entered to be appended to the redirect URL. If you don't use query strings in this section of the site, you can remove that flag. Also, if the string as shown doesn't work, you can try removing the leading slash from the RewriteRule and retrying it.
Add the following rule before the %{HTTPS} line:
RewriteCond %{HTTP_HOST} ^support.domain.com$
This will only allow the rule to execute if the visitor is coming from the subdomain. Please note, these rules will likely need to be put in the .htaccess file that is the root for the subdomain, not the main site root folder.