How to rewrite a subdomain in htaccess - .htaccess

Im trying to simplify the subdomain complexity perception to the user so I would like to mask the subdomain.
My goal is the following:
When the user tries to get here
blog.example.com/blog/whatever
I would like to mask the subdomain to be
example.com/blog/whatever
Same content served but with the subdomain hidden.
I have tried the following but with no success.
<IfModule mod_rewrite.c>
RewriteCond %{HTTP_HOST} ^https://blog\.example.com\/blog [NC]
RewriteRule ^(.*)$ http://example.com/blog/$1 [R=301,L]
</IfModule>
Update: Rewrite module is enabled

RewriteCond %{HTTP_HOST} ^https://blog\.example.com\/blog [NC]
RewriteRule ^(.*)$ http://example.com/blog/$1 [R=301,L]
The HTTP Host header (ie. the value of the HTTP_HOST server variable) contains the hostname only, ie. blog.example.com. It does not contain the full absolute URL.
So, your rule should be like this instead:
RewriteCond %{HTTP_HOST} ^blog\.example\.com [NC]
RewriteRule ^blog($|/) https://example.com%{REQUEST_URI} [R=301,L]
This matches the URL-path /blog or /blog/<whatever> (but not /blog<something>) and redirects to the same URL-path at example.com (+ HTTPS). The REQUEST_URI server variable contains the root-relative URL-path, starting with a slash.
You were redirecting to HTTP, but I assume this must be HTTPS?
You should clear your browser cache before testing and test first with a 302 (temporary) redirect to avoid potential caching issues.

Related

Forwarding Path With .htaccess

I use cPanel hosting on https://files.example.com and I'd like https://files.example.com/anything-here to redirect to my main website and forward the path, so you'd end up on https://www.example.com/anything-here. Is this possible?
Note that I also have a forced SSL redirect inside my .htaccess file.
https://www.example.com is a Google Site.
My .htaccess file:
ErrorDocument 400 /index.html
ErrorDocument 401 /index.html
ErrorDocument 403 /index.html
ErrorDocument 404 /index.html
ErrorDocument 500 /index.html
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
Header always set Content-Security-Policy "upgrade-insecure-requests;"
https://www.example.com is a Google Site.
If the two sites are on different servers and you simply need to redirect everything from one host to the other and maintain the same URL-path then you don't appear to need anything in your .htaccess file at files.example.com except for the following mod_alias Redirect directive:
# Redirect everything to https://www.example.com/ and maintain URL-path
Redirect 302 / https://www.example.com/
The Redirect directive is prefix matching and everything after the match is copied onto the end of the target URL. So, a request for /foo is redirected to https://www.example.com/foo.
If, however, you have other hostnames pointing to your cPanel account then you'll need to use a mod_rewrite rule and check the requested hostname.
For example, at the end of your existing .htaccess file:
# Redirect every request for "files.example.com"
# to https://www.example.com/ and maintain URL-path
RewriteCond %{HTTP_HOST} ^files\.example\.com [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=302,L]
Reference:
https://httpd.apache.org/docs/2.4/mod/mod_alias.html#redirect
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriterule
UPDATE#1:
But I just realised that it's also forwarding the path for files that do exist on my hosting. I onlt want it to forward invalid paths through to www.example.com.
In that case, you'll need to do it like this instead:
RewriteCond %{HTTP_HOST} ^files\.example\.com [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=302,L]
The 2nd and 3rd conditions check that the request does not map to an existing file (or directory) before issuing the redirect.
Remove the first condition that checks the HTTP_HOST if it's not required.
UPDATE#2:
Is there a way to have it exclude "/URL" from this? If "URL" is specified in the path (example.com/URL/whatever) then I do not want this .htaccess rule to take place. I just want it to use my ErrorDocuments for this path.
If it's just the one pattern you want to exclude, ie. all URLs that start /URL then you can modify just the RewritRule directive. For example:
:
RewriteRule !^URL https://www.example.com%{REQUEST_URI} [R=302,L]
Any URLs that do not start /URL will be excluded. Note that this also includes /URLwhatever, not just /URL/whatever.

Rewrite subdomain to existing folders

