Now I've written dozens of redirects in my time, some with tricky regex, some more tame, but today, the very simplest redirect is stumping me on a CentOS server, running Apache 2.2.3.
All I'd like to do is redirect every single request on an old domain, regardless of path and query string, to the front page only of a new site. This is why, for example, a mod_alias Redirect directive isn't appropriate, since it appends the path to the new address.
In an Apache conf file, where the virtual server is defined, I now have
<VirtualHost THE.IP.ADDRESS:80>
DocumentRoot "/var/www/html/SITE_ROOT"
ServerName OLD_DOMAIN.com
<Directory "/var/www/html/SITE_ROOT">
Options FollowSymLinks
RewriteEngine On
RewriteRule ^$ https://NEW_DOMAIN [R=301,L]
AllowOverride None
</Directory>
</VirtualHost>
While the redirect to https://NEW_DOMAIN occurs as expected, the path of the original request is always appended, leading to 404 errors on the new site.
For example, visiting http://OLD_DOMAIN.com/asdf
redirects to https://NEW_DOMAIN.com/asdf
...when I'd actually want to arrive at https://NEW_DOMAIN.com/
Why is the path being appended, even though I'm not collecting a pattern match, and am not specifying such a match in the destination?
There are plenty of answers like this on SO already:
Apache redirect to a clean URL
https://stackoverflow.com/a/11590814/1738274
But I can't find a discrepancy comparing these solutions against my own configuration. Any ideas?
RewriteRule ^(.*)$ https://NEW_DOMAIN [R=301,NC,L] should work. I have tested with various URLs and it always redirects to https://NEW_DOMAIN
My config structure looks a bit different:
<VirtualHost *:80>
ServerName OLD_DOMAIN.com
DocumentRoot "C:\Program Files (x86)\Apache Software Foundation\Apache2.2\htdocs"
<IfModule mod_rewrite.c>
RewriteEngine on
Options FollowSymLinks
RewriteRule ^(.*)$ https://NEW_DOMAIN [R=301,NC,L]
.......
.......
Related
I need every page request on a site -- 200, 404, etc. -- to land at a fixed page on the site, in this case index_new.php.
I've tried other SO and ServerFault answers and I continue to get an endless redirect loop.
Here's my code in httpd.conf:
<VirtualHost *:80>
ServerName my.example.com
ServerAlias *.my.example.com
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/index_new.php
RewriteRule ^(.*)$ /index_new.php [R=301,L]
</VirtualHost>
Notes:
the site's .htaccess file is empty
the "index_new.php" page is static with no PHP header("location:") internal redirects, etc.
I have restarted apache
A Negative lookahead should do, and can easily be done with a single line with RedirectMatch instead of using mod_rewrite:
RedirectMatch permanent ^/(?!index_new.php).* /index_new.php
Clear your browsers cache and/or try with curl -I http://my.example.com/wahtever to make sure it is working
For sanity specify documentroot in the virtualhost and a directory entry to allow access (Require all granted / Allow from all depending on the version) and since you are not using .htaccess (btw congratulations! you are one of the few doing things right from the start), set the directory of the DocumentRoot with "AllowOverride none" just to be safe.
I'm trying to slowly take over an existing website, route per route. I found Apache's Alias(Match) which seems to allow me to set a different (content) document root per request. But I'm failing with trailing slashes and more complex paths.
My goal now is to have the old website serve everything as it is used to. And to have a new website, serving a first specific request, say /foo and /foo/*.
I have my vhost setup like this:
<VirtualHost *:80>
ServerName example.com
UseCanonicalName on
AliasMatch ^/foo/(.*)$ /www/new/$1
AliasMatch ^/foo$ /www/new/$1
<Directory /www/new/>
Options +FollowSymLinks -MultiViews
AllowOverride All
Require all granted
</Directory>
DocumentRoot /www/old
<Directory /www/old/>
Options +FollowSymLinks -MultiViews
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
In both directories I have an .htaccess with:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php/$1 [L]
The index.php's show 'old' or 'new' depending on their directory.
What happens to the different routes I test:
When requesting example.com/bar it shows 'old'.
When requesting example.com/foo it redirects too /foo/, and then shows 'new'.
When requesting example.com/foo/bar it shows 'old'.
I don't want the forced redirect of /foo to /foo/. And I want /foo/bar to show 'new'.
I've been following Apache's mod_alias to get the multiple AliasMatch directives to catch anything after /foo but apparently that's not working correctly. Also, I don't read anything there of the trailing slash being added magically.
Anyone knows the magic tricks?
I've been able to fix this by adjusting the Alias to point to the index.php directly:
AliasMatch ^/foo/(.*)$ /www/new/index.php
AliasMatch ^/foo$ /www/new/index.php
Then /bar and anything else goes to the old website, and /foo, /foo/ and /foo/bar goes to the new website.
There's two downsides to this method:
The .htaccess in the new website is skipped completely. But as I mainly use that for letting the index.php pick up every route, that's fine for now.
Frontend resources like css/js go to the old website. Fix that with another simple alias: example.com/frontend/app.css + Alias /frontend /www/new/public_html/frontend.
I have a .htaccess file which (among other things) creates pretty urls. Here's a sample of part of the file:
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
...
# Pretty urls
RewriteRule ^home(\d+)*$ ./index.html
RewriteRule ^contact(\d+)*$ ./contact.html
RewriteRule ^enquire(\d+)*$ ./enquire.html
RewriteRule ^terms(\d+)*$ ./terms.html
RewriteRule ^about(\d+)*$ ./about.html
RewriteRule ^owners(\d+)*$ ./owners.html
I am currently moving the site to new hosting on digitalocean. When I test the site out by browsing the IP e.g.
111.222.333.444/html_docs/contact
the .htaccess file is working perfectly. Rewrite rules are on and the site properly rewrites the url and serves (in this case, contact.html) to the browser.
When I change the nameservers and browse the site by domain after propogation e.g.
mydomain.com/contact
the .htacces file fails to do the redirect, at least, it seems like it's not being seen at all. This is weird to me since it works when I'm browsing by ip. I purposely put some rubbish into the .htaccess to test if it was being picked up. Again, if I browse via the ip I get a 500 which I would expect, but when browsing by domain name I do not get an error but the rewrites don't work.
I'm banging my head at this stage and can't figure it out. Any help appreciated,
many thanks,
Wittner
Ok, this was less of a lack of knowledge about how .htaccess works and more to do with not configuring my vhosts settings properly.
<VirtualHost *:80>
ServerName mydomain.com
ServerAlias www.mydomain.com
ServerAdmin me#mydomain.com
DocumentRoot "/var/www/mydomain.com/html_docs/"
<Directory "/var/www/mydomain.com/html_docs/"> <-- Problem was here
Options Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from All
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
Turns out that in the tag I had left out the path to my domain root. So when I directly browsed the site via the IP the system was able to figure it out, but no while browsing. All my .htaccess stuff is now working. Thanks to all who looked and anyone who replied. Live and learn I guess :-)
cheers,
Wittner
I'm using Apache 2.4, and I set up two virtual directories. One requires SSL, and the other one redirects to it.
If a user attempts to visit https://www.derp.com/derp without /derp existing, they correctly get a 404. But when a user visits http://www.derp.com/derp, Apache incorrectly redirects the user to https://www.derp.comderp, removing the slash between the path and the domain name.
I have no idea what would be causing this.
The following is the setup of my Virtual Host.
<VirtualHost *:443>
ServerAdmin derp#derp.com
ServerName www.derp.com
ServerAlias derp.com
DocumentRoot "C:\Users\derp\Documents\Web Projects\derp"
SSLEngine on
SSLCertificateFile "C:\Apache24\certs\cert.cer"
SSLCertificateKeyFile "C:\Apache24\certs\key.key"
</VirtualHost>
<VirtualHost *:80>
ServerAdmin derp#derp.com
ServerName www.derp.com
ServerAlias derp.com
Redirect permanent / https://www.derp.com/
</VirtualHost>
<Directory "C:\Users\derp\Documents\Web Projects\derp">
Options Indexes FollowSymLinks Includes ExecCGI
AllowOverride All
Require all granted
SSLRequireSSL
</Directory>
Why would Apache be behaving this way?
Bonus Question: Should redirects be handled in my virtual host definition, or should it be handled in the .htaccess file in the web site's physical directory?
Edit:
I'm starting a Laravel project, and by default the public folder does contain a .htaccess file, so here's that guy:
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
Edit Two:
I tried:
adding a slash at the end of the DirectoryRoot path
replacing the backslashes with forward slashes in the DirectoryRoot path
replacing the backslashes with double backslashes in the DirectoryRoot path
I also removed the .htaccess file from the directory completely.
It redirects correctly when you go from http://www.derp.com to https://www.derp.com. It's just when you specify a path and attempt https that it removes the slash between the domain and the path.
Edit Three:
I also attempted the following suggestion:
Redirect permanent / https://www.derp.com/
Try
RedirectMatch permanent /(.*) https://www.derp.com/$1
or
RedirectMatch permanent (.*) https://www.derp.com/$1
... and instead of redirecting to https://www.derp.comderp, it instead does not redirect, attempts and gives a 404 for http://www.derp.com/derp, but using Apache's 404, instead of throwing a Not Found Exception, as Laravel does without configuration.
Edit Four:
I have also tried:
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
In the .htaccess file and the behavior did not change at all.
I got it.
The issue did not lay with the rewriting at all, it was the SSLRequireSSL directive under my Directory definition that was causing the problem.
I simply removed this directive, refreshed the cache in all of my browsers, and the site then continued to work correctly. This was discovered through the process of elimination.
The documentation notes:
This directive forbids access unless HTTP over SSL (i.e. HTTPS) is enabled for the current connection. This is very handy inside the SSL-enabled virtual host or directories for defending against configuration errors that expose stuff that should be protected. When this directive is present all requests are denied which are not using SSL.
The emphasis is my own. SSLRequireSSL may have Apache only return a 403 or 404 if HTTP over SSL is not enabled, interfering with the Redirect rule. A rewrite rule such as the one in this answer on Server Fault may be a better alternative depending on your use case:
RewriteEngine On
RewriteCond %{SERVER_PORT} !443
RewriteRule ^(/(.*))?$ https://%{HTTP_HOST}/$1 [R=301,L]
My issue was related to browser caching.
I tried it in a different browser and it worked and then tried again in a private session in the first browser and it also worked.
I've correctly configured my website to re-route every piece of traffic from
mywonderfulwebsite.com/folder1/whatever-url.php
to
http://folder1.mywonderfulwebsite.com/whatever-url-as-above.php
Question is: many times, an external website links the page with GET parameters, for example
mywonderfulwebsite.com/folder1/whatever-url.php*?trackingToken=1*
So, question is how to make the mod_rewrite pass in the GET parameters to the "rewrited" url, like this:
folder1.mywonderfulwebsite.com/whatever-url-as-above.php*?trackingToken=1*
Currently, I'm doing the following:
<VirtualHost *>
ServerName mywonderfulwebsite.com
ServerAlias www.mywonderfulwebsite.com
DocumentRoot /var/www/mywonderfulwebsite/
DirectoryIndex index.html
<Directory />
allow from all
Options +FollowSymlinks -Indexes
</Directory>
RewriteEngine On
RewriteRule ^/folder1/(.*)?$ http://folder1.mywonderfulwebsite.com/$1&%{QUERY_STRING} [L,R=301]
</VirtualHost>
This piece of htaccess is awful: for example, trying to access this url:
www.mywonderfulwebsite.com/folder1/atextfile.txt
Redirects to
folder1.mywonderfulwebsite.com/atextfile.txt&
In fact, the mod_rewrite appends the trailing &
How do I fix this issue? How to correctly redirecting to the correct ( also with GET parameters ) url?
Many thanks
Just add the [QSA] flag to your other flags to have the [Q]uery [S]tring [A]ppended automatically.
[L,R=301,QSA]