.htaccess rules being ignored - apache

I have the below in a .htaccess file. The SSL redirect is working perfectly, however when I got to abc.html I get a 404. The test.html page exists and works if I go directly to it.
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteRule ^abc\.html$ /test.html [L]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.org/$1 [R,L]
Rewrite rules were all working as expected with a much longer list of rules previously. After updating the primary domain in cPanel they stopped working and have reduced it down to this minimal example.

Appears there was a configuration error in the httpd.conf generated by cPanel when the domain was updated. Forcing cPanel to regenerate the conf files fixed the issue.

Related

apache apply rewrite rules to only one subdirectory

I have the following directory structure:
/var/www/html
--myapp
--phpmyadmin
In the /var/www/html folder there is a .htaccess file with following content:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^mydomain.sk$ [NC,OR]
RewriteCond %{HTTP_HOST} ^www.mydomain.sk$
RewriteCond %{REQUEST_URI} !myapp/public
RewriteRule (.*) /myapp/public/$1 [L]
If I access the http://mydomain.sk the rewrite rules work as expected and I get the myapp/public/index.php file as root. However, if I want to access http://mydomain.sk/phpmyadmin the request is redirected to http://mydomain/myapp/public/phpmyadmin. Here I get the error 404 - page not found.
I cannot find a way to only serve http://mydomain.sk/myapp/public as a root folder and to serve http://mydomain.sk/phpmyadmin "as is".
It took some time to figure this one out. The rules posted above actually work as expected. It turns out I had another set of rewrite rules in apache2.conf file (that I totally forgot about) that took precedence over my .htaccess file.

Directory index page precedes htaccess

What I want is that only if my root domain is accessed meaning URI is empty, it gets rewritten without redirect, otherwise rewrite to index.php if not accessing file or folder. My .htaccess looks like this:
RewriteEngine On
RewriteBase /
RewriteRule ^/?$ /mypages/landing_page.html [QSA,L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
It works as expected on some servers but on another it works only if there is no index.php file in folder. Something like directory indexing preceding htaccess rules? If I delete the index.php or rename it to index2.php and change my htaccess rules accordingly rewrite works as expected.
Any ideas what might be causing the server to behave like that?
There was a bug introduced in Apache 2.4.2 (#53929) that has the same symptom you're describing:
"The issue is caused by the DirectoryIndex directive. mod_dir is not
respecting the result of the rewrite execution. If DirectoryIndex is
set to disabled, it starts working correctly."
The issue is fixed in Apache 2.4.9.
If you have a mixed environment (i.e. pre and post Apache 2.4.2 versions), this could also explain why your Rewrite is working correctly on some servers, but not others.
If upgrading is not an option, you can also workaround the issue using a conditional SetHandler (based on an env var set in your RewriteRule). This will disable DirectoryIndex for just those requests.
The bug itself (and workaround example) is documented in the following link:
https://bz.apache.org/bugzilla/show_bug.cgi?id=53929

Changes to RewriteRule in .htaccess not taking effect

I had this rewrite rule set up in .htaccess and it was all working fine...
Options +FollowSymLinks +ExecCGI
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/mypage(.*)$ [NC]
RewriteRule ^(.*) http://example.com/PHProxy/poxy-0.5b2/index.php?url=http://example.org/mypage [L,R=302,NC]
However, when I change the url in the RewriteRule to
http://example.com/PHProxy/poxy-0.5b2/index.php?url=http://example.org/mypage it still redirects to the old URL.
After some research, I added a syntax error into the .htaccess file to check the .htaccess file was being used (and indeed it was - as it resulted in an Internal Server Error when you tried to load a page from that directory).
There seems to be some caching somewhere, but I'm not sure. Any ideas why my change is not being picked up / how to troubleshoot and resolve?
Problem solved. Just noticed that there is a mypage subdirectory which still contained the old rewrite rule, so that was the one being executed.

Using .htaccess file to redirect to a subdomain

In my root folder, I have a home directory. I'd like all requests for mydomain.com or www.mydomain.com to be forwarded to home.mydomain.com. In my cPanel, I have already set up the sub-domain home.mydomain.com to point to mydomain.com/home.
Here's what I currently have in my .htaccess file:
RewriteEngine On
Options +SymLinksIfOwnerMatch
RewriteRule ^(.*)$ \/home\/$1 [L]
This successfully forwards mydomain.com and www.mydomain.com to mydomain.com/home or www.mydomain.com/home, respectively. But home.mydomain.com/filename gives me an internal server error, instead of serving the file at mydomain.com/home/filename.
I'm not sure I understand the exact requirements, but it seems you want to rewrite all (www.)mydomain.com requests to the /home directory while your subdomain home.mydomain.com already points to that directory and thus should be exempt from that rewrite directive. If for some reason (www.)mydomain.com can't be set up to point to /home as well, you'd need a Rewrite Condition, something like
RewriteEngine On
Options +SymLinksIfOwnerMatch
RewriteCond %{HTTP_HOST} ^(www\.)?mydomain\.com$ [NC]
RewriteRule ^(.*)$ /home/$1 [L]
I also removed the backslashes which should not be needed. You can use the htaccess tester to check rewrite rules easily online.

.htaccess require SSL for a particular URL

I want to force Apache to use HTTPS for a particular URL in the following form:
https://www.example.com/signup/*
so
if someone goes to any of the following example URLs directly, Apache will forward the URL over to the HTTPS equivalent site.
e.g.
http://www.example.com/signup --> https://www.example.com/signup
http://www.example.com/signup/basic+plan --> https://www.example.com/signup/basic+plan
http://www.example.com/signup/premium --> https://www.example.com/signup/premium
Anyone know how?
Thanks in advance
Thank Murat,
Yours almost worked but figured out how to get it to exactly work.
The following is what works:
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} ^/somefolder/?
RewriteRule ^(.*)$ https://www.domain.com/$1 [R,L]
Notice that I didn't include somefolder in the www.domain.com rewriterule
I think this was what i used:
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} ^/somefolder/?
RewriteRule ^(.*)$ https://www.domain.com/somefolder/$1 [R,L]
(from here)
You can use the Redirect directive:
Redirect 301 /signup https://www.example.com/signup
This will automatically preserve anything following /signup in the URL. Be sure to configure this directive only on your non-SSL site, or it might get into a recursive loop!
You should take a look at mod_rewrite documentation
I used the following to require the checkout section of a website to require SSL:
<Directory "/var/www/html">
RewriteEngine on
Options +FollowSymLinks
Order allow,deny
Allow from all
RewriteCond %{SERVER_PORT} !^443$
RewriteRule \.(gif|jpg|jpeg|jpe|png|css|js)$ - [S=1]
RewriteRule ^checkout(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
</Directory>
So for example, hitting http://www.example.com/checkout redirects to https://www.example.com/checkout
The rule will skip file extensions that are typically included within a page so that you don't get mixed content warnings. You should add to this list as necessary.
If you want multiple pages change the RewriteRule to something like:
RewriteRule ^(checkout|login)(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
Of course, the directory should match the actual path on your server. This page may also help with some more information for your specific needs: http://www.whoopis.com/howtos/apache-rewrite.html
I'm using this on a website that runs Plesk 8.6 but that shouldn't matter. This is in my vhost.conf file which is like putting it in your httpd.conf file. I'm not sure if you'd need to adjust anything to use it in a .htaccess file but I doubt it. If adding to a conf file don't forget to restart apache to reload the configuration.
If you are like me and want to use SSL only on particular pages then you also want a rewrite rule that sends you back to regular http for the rest. You can use the following for the reverse effect:
RewriteCond %{SERVER_PORT} ^443$
RewriteRule \.(gif|jpg|jpeg|jpe|png|css|js)$ - [S=1]
RewriteRule !^(checkout|login)(.*)$ http://%{SERVER_NAME}%{REQUEST_URI} [L,R]
If you are using Plesk like I am keep in mind that all non-SSL traffic uses the vhost.conf file but all SSL traffic uses the vhost_ssl.conf file. That means your first rewrite rule to require SSL would go in the vhost.conf file but the second rule to force back to non-SSL will have to go in the vhost_ssl file. If you are using httpd.conf or .htaccess I think you can put them both in the same place.
I've also posted this tutorial on my blog: Apache rewrite rules to force secure/non-secure pages.
You can do this with mod_rewrite -
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^/signup https://example.com/signup
RewriteRule ^/signup/(.*)$ https://example.com/signup/$1
Should work, though I haven't tested it.
-- edit --
Correction, I just tried this on one of my servers, and it works fine for me. You may want to doublecheck your mod_rewrite configuration. Also, if you're using .htaccess, you'll want to make sure overrides are allowed for that directory.
As a side note, this assumes your SSL traffic is coming over port 443. If it isn't, you'll need to adjust the rewrite condition accordingly.
.htaccess files are normally placed in a scope with Options -FollowSymLinks, which blocks Rewrite rules. This is often a security rule.
So a more trivial thing is often needed like this one:
<If "%{HTTPS} != 'on'">
Redirect 301 /your/path https://www.example.com/your/path
</If>
This is a small enhancement to the answer of Greg Hewgill.