I have a folder structure like this:
public_html
...images
...v2020
...v2021
With mod_rewrite, I redirect to the folder v2021 and force to https://www.example.com. Now I struggle with adding subdomains. When I go to images.example.com I want the redirection to the folder images, with images.example.com being unchanged in the address field.
I tested the code in two parts separately, first is the forwarding towards https://www including subdomain. It works without subdomains, but if I add any subdomain it leads to nowhere.
RewriteEngine on
# "example.com" to "www.example.com" (and HTTPS)
RewriteCond %{HTTP_HOST} ^(example\.com) [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,R=301,L]
# HTTP to HTTPS (same host) - preserve subdomain
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [NE,R=301,L]
The second part as a minimal working example is the forwording of the standard domain (no subdomain) and subdomain forwarding to a debug script.
RewriteCond %{HTTP_HOST} ^www\.example\.com
RewriteRule ^((?!v2021/).*)$ v2021/$1 [L]
RewriteCond %{HTTP_HOST} ^(.+?)\.example\.com
RewriteRule (.*) echo.php\?a=%1\&b=$1 [L]
The script works fine and outputs a="www" when using it with the upper condition, but it is not execute with the lower one. I get forwarded to nowhere.
Thanks for your help!
There seem to be several issues here...
RewriteCond %{HTTP_HOST} !^www\. [OR,NC]
RewriteCond %{HTTPS} off
RewriteRule ^ https://www.example.com%{REQUEST_URI} [NE,R=301,L]
You first rule redirects all your subdomains (every hostname that does not start www.) to www.example.com, so the subdomain is lost. You probably need to change the first condition so that it only redirects requests for example.com (the domain apex) to www.example.com. But you also need to split the HTTP to HTTPS redirect in order to preserve the subdomain (images etc.)
For example:
# "example.com" to "www.example.com" (and HTTPS)
RewriteCond %{HTTP_HOST} ^(example\.com) [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,R=301,L]
# HTTP to HTTPS (same host) - preserve subdomain
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [NE,R=301,L]
RewriteCond %{HTTP_HOST} ^(.*)\.example\.com
RewriteRule ^(.*)$ %1/$1 [L,NC,QSA]
This will result in an internal rewrite loop (500 error) since it repeatedly rewrites to subdomain/url-path resulting in subdomain/subdomain/subdomain/url-path etc. etc.
You need a condition to either only rewrite the direct/initial request (not rewritten requests), or check that the subdomain has not already been rewritten to a subdirectory of the same name.
However, this also rewrites the www subdomain, which I assume is not the intention, so another condition is required to exclude this.
For example, to only rewrite the initial request and exclude the www subdomain:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTP_HOST} ^(.*)\.example\.com
RewriteRule (.*) %1/$1 [L]
By always rewriting the initial request and not explicitly checking that the subdirectory does not match the subdomain means that you can have a sub-subdirectory of the same name as the subdomain (if required). eg. /images/images/foo.jpg is not a problem.
The NC and QSA flags on the RewriteRule are not required. (Since it's already case-insensitive and you have no query string to append to.)
The REDIRECT_STATUS environment variable is empty on the initial request and set to 200 (as in 200 OK status) after the first successful rewrite, so by checking that it is empty it avoids a rewrite loop.
If you've configured a wildcard subdomain then you might want to check that the subdirectory exists before rewriting. (Although filesystem checks are relatively expensive, so this is probably best avoided if possible. Particularly when serving assets.)
RewriteRule ^((?!v2021/).*)$ /v2021/$1 [L]
This would seem to conflict with the above rule. Shouldn't this only apply to the www subdomain (the opposite of the above rewrite)? For example:
RewriteCond %{HTTP_HOST} ^www\.
RewriteRule ^((?!v2021/).*)$ v2021/$1 [L]

Google is not indexing https

I have used the http protocol for a long time. After years I implemented a domain certificate. Now I am trying to get the website with the https:// protocol indexed but Google still indexes the http protocol.
I have tried several things. I enabled the 'Force SSL with https redirect' option in DirectAdmin.
I changed my .htaccess so the browser redirects every option to the https protocol:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^[^.]+\.[^.]+$
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RedirectMatch permanent index.php/(.*) https://www.***.com/$1
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.(php|html) [NC]
RewriteRule ^index\.php$ https://www.***.com/ [R=301,L]
RewriteCond %{THE_REQUEST} ^GET\ /.*/index\.(php|html)\ HTTP
RewriteRule (.*)index\.(php|html)$ /$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^domain\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.domain\.com$
RewriteRule ^home\.html$ "https\:\/\/www\.domain\.com\/" [R=301,L]
RewriteCond %{HTTP_HOST} ^domain\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.domain\.com$
RewriteRule ^home$ "https\:\/\/www\.domain\.com\/" [R=301,L]
I have created a sitemap.xml that contains only the https:// protocol.
In the Google Search Console I see that the website is indexed today and that the 'Google selected canonical URL' is still the http protocol.
Does someone know what I need to do to fix this problem?
I changed my .htaccess so the browser redirects every option to the https protocol:
Actually, you've not.
You don't have an HTTP to HTTPS redirect at all and the first rule (a non-www to www redirect) specifically maintains whatever protocol has been requested (HTTP or HTTPS).
Try the following two rules instead, replacing your first (non-www to www) rule:
# non-www to www (and HTTPS)
RewriteCond %{HTTP_HOST} ^[^.]+\.[^.]+$
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# HTTP to HTTPS (already www)
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
The remaining directives can also be simplified...
# Redirect to path-info (removing "index.php")
RewriteRule ^(.+/)?index\.php/(.*) /$1 [R=301,L]
# Remove "index.php" from the end of the URL
RewriteRule ^(.+/)?index\.php$ /$1 [R=301,L]
# Redirect "home" and "home.html" to the document root
RewriteRule ^home(\.html)?$ / [R=301,L]
You don't seem to need to target the domain name in the later directives, so I've removed the seemingly superfluous conditions.
I've simplified/reduced the two rules that removed index.php into a single directive. Unless you have a front-controller whereby you are routing all requests to index.php then you don't need the additional condition that checks against THE_REQUEST. (There is no front-controller in the directives you've posted.)
(Although the rule that removes and redirects to the path-info is a little out of place if you don't have a front-controller?)
I've changed the mod_alias RedirectMatch to the corresponding*1 mod_rewrite rule. mod_alias directives are processed after mod_rewrite, despite the apparent order of directives in the config file, so it is advisable to avoid mixing redirects from both modules to avoid unexpected conflicts.
(*1 I've also "corrected" this so to avoid matching URLs of the form <anything>index.php, rather than <anything>/index.php, which I assume is the intention.)
Clear your browser cache and test first with 302 (temporary) redirects to avoid any potential caching issues.
I also tried to delete the canonical link element
You should not delete the "canonical link element" providing you are linking to the correct canonical URL, ie. HTTPS + www.
You've not actually stated how long it is since you've "switched to HTTPS", but this can take some time. Google naturally favours HTTPS, but you are likely to have many HTTP backlinks due to the age of your site. It is important that you 301 redirect HTTP to HTTPS.
You should register both properties: HTTP and HTTPS in GSC and monitor the index status of both.
NB: Questions of this nature are generally better asked on the Webmasters stack: https://webmasters.stackexchange.com/

htaccess redirect from A record to www and new page

Need to redirect example.com/page to www.example.com/page_2. Can also be from www.example.com/page to www.example.com/page_2. I have tried
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com/page [NC]
RewriteRule (.*) https://www.example.com/page_2 [R=301,L]
But that does not appear to work.
The HTTP_HOST server variable contains just the Host header, as its name suggests (eg. www.example.com), it does not include the URL-path as well (ie. /page).
You match the URL-path with the RewriteRule pattern. So, try the following instead:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com [NC]
RewriteRule ^page$ https://www.example.com/page_2 [R=302,L]
Change the 302 (temporary) redirect to 301 (permanent) only when you are sure it's working OK (if this is indeed intended to be permanent). 301s are cached hard by the browser so can make testing problematic.
Unless you have multiple domains on this account, you can remove the RewriteCond directive altogether.

redirect from example.com/forum to example.ir/forum

i'm going to redirect from
www.example.com/forum or example.com/forum
to
www.example.ir/forum
using htaccess
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example.ir/forum$ [OR]
RewriteCond %{HTTP_HOST} ^example.com/forum$ [OR]
RewriteCond %{HTTP_HOST} ^www.example.com/forum$
RewriteRule (.*) http://www.example.ir/forum$1 [R=301,L]
i fail to do that and i always got:
www.example.irforum (without slash /) which is dead link.
The code you have posted could not possibly redirect to www.example.irforum (without slash). In fact, the code you have posted won't do anything (since none of the conditions will match). If you are seeing a redirect then it's possibly a previously cached (erroneous) redirect.
Assuming example.com and example.ir are pointing to the same place then try the following in your .htaccess file:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$ [NC]
RewriteRule ^forum(.*) http://www.example.ir/forum$1 [R=302,L]
The above rules are processed as follows:
Does the URL-path (less the directory prefix) of the request match the RewriteRule pattern ^forum(.*)? If so, then continue...
Does the HTTP_HOST server variable match the CondPattern. ie. Is the Host header either www.example.com or example.com? If so, then continue...
Redirect the request to http://www.example.ir/forum$1 - this is the RewriteRule substitution. $1 refers to the captured group (first parenthesised subpattern) in the RewriteRule pattern - ie. whatever matches (.*).
If example.com and example.ir point to different servers then you don't need the RewriteCond directive.
Test with 302 (temporary) redirects until you are sure it's working OK then change to 301 (permanent). Or, test with browser caching disabled.
The HTTP_HOST variable contains just the HTTP Host header. eg. example.com. This contains no path information. Use the RewriteRule pattern to match the URL-path.

Resources