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.
Related
On our shared hosting server, we had a request to keep client's domain on their server but redirect the DNS responsible for web traffic to our server.
On our server we had to add an entry in the .htaccess file in our root to point it to a folder in the server:
RewriteCond %{HTTP_HOST} ^(www\.)?example\.pl$ [NC]
RewriteCond %{REQUEST_FILENAME} !/WebsitesLive/Example/
RewriteRule ^(.*)$ /WebsitesLive/Example/$1 [L]
And the website works fine but we noticed in Google Analytics that some people access the website using https://example.pl/WebsitesLive/Example. I finally realised that (maybe) it's the HTTPS and non-www redirection in the htaccess file of the client's site:
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Is it true that %{REQUEST_URI} would, in this case, contain WebsitesLive/Example in the redirection URL?
Most importantly, how do I stop it?
Is it true that %{REQUEST_URI} would, in this case, contain WebsitesLive/Example in the redirection URL?
Yes, after the internal rewrite from the root the REQUEST_URI server variable is updated to include the full URL-path. You could instead capture the URL-path in the RewriteRule pattern and use the backreference which will be relative to the directory that contains the .htaccess file.
For example:
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=301,L]
(You were already capturing the URL-path, but not using it.)
Ordinarily, if this canonical redirect was used in a subdirectory and that subdirectory was part of the visible URL then this would be incorrect, since it would remove the subdirectory from the redirected URL.
Alternatively, you could implement the canonical redirects in the root .htaccess file instead.
However, whilst this should prevent the filesystem directory being exposed in the canonical redirect, this doesn't prevent a user from accessing this subdirectory (from any domain). And since this subdirectory has already been exposed (especially as a 301 permanent redirect) then direct access to this subdirectory needs to be blocked or redirected back to the root. However, we need to be careful of redirect loops when doing so.
You can use something like the following in the subdirectory .htaccess to redirect any "direct" requests from the user back to the root:
# /WebsitesLive/Example/.htaccess
# Redirect direct requests to subdirectory back to root
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=301,L]
The REDIRECT_STATUS environment variable is empty on direct requests, but set to the HTTP status code after the first internal rewrite - thus preventing internal rewrites to the subdirectory being redirected back to the root (an endless redirect loop).
Aside:
RewriteCond %{HTTP_HOST} ^(www\.)?example\.pl$ [NC]
RewriteCond %{REQUEST_FILENAME} !/WebsitesLive/Example/
RewriteRule ^(.*)$ /WebsitesLive/Example/$1 [L]
Whilst this might "work", the second condition is too broad since it is checking that /WebsitesLive/Example/ does not occur anywhere in the "filesystem path". Whereas you should be checking that /WebsitesLive/Example/ does not occur at the "start" of the URL-path. In other words, it should be like this:
:
RewriteCond %{REQUEST_URI} !^/WebsitesLive/Example/
:
Note that this condition is only necessary (to prevent a rewrite loop) if there is no .htaccess file in the subdirectory (being rewritten to) that contains mod_rewrite directives. (Since mod_rewrite directives in the subdirectory completely override the parent - by default.)
If there is no .htaccess file in the subdirectory then you would obviously need to prevent direct access to that subdirectory in the root .htaccess file, but the required rule would be slightly different to the above. For example:
# /.htaccess
# Redirect direct requests to subdirectory back to root
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^WebsitesLive/Example/(.*) https://%{HTTP_HOST}/$1 [R=301,L]
# Rewrite to subdirectory
:
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.
I have some files placed under a particular folder in my old domain:
http://www.olddmain.com/subfolder/example1.html
I want to redirect all files under this folder to a new domain.
Example:
http://www.newdomain.com/subfolder/example1.html
How do I do this without losing Ranking of the pages?
Maybe you need this
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.olddomain\.com$
RewriteRule (.*) http://www.newdomain.com/$1 [R=301,L]
RewriteCond %{HTTP_HOST} !^olddomain\.com$
RewriteRule (.*) http://www.newdomain.com/$1 [R=301,L]
from "Redirecting to a different domain" in Redirecting a Web Folder Directory to another Directory in htaccess
In the olddomain.com/subfolder/.htaccess file you just need a single mod_alias Redirect directive to redirect all files to newdomain.com/subfolder/<file>:
Redirect 302 /subfolder http://www.newdomain.com/subfolder
Change the 302 (temporary) to 301 (permanent) only when you are sure it's working OK. (301s are cached hard by the browser, so can make testing problematic.)
However, if olddomain.com and newdomain.com point to the same place then you will need to use mod_rewrite and include a condition that specifically checks for the host being requested, otherwise you'll get a redirect loop. For example, in the same olddomain.com/subfolder/.htaccess file:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?olddomain\.com [NC]
RewriteRule ^ http://www.newdomain.com%{REQUEST_URI} [R=302,L]
This redirects any request for olddomain.com/subfolder/<anything> to http://www.newdomain.com/subfolder/<anything>.
Again, change 302 to 301 when you are sure it's working OK.
I am currently using this .htaccess to redirect all the requests for pages with a directory to my index.php
RewriteEngine on
RewriteCond $1 !^(index\.php|cas)
RewriteRule ^(.*)$ /seattle/index.php/$1 [L]
And this works just fine and produces urls that hide the index.php, and I have code in index.php that makes urls clean looking.
But now I need to force pages to connect via ssl, so I tried
RewriteEngine on
RewriteCond %{SERVER_PORT} 80
RewriteCond $1 !^(index\.php|cas)
RewriteRule ^(.*)$ https://example.com/seattle/index.php/$1 [L]
and it works to force ssl, but now it also forces the url to include the index.php:
https://example.com/seattle/index.php/pagename
instead of what I want
https://example.com/seattle/pagename
What am I missing?
To change protocol (HTTP -> HTTPS) and/or domain name (www.example.com -> example.com) the proper redirect ("301 Permanent Redirect" or "302 Found/Temp Redirect") is required.
Therefore you cannot combine rewrite and redirect and still showing original URL. It has to be 2 different rules and the one for changing protocol/domain should be listed first. For example:
RewriteEngine on
# force HTTPS for all URLs
RewriteCond %{HTTPS} =off
RewriteRule . https://example.com%{REQUEST_URI} [R=301,L]
# other rewrite rules
RewriteCond $1 !^(index\.php|cas)
RewriteRule ^(.*)$ /seattle/index.php/$1 [L]
The rule I have added will redirect ALL HTTP URLs to HTTPS. If you need only some of them to be redirected -- add appropriate conditions via additional RewriteCond line(s).
The %{HTTPS} is the most common and kind of "proper" way of checking if SSL is ON or OFF (but it is all depending on your specific circumstances and server config). When checking against %{HTTPS} you are safe against situation when your site is running on non-standard port (other than 80). You can use %{SERVER_PORT} =80 instead (will work for majority of cases).
With the above rules the rewrite for http://example.com/seattle/pagename will occur in 2 steps:
301 Redirect to https://example.com/seattle/pagename
Rewrite (internal redirect) to /seattle/index.php/pagename
So I have moved a website and am trying to 301 redirect everything, which I do quite often so this is a weird problem but probably something stupid I'm not seeing.
ALL of my redirects are working fine, except any redirect that the first string starts with "/Dining" or "/dining" are failing. For example, this redirect works fine-
Redirect 301 /healthfitness/teeth.cfm /healthcare/pretty-teeth
...as well as 100s of others.
But all of these are failing (many more than I'm showing)-
Redirect 301 /Dining/diningreviews/vawines.cfm /shopping/wines-2004
Redirect 301 /Dining/diningathome/carrotcake.cfm /home-garden/carrot-cake-2003
Redirect 301 /Dining/diningathome/oldvarolls.cfm /home-garden/virginia-rolls-2003
Redirect 301 /Dining/diningathome/pumpkincake.cfm /home-garden/pumpkin-cake-2003
The top of my .htaccess file looks like this-
RewriteEngine On
RewriteBase /
#uploaded files
RewriteRule ^(.*/)?files/$ index.php [L]
RewriteCond %{REQUEST_URI} !.*wp-content/plugins.*
RewriteRule ^(.*/)?files/(.*) wp-content/blogs.php?file=$2 [L]
# add a trailing slash to /wp-admin
RewriteCond %{REQUEST_URI} ^.*/wp-admin$
RewriteRule ^(.+)$ $1/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule . - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-.*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]
<IfModule mod_security.c>
<Files async-upload.php>
SecFilterEngine Off
SecFilterScanPOST Off
</Files>
</IfModule>
#Everything below here are Redirect 301s
Dont redirect statements have to include the protocol in the destination?
You must include the domain name in the redirect.
Never mix mod_alias and mod_rewrite directives in the same file. If you use RewriteRule for any of your rules, you must use RewriteRule (not Redirect or RedirectMatch) for ALL of your rules.
List all redirects (using RewriteRule syntax) before any of the rewrites (using RewriteRule syntax) otherwise you will inadvertently expose rewritten pointers back out on the the web as new URLs.
The code you are currently using is very very inefficient. The .* patterns mean your .htaccess file will attempt hundreds of thousands of "back off and retry" trial matches for every URL request hitting the server.
In particular,
^(.\*/)? should be replaced by ^([^/]+/)\* in two places.
^.\*/ should be replaced by ^/([^/]+/)\*
!.\*wp-content/plugins.\* should be replaced by !wp-content/plugins
^([_0-9a-zA-Z-]+/)?(.\*\\.php)$ should be replaced by ^([_0-9A-Z-]+/)?([^.]+\\.php)$ with the [NC] flag also added.
The "add a trailing slash to /wp-admin" redirect should be the very first ruleset in the file and the target URL should include the protocol and domain name. That rule should be immediately followed with a non-www to www canonicalisation rule.
The new code may well run hundreds of times quicker.