Silverstripe htaccess - .htaccess

I have a Silverstripe platform website that has duplicate URLs for www, non-www, http and https
There seem to be multiple solutions but no definitive answer. Is there someone that knows the correct code for the htaccess file for Silverstripe?
I want to get all pages pointing to https ://www
This is the current code in the htaccess file -
ErrorDocument 401 /base/401.txt
### SILVERSTRIPE START ###
# Deny access to templates (but allow from localhost)
<Files *.ss>
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Files>
# Deny access to IIS configuration
<Files web.config>
Order deny,allow
Deny from all
</Files>
# Deny access to YAML configuration files which might include sensitive information
<Files ~ "\.ya?ml$">
Order allow,deny
Deny from all
</Files>
# Route errors to static pages automatically generated by SilverStripe
ErrorDocument 404 /assets/error-404.html
ErrorDocument 500 /assets/error-500.html
<IfModule mod_env.c>
# Ensure that X-Forwarded-Host is only allowed to determine the request
# hostname for servers ips defined by SS_TRUSTED_PROXY_IPS in your _ss_environment.php
# Note that in a future release this setting will be always on.
SetEnv BlockUntrustedIPs true
</IfModule>
<IfModule mod_rewrite.c>
# Turn off index.php handling requests to the homepage fixes issue in apache >=2.4
<IfModule mod_dir.c>
DirectoryIndex disabled
</IfModule>
RewriteEngine On
# non-www to www redirect
#RewriteCond %{HTTP_HOST} ^bolstered.com.au$ [NC]
#RewriteRule (.*) https://www.bolstered.com.au/$1 [R=301,L]
# http to https redirect
#RewriteCond %{HTTPS} !=on
#RewriteRule ^ (.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Enable HTTP Basic authentication workaround for PHP running in CGI mode
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Deny access to potentially sensitive files and folders
RewriteRule ^vendor(/|$) - [F,L,NC]
RewriteRule silverstripe-cache(/|$) - [F,L,NC]
RewriteRule composer\.(json|lock) - [F,L,NC]
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !\.php$
RewriteRule .* index.php?url=%1&%{QUERY_STRING} [L]
</IfModule>
### SILVERSTRIPE END

I typically keep the SilverStripe part between ### SILVERSTRIPE START ### and ### SILVERSTRIPE END ### untouched and put my rules only before or after those of silverstripe.
There is no issue with having RewriteEngine On twice.
I also did not bother to check if mod_rewrite exists, because all my servers will have it enabled and I wouldn't let a client put it on a server without it.
Here is a full example of a .htaccess that I would typically use in silverstripe a project:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^localhost [NC]
RewriteCond %{HTTP_HOST} !^127.0.0.1 [NC]
RewriteCond %{HTTPS} !on [OR]
RewriteCond %{HTTP_HOST} !^www\.examle\.org [NC]
RewriteRule ^ https://www.examle.org%{REQUEST_URI} [R=301,L]
### SILVERSTRIPE START ###
# Deny access to templates (but allow from localhost)
<Files *.ss>
Require ip 127.0.0.1
</Files>
# Deny access to IIS configuration
<Files web.config>
Require all denied
</Files>
# Deny access to YAML configuration files which might include sensitive information
<Files ~ "\.ya?ml$">
Require all denied
</Files>
# Route errors to static pages automatically generated by SilverStripe
ErrorDocument 404 /assets/error-404.html
ErrorDocument 500 /assets/error-500.html
<IfModule mod_rewrite.c>
# Turn off index.php handling requests to the homepage fixes issue in apache >=2.4
<IfModule mod_dir.c>
DirectoryIndex disabled
DirectorySlash On
</IfModule>
SetEnv HTTP_MOD_REWRITE On
RewriteEngine On
# Enable HTTP Basic authentication workaround for PHP running in CGI mode
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Deny access to potentially sensitive files and folders
RewriteRule ^vendor(/|$) - [F,L,NC]
RewriteRule ^\.env - [F,L,NC]
RewriteRule silverstripe-cache(/|$) - [F,L,NC]
RewriteRule composer\.(json|lock) - [F,L,NC]
RewriteRule (error|silverstripe|debug)\.log - [F,L,NC]
RewriteRule ^Security - [F,L,NC]
# Process through SilverStripe if no file with the requested name exists.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php
</IfModule>
### SILVERSTRIPE END ###
Step-by-step explanation:
Turns on the rewrite engine
RewriteEngine On
The 4 RewriteCond are all conditions connected to the RewriteRule below it.
RewriteCond %{HTTP_HOST} !^localhost [NC]
RewriteCond %{HTTP_HOST} !^127.0.0.1 [NC]
RewriteCond %{HTTPS} !on [OR]
RewriteCond %{HTTP_HOST} !^www\.examle\.org [NC]
Multiple conditions will be a logical AND, unless you add a [OR].
[NC] stands for no-case, so not case-sensitive
The first 2 are an exception for localhost/127.0.0.1 to ensure a redirect will not be done when I am developing on my workstation.
3 is checking if https if off
4 is checking if the domain is correct
So speaking in pseudo code, it's like this:
if ($HTTP_HOST != "localhost" && $HTTP_HOST != "127.0.0.1" AND ($HTTPS != "on" OR $HTTP_HOST != "www.examle.org") {
do_redirect();
}
The actual redirect
RewriteRule ^ https://www.examle.org%{REQUEST_URI} [R=301,L]
It's redirecting to the desired domain and attaches the path (/foo/bar) and the query paramters (?foo=bar) to it.
R=301 is the http response code. If you wanted a temporary redirect you could make it 302.
L means Last I think, which will stop the processing at this point and will not continue to try other rules below.
Alternatives:
.htaccess is the best way to do it. But it's worth pointing out that this is not the only option.
You could do it in plain PHP, in the config of any/most webservers, ...
And SilverStripe has builtin methods for doing the check & redirect:
Director::forceSSL();
Director::forceWWW();
but as said, .htaccess is much better (much faster and only a single redirect)

Related

Codeigniter4 Shared web hosting. Issue with configuring URLs

here is the thing. localhost development works fine. as I move to shared hosting try to configure codeigniter4 I'm facing issues with routes.
I use softaculouse to install CI4 on the main directory (public_html). when I try to configure the routes things work fine except
when I write the domain name.
example
https://example.com/ (Issue) it will send me to https://example.com/public/ (Code 500)
I contacted support they claim the issue in public folder I'm not allowed to add .htaccess so they deleted it for me .htaccess file in public. things work fine. however; when I write https://example.com/ works but the URL in the address bar changes to https://example.com/public
How to remove /public ?
is it a .htaccess configuration?
is it an issue with Apache configuration from hosting company side?
by the way
https://example.com/home (No problem)
https://example.com/en (No Problem) after modifying routes using {locale}
htaccess in public_html
# To prevent access to .env and other files
<Files .*>
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
</Files>
<IfModule mod_alias.c>
RedirectMatch 301 ^/$ https://example.com/public
</IfModule>
This is htaccess which initially was generated inside public folder (Its standard generated by composer i think)
# Disable directory browsing
Options All -Indexes
# ----------------------------------------------------------------------
# Rewrite engine
# ----------------------------------------------------------------------
# Turning on the rewrite engine is necessary for the following rules and features.
# FollowSymLinks must be enabled for this to work.
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine On
# If you installed CodeIgniter in a subfolder, you will need to
# change the following line to match the subfolder you need.
# http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase
# RewriteBase /
# Redirect Trailing Slashes...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Rewrite "www.example.com -> example.com"
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
# Checks to see if the user is attempting to access a valid file,
# such as an image or css document, if this isn't true it sends the
# request to the front controller, index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([\s\S]*)$ index.php/$1 [L,NC,QSA]
# Ensure Authorization header is passed along
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
<IfModule !mod_rewrite.c>
# If we don't have mod_rewrite installed, all 404's
# can be sent to index.php, and everything works as normal.
ErrorDocument 404 index.php
</IfModule>
# Disable server signature start
ServerSignature Off
# Disable server signature end

Apache2 rewrite condition with https

I have 2 .htacces file
/usr/local/apache2/htdocs .htacess file with
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteCond %{REQUEST_URI} !^/test2/
RewriteRule ^(.*)$ /test2/$1 [NC,QSA]
/usr/local/apache2/htdocs/test2 .htacess file with
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
RewriteRule !^(ui/|index.php|favicon.ico) - [F,L,NC]
#RewriteCond %{HTTPS} off
#RewriteCond %{REQUEST_URI} !^/admin
#RewriteRule .* https://%{HTTP_HOST}%/admin [L,R=301]
</IfModule>
The application will force the application to the url below while hiding the index.php
http://www.example.com/admin
additionally there is another link with http://www.example.com/display
default directory configured in httpd.conf are :
DocumentRoot "/usr/local/apache2/htdocs/test2"
<Directory "/usr/local/apache2/htdocs/test2"
However if I try to run with https the link
https://www.example.com/admin
I will get this error :
Forbidden
You don't have permission to access /admin/ on this server.
I have tried using the #commented code and still has error. Please help
These problem were fix by applying
I have found out that there are another file, ssl.conf that has a DocumentRoot, fix the problem via adding the same document root in ssl.conf
DocumentRoot "/usr/local/apache2/htdocs/test2"
<Directory "/usr/local/apache2/htdocs/test2"
and
Change a file php.conf to (# was the old code)
# Depreciated in Apache 2.2
# Order allow,deny
# Deny from all
# Satisfy All
# New in Apache 2.4
<RequireAll>
Require valid-user Require ip 127.0.0.1
</RequireAll>

RewriteRule ^ index.php [L] affecting 301 redirect

I have a Drupal 7 website with several 301 redirects, however we've recently noticed an odd issue... When typing the url into your browser, it will not work if you include www.
www.example.com/something redirects to https://www.example.com/index.php
Using https://wheregoes.com/retracer.php the results for the above are:
http://www.example.com/something
301 Redirect -> http://www.example.com/here/something
301 Redirect -> https://www.example.com/index.php
example.com/someting will redirect correctly to https://www.example.com/here/something
Using https://wheregoes.com/retracer.php the results for the above are:
http://example.com/something
301 Redirect -> https://www.example.com/something
301 Redirect -> https://www.example.com/here/something
https://www.example.com/here/something is the expected endpoint.
From digging in my htaccess the issue appears to be with the standard Drupal 7 RewriteRule ^ index.php [L] line; however if I remove this I cannot log into the admin area.
Any thoughts on how this can be resolved? The SSL is only installed on www.example.com, so we need to redirect users to www.example.com and apply the SSL there. example.com has no SSL and unfortunately we cannot control this.
Below is my htaccess file:
#
# Apache/PHP/Drupal settings:
#
# Protect files and directories from prying eyes.
<FilesMatch "\.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^(\.(?!well-known).*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock))$|^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig\.save)$">
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
<IfModule !mod_authz_core.c>
Order allow,deny
</IfModule>
</FilesMatch>
# Don't show directory listings for URLs which map to a directory.
Options -Indexes
# Follow symbolic links in this directory.
Options +FollowSymLinks
# Make Drupal handle any 404 errors.
ErrorDocument 404 /index.php
# Set the default handler.
DirectoryIndex index.php index.html index.htm
# Override PHP settings that cannot be changed at runtime. See
# sites/default/default.settings.php and drupal_environment_initialize() in
# includes/bootstrap.inc for settings that can be changed at runtime.
# PHP 5, Apache 1 and 2.
<IfModule mod_php5.c>
php_flag magic_quotes_gpc off
php_flag magic_quotes_sybase off
php_flag register_globals off
php_flag session.auto_start off
php_value mbstring.http_input pass
php_value mbstring.http_output pass
php_flag mbstring.encoding_translation off
</IfModule>
# Requires mod_expires to be enabled.
<IfModule mod_expires.c>
# Enable expirations.
ExpiresActive On
# Cache all files for 2 weeks after access (A).
ExpiresDefault A1209600
<FilesMatch \.php$>
# Do not allow PHP scripts to be cached unless they explicitly send cache
# headers themselves. Otherwise all scripts would have to overwrite the
# headers set by mod_expires if they want another caching behavior. This may
# fail if an error occurs early in the bootstrap process, and it may cause
# problems if a non-Drupal PHP file is installed in a subdirectory.
ExpiresActive Off
</FilesMatch>
</IfModule>
# Various rewrite rules.
<IfModule mod_rewrite.c>
RewriteEngine on
# Set "protossl" to "s" if we were accessed via https://. This is used later
# if you enable "www." stripping or enforcement, in order to ensure that
# you don't bounce between http and https.
RewriteRule ^ - [E=protossl]
RewriteCond %{HTTPS} on
RewriteRule ^ - [E=protossl:s]
# Make sure Authorization HTTP header is available to PHP
# even when running as CGI or FastCGI.
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Block access to "hidden" directories whose names begin with a period. This
# includes directories used by version control systems such as Subversion or
# Git to store control files. Files whose names begin with a period, as well
# as the control files used by CVS, are protected by the FilesMatch directive
# above.
#
# NOTE: This only works when mod_rewrite is loaded. Without mod_rewrite, it is
# not possible to block access to entire directories from .htaccess, because
# <DirectoryMatch> is not allowed here.
#
# If you do not have mod_rewrite installed, you should remove these
# directories from your webroot or otherwise protect them from being
# downloaded.
RewriteRule "/\.|^\.(?!well-known/)" - [F]
# If your site can be accessed both with and without the 'www.' prefix, you
# can use one of the following settings to redirect users to your preferred
# URL, either WITH or WITHOUT the 'www.' prefix. Choose ONLY one option:
#
# To redirect all users to access the site WITH the 'www.' prefix,
# (http://example.com/... will be redirected to http://www.example.com/...)
# uncomment the following:
# RewriteCond %{HTTP_HOST} .
# RewriteCond %{HTTP_HOST} !^www\. [NC]
# RewriteRule ^ http%{ENV:protossl}://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
#
# To redirect all users to access the site WITHOUT the 'www.' prefix,
# (http://www.example.com/... will be redirected to http://example.com/...)
# uncomment the following:
# RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
# RewriteRule ^ http%{ENV:protossl}://%1%{REQUEST_URI} [L,R=301]
# Modify the RewriteBase if you are using Drupal in a subdirectory or in a
# VirtualDocumentRoot and the rewrite rules are not working properly.
# For example if your site is at http://example.com/drupal uncomment and
# modify the following line:
# RewriteBase /drupal
#
# If your site is running in a VirtualDocumentRoot at http://example.com/,
# uncomment the following line:
# RewriteBase /
# Pass all requests not referring directly to files in the filesystem to
# index.php. Clean URLs are handled in drupal_environment_initialize().
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^ index.php [L]
# Rules to correctly serve gzip compressed CSS and JS files.
# Requires both mod_rewrite and mod_headers to be enabled.
<IfModule mod_headers.c>
# Serve gzip compressed CSS files if they exist and the client accepts gzip.
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.css $1\.css\.gz [QSA]
# Serve gzip compressed JS files if they exist and the client accepts gzip.
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.js $1\.js\.gz [QSA]
# Serve correct content types, and prevent mod_deflate double gzip.
RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1]
RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1]
<FilesMatch "(\.js\.gz|\.css\.gz)$">
# Serve correct encoding type.
Header set Content-Encoding gzip
# Force proxies to cache gzipped & non-gzipped css/js files separately.
Header append Vary Accept-Encoding
</FilesMatch>
</IfModule>
</IfModule>
# Add headers to all responses.
<IfModule mod_headers.c>
# Disable content sniffing, since it's an attack vector.
Header always set X-Content-Type-Options nosniff
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine on
Redirect 301 /examplelink.php /example-link
Redirect 301 /someoldlink.php /new/location
Redirect 301 /something /here/something
</IfModule>
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
The problem you are probably having is that your 301 redirects are happening after your internal routing to the index.php page. Additionally, you're using the Redirect directive, which is mod_alias and not part of mod_rewrite. This means the same request gets processed twice, once by mod_alias and once by mod_rewrite. This is making it so an internal rewrite (to index.php) ends up getting redirected because mod_alias marked the request for a 301.
Remove these lines from the bottom of your .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine on
Redirect 301 /examplelink.php /example-link
Redirect 301 /someoldlink.php /new/location
Redirect 301 /something /here/something
</IfModule>
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Then under the first mod_rewrite block, which looks like this:
# Various rewrite rules.
<IfModule mod_rewrite.c>
RewriteEngine on
Add these lines under RewriteEngine on:
RewriteRule ^examplelink\.php$ /example-link [L,R=301]
RewriteRule ^someoldlink\.php$ /new/location [L,R=301]
RewriteRule ^something$ /here/something [L,R=301]
RewriteCond %{HTTPS} !on
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

.htaccess redirect from domain.org/sub to sub.domain.org/ not working

I'm trying to get aphdigital.org/GVH/ to redirect to gvh.aphdigital.org, and aphdigital.org/GVH/something/ to gvh.aphdigital.org/something/ but I'm having quite a lot of difficulty. I tried the code from this question, but it's not working. The commented-out code blocks below also show failed attempts at a redirect. What am I doing wrong? I would enable logging if I had access to httpd.conf, but I only have FTP access. I know apache is reading this file, because syntax errors seem to cause 500 errors.
Here's my .htaccess file:
# Remember to enable display_errors on development environments only.
<IfModule mod_php5.c>
php_value display_errors 1
php_flag register_globals off
</IfModule>
RewriteEngine on
# If know that mod_rewrite is enabled, but you are still getting mod_rewrite errors,
# uncomment the line below and replace "/" with your base directory.
# RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^admin/ - [C]
RewriteRule .* admin/index.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php
# Added this on Jan. 4, 2013 to redirect from old URL to new. Doesn't seem to be working.
RewriteCond %{HTTP_HOST} ^www.aphdigital.org/GVH$
RewriteCond %{HTTP_HOST} ^www\.aphdigital\.org/GVH$
RewriteRule ^gvh/(.*)$ http://gvh.aphdigital.org/$1 [L,QSA,R=301]
# End of Jan. 4 add.
#TEST for redirect added April 3. Also doesn't work.
# To redirect /mysub/foo to http://mysub.mysite.co.uk/foo
#RewriteCond %{HTTP_HOST} ^(www\.)?(aphdigital\.org)$ [NC]
#RewriteRule ^(gvh)/?(.*)$ http://$1.%2/$2 [R=301,L,NC]
#TEST2, code from Stackoverflow question
#Options +FollowSymLinks -MultiViews
#RewriteEngine on
#RewriteBase /
# To redirect http:://www.mysite.co.uk/ to http:://mysite.co.uk/
#RewriteCond %{HTTP_HOST} ^www\.(aphdigital\.org)$ [NC]
#RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
# To redirect /mysub/foo to http://mysub.mysite.co.uk/foo
#RewriteCond %{HTTP_HOST} ^(www\.)?(aphdigital\.org)$ [NC]
#RewriteRule ^(gvh)/?(.*)$ http://$1.%2/$2 [R=301,L,NC]
#END TEST 2
#Intentionally breaking to see if reading .htaccess. Yep, this breaks it.
#<directory / ></directory>
<FilesMatch "\.(php|ini)$">
Order Allow,Deny
Deny from all
</FilesMatch>
<Files index.php>
Allow from all
</Files>
# Uncomment the lines below in order to enable caching of some files via Apache (after a finished site has gone live)
<IfModule mod_expires.c>
# <FilesMatch "\.(js|ico|gif|jpg|png|css)$">
# ExpiresActive on
# ExpiresDefault "access plus 10 day"
# </FilesMatch>
</IfModule>
This is for a site running the Omeka CMS.
The URL path GVH is not part of %{HTTP_HOST}, so this should be
RewriteCond %{HTTP_HOST} ^(?:www\.)?aphdigital\.org$
RewriteRule ^gvh/(.*)$ http://gvh.aphdigital.org/$1 [R,L,NC]
Never test with 301 enabled, see this answer Tips for debugging .htaccess rewrite rules for details.

Redirect top-level domain except for one page in Drupal

I have two top-level domains pointing to my Drupal installation, abc.com and xyz.com.
I'd like to force all pages to use abc.com, EXCEPT for one page (node), which should always use xyz.com.
I've tried a bunch of different .htaccess, none seem to work. This is the closest I've gotten:
# Redirect abc.com/path/to/my/page to xyz.com/path/to/my/page
RewriteCond %{HTTP_HOST} ^(www\.)?abc\.com$ [NC]
RewriteRule ^path/to/my/page$ http://www.xyz.com$1 [R,L,NC]
# Redirect xyz.com to www.abc.com
RewriteCond %{HTTP_HOST} ^(www\.)?xyz\.com$ [NC]
RewriteRule ^ http://www.abc.com%{REQUEST_URI} [R,L]
The above works for the whole site redirect, but when you go to abc.com/path/to/my/page it redirects to the main page, abc.com. I also tried this:
# Redirect abc.com/path/to/my/page to xyz.com/path/to/my/page
RewriteCond %{HTTP_HOST} ^(www\.)?abc\.com$ [NC]
RewriteRule ^path/to/my/page$ http://www.xyz.com/path/to/my/page [R,L,NC]
But that just gave me an error about too many redirects to xyz.com/path/to/my/page.
Any ideas? I'm not sure if my .htaccess code is wrong, or if it has to do with Drupal's clean URL functions, or what.
Here's the full Drupal .htaccess file:
#
# Apache/PHP/Drupal settings:
#
# Protect files and directories from prying eyes.
<FilesMatch "\.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)$|^(\..*|Entries.*|Repository|Root|Tag|Template)$">
Order allow,deny
</FilesMatch>
# Don't show directory listings for URLs which map to a directory.
Options -Indexes
# Follow symbolic links in this directory.
Options +FollowSymLinks
# Make Drupal handle any 404 errors.
ErrorDocument 404 /index.php
# Set the default handler.
DirectoryIndex index.php index.html index.htm
# Override PHP settings that cannot be changed at runtime. See
# sites/default/default.settings.php and drupal_initialize_variables() in
# includes/bootstrap.inc for settings that can be changed at runtime.
# PHP 5, Apache 1 and 2.
<IfModule mod_php5.c>
php_flag magic_quotes_gpc off
php_flag magic_quotes_sybase off
php_flag register_globals off
php_flag session.auto_start off
php_value mbstring.http_input pass
php_value mbstring.http_output pass
php_flag mbstring.encoding_translation off
</IfModule>
# Requires mod_expires to be enabled.
<IfModule mod_expires.c>
# Enable expirations.
ExpiresActive On
# Cache all files for 2 weeks after access (A).
ExpiresDefault A1209600
<FilesMatch \.php$>
# Do not allow PHP scripts to be cached unless they explicitly send cache
# headers themselves. Otherwise all scripts would have to overwrite the
# headers set by mod_expires if they want another caching behavior. This may
# fail if an error occurs early in the bootstrap process, and it may cause
# problems if a non-Drupal PHP file is installed in a subdirectory.
ExpiresActive Off
</FilesMatch>
</IfModule>
# Various rewrite rules.
<IfModule mod_rewrite.c>
RewriteEngine on
# Redirect abc.com/path/to/my/page to xyz.com/path/to/my/page
RewriteCond %{HTTP_HOST} ^(www\.)?abc\.com$ [NC]
RewriteRule ^(path/to/my/page)$ http://www.xyz.com/$1 [R=302,L,NC]
# Redirect xyz.com to www.abc.com (except for /path/to/my/page)
RewriteCond %{REQUEST_URI} !^/path/to/my/page$ [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?xyz\.com$ [NC]
RewriteRule ^ http://www.abc.com%{REQUEST_URI} [R=302,L]
# Block access to "hidden" directories whose names begin with a period. This
# includes directories used by version control systems such as Subversion or
# Git to store control files. Files whose names begin with a period, as well
# as the control files used by CVS, are protected by the FilesMatch directive
# above.
#
# NOTE: This only works when mod_rewrite is loaded. Without mod_rewrite, it is
# not possible to block access to entire directories from .htaccess, because
# <DirectoryMatch> is not allowed here.
#
# If you do not have mod_rewrite installed, you should remove these
# directories from your webroot or otherwise protect them from being
# downloaded.
RewriteRule "(^|/)\." - [F]
# If your site can be accessed both with and without the 'www.' prefix, you
# can use one of the following settings to redirect users to your preferred
# URL, either WITH or WITHOUT the 'www.' prefix. Choose ONLY one option:
#
# To redirect all users to access the site WITH the 'www.' prefix,
# (http://example.com/... will be redirected to http://www.example.com/...)
# uncomment the following:
# RewriteCond %{HTTP_HOST} !^www\. [NC]
# RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
#
# To redirect all users to access the site WITHOUT the 'www.' prefix,
# (http://www.example.com/... will be redirected to http://example.com/...)
# uncomment the following:
# RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
# RewriteRule ^ http://%1%{REQUEST_URI} [L,R=301]
# Modify the RewriteBase if you are using Drupal in a subdirectory or in a
# VirtualDocumentRoot and the rewrite rules are not working properly.
# For example if your site is at http://example.com/drupal uncomment and
# modify the following line:
# RewriteBase /drupal
#
# If your site is running in a VirtualDocumentRoot at http://example.com/,
# uncomment the following line:
# RewriteBase /
#custom redirects (there are lots of these, all are specific paths used on an old site mapped to their respective pages on the new, reorganized site)
RewriteRule ^specific/old/path/$ http://www.abc.com/corresponding/new/path [R=301,L]
#end custom redirects
# Pass all requests not referring directly to files in the filesystem to
# index.php. Clean URLs are handled in drupal_environment_initialize().
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^ index.php [L]
# Rules to correctly serve gzip compressed CSS and JS files.
# Requires both mod_rewrite and mod_headers to be enabled.
<IfModule mod_headers.c>
# Serve gzip compressed CSS files if they exist and the client accepts gzip.
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.css $1\.css\.gz [QSA]
# Serve gzip compressed JS files if they exist and the client accepts gzip.
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.js $1\.js\.gz [QSA]
# Serve correct content types, and prevent mod_deflate double gzip.
RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1]
RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1]
<FilesMatch "(\.js\.gz|\.css\.gz)$">
# Serve correct encoding type.
Header set Content-Encoding gzip
# Force proxies to cache gzipped & non-gzipped css/js files separately.
Header append Vary Accept-Encoding
</FilesMatch>
</IfModule>
</IfModule>
Your code generates a loop. abc.com/path/to/my/page redirect to xyz.com/path/to/my/page, but all xyz urls are redirect to abc.com, so it would redirect back to abc.com/path/to/my/page, over and over again.
# Redirect abc.com/path/to/my/page to xyz.com/path/to/my/page
RewriteCond %{HTTP_HOST} ^(www\.)?abc\.com$ [NC]
RewriteRule ^(path/to/my/page)$ http://www.xyz.com/$1 [R=302,L,NC]
# Redirect xyz.com to www.abc.com (except for /path/to/page)
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} !^/path/to/my/page$ [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?xyz\.com$ [NC]
RewriteRule ^ http://www.abc.com%{REQUEST_URI} [R=302,L]
The rule in your first code was incorrect, redirecting abc.com/path/to/my/page to abc.com/ (and that didn't create a loop).
RewriteRule ^path/to/my/page$ http://www.xyz.com$1 [R,L,NC]
This was because $1 reference to the first pair of parentheses, but you didn't have any. Secondly you needed to add a / before it, or it would redirect to xyz.compath/to/my/page
If this "page" is a file, then you might need to do it this way. I used this to keep all Drupal files served from the original server, then forward all non-file traffic to the new site.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/files/.* [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?iradvocates\.org$ [NC]

Resources