I have an apache vhost listening on port :443
I am trying to redirect any https requests back to http unless they meet the condition of being
from the domain www.site.co.uk
and contain either /alpha or /beta in the uri part of the request
I have the following statements in the config along with commented logic I though the process follows, but https://www.mysite.co.uk/alpha and https://www.mysite.co.uk/beta are being 301'd somehow
have I misunderstood the logic flow for conditional rewrites ?
RewriteEngine On
# if host submitted is not 'www.mysite.co.uk' un-https the url (i.e. catchall)
RewriteCond %{HTTP_HOST} !^www\.mysite\.co\.uk [NC]
RewriteRule ^(.*)$ http://%{HTTP_HOST}$1 [NC,L,R=301]
# otherwise IF THE domain is 'www.mysite.co.uk
# *and* if the uri does not contain 'alpha' *or* 'beta' un-https the url
RewriteCond %{HTTP_HOST} ^www\.mysite\.co\.uk [NC]
RewriteCond %{REQUEST_URI} !^\/alpha/? [NC,OR]
RewriteCond %{REQUEST_URI} !^\/beta/? [NC]
RewriteRule ^(.*)$ http://%{HTTP_HOST}$1 [NC,L,R=301]
# otherwise the domain must be www.mysite.co.uk
# and the uri must contain '/alpha' *or* '/beta'
# in which case do nothing
The rules that you have is a logical OR of URI not contains /alpha or /beta. You need all the conditions to be and'ed together. Just remove the [OR] flag:
RewriteCond %{REQUEST_URI} !^\/alpha/? [NC]
RewriteCond %{REQUEST_URI} !^\/beta/? [NC]
It's a logical negation expansion. Say A is /alpha and B is /beta. !A is thus not /alpha. So when you say !(A or B), if you expand the !, you get !A and !B.
Related
I have two domains at the moment: example.pl and example.com.
I'm trying to make sure they all go to https://example.pl or http://example.com respectively but I have a problem (or my browser also remembers old state).
I have this code at the moment:
RewriteCond %{ENV:HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^example.pl [NC]
RewriteRule ^ https://example.pl%{REQUEST_URI} [L,NE,R=301]
RewriteCond %{ENV:HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^example.com [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [L,NE,R=301]
But I'm not sure if it's working correctly (http://example.com redirects somehow to https://example.pl) and also whether this can be done in one block of code?
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^example.com [NC]
Both these conditions cannot be successful, so the rule will ultimately fail (do nothing) if requesting the www subdomain over HTTPS.
If it's just two domains then you need to modify the 3rd condition to allow an optional www subdomain and use regex alternation to match the two domains.
For example:
RewriteCond %{ENV:HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(example\.com|example\.pl) [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]
The %1 backreference matches the captured subpattern in the last matched RewriteCond directive, ie. either example.com or example.pl. The important point is that the 3rd condition is always successful, since the only purpose of this 3rd condition is to capture the domain name.
You will need to clear your browser cache since any (erroneous) 301 (permanent) redirects will have been cached by the browser.
But I'm not sure if it's working correctly (http://example.com redirects somehow to https://example.pl) and also whether this can be done in one block of code?
That's not possible with the rules you've posted. It's possible you are seeing a cached redirect from an earlier (erroneous) 301 permanent redirect.
See my earlier answer for an any domain solution.
I would like to have .htaccess code that adds https and www to my URLs – but only when my site is live, not when I am developing locally on my computer.
I have the following
RewriteCond %{HTTP_HOST} !^localhost(?::\d+)?$ [NC]
RewriteCond %{HTTP_HOST} !^www\. [NC,OR]
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L,NE]
But this doesn't appear to be adding the www when my site is live. So for example https://example.com doesn't have the www and all the links are broken. For example https://example.com/about just gets a 404 Not Found error message.
Thanks for any help. I don't understand .htaccess files/code.
EDIT / UPDATE
Comparing the code to other code, should it be the following?
RewriteCond %{HTTP_HOST} !^localhost(?::\d+)?$ [NC]
RewriteCond %{HTTP_HOST} !^www\. [NC,OR]
RewriteCond %{HTTPS} !on
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [R=301,L,NE]
Comparing the code to other code, should it be the following?
RewriteCond %{HTTP_HOST} !^localhost(?::\d+)?$ [NC]
RewriteCond %{HTTP_HOST} !^www\. [NC,OR]
RewriteCond %{HTTPS} !on
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [R=301,L,NE]
Yes.
Your original rule explicitly removed the www subdomain. If you had requested http://www.example.com/ (note HTTP), you would have been redirected to https://example.com/ (HTTPS + non-www). But nothing would happen if requesting https://www.example.com/ - the canonical URL (the rule is skipped because the 2nd and 3rd conditions fail).
The %1 backreference contains the match from the first capturing group in the preceding CondPattern. eg. Given the CondPattern ^(?:www\.)?(.+)$ then %1 contains whatever is matched by (.+) (the first capturing group), ie. the hostname, less the optional www. prefix.
There is no difference between testing %{HTTPS} off or %{HTTPS} !on - the result is the same.
Test first with 302 (temporary) redirects to avoid potential caching issues. You will need to clear your browser cache before testing since the erroneous redirect will have been cached by the browser.
RewriteCond %{HTTP_HOST} !^localhost(?::\d+)?$ [NC]
Checking for a port number would seem to be unnecessary here. This will fail if you are using localhost on the standard port (80 or 443) since the port number will be omitted from the Host header. Something like !^localhost would suffice, or perhaps !^localhost($|:) if you happen to using a domain name that starts localhost!
The first rule works fine when the maintenance file is in place. When it's not - the second rule is not redirecting to the specific URI. Is there an ordering issue of rules or ?
#########################################
RewriteCond %{DOCUMENT_ROOT}/server_maintenance.html -f
RewriteCond %{REQUEST_FILENAME} !/server_maintenance.html
RewriteRule ^.*$ /server_maintenance.html [L]
#########################################
## the %{HTTP_HOST} evaluates to the HTTP header with the name given in this case host.server.org, with NC being non case sensitive.
## it will rewrite the url at the server side to append the URI of lawson/portal
##########################################################################
RewriteCond %{HTTP_HOST} ^host\.server\.org$ [NC]
RewriteRule ^host\.server\.org$ "https\:\/\/host\.server\.org\/lawson\/portal" [L]
#########################################
You don't match a hostname in a RewriteRule, even so with more reason if you are already matching it in a previously defined RewriteCond.
So just do:
RewriteCond %{HTTP_HOST} ^host\.server\.org$ [NC]
RewriteRule ^ https://host.server.org/lawson/portal [L]
Note: RewriteRule target/destination is not regix so do not need to escape every single little thing.
Note2: a single ^ will match anything
I have the following ReWrite Rule
RewriteCond %{REQUEST_URI} !/maintenance.php$ [NC]
RewriteCond %{REQUEST_URI} !\.(jpe?g?|png|gif) [NC]
RewriteCond %{REQUEST_URI} !\.(jpe?g?|png|gif) [NC]
RewriteCond %{REMOTE_ADDR} !{developer_ip}
RewriteRule .* /maintenance.php [R=302,L]
This .htaccess should redirect all requests to the maintenance.php, except the requests coming from {developer_ip} which is my own ip address.
Problem:
The above rules work, but when I click on any of the internal links, it again shows me maintenance.php (which due to the IP rule, must not happen) which ends in either a index.php?{some_query} or a URL which is also already rewritten by the .htaccess itself, such as /Page/About-US (which originally is index.php?page_id=200.
Now I want the .htaccess to redirect all requests to maintenace.php (which already is doing) but no the requests coming from {developer_ip}. The above rules are fine, except the part excluding my own ip address, which redirects me for the internal links.
Perform an internal rewrite to maintenance page and keep your rules in this order:
RewriteEngine On
RewriteCond %{REQUEST_URI} !\.(jpe?g?|png|gif)$ [NC]
RewriteCond %{REMOTE_ADDR} !{developer_ip}
RewriteRule !^maintenance\.php$ /maintenance.php [NC,L]
# skip any requests alredy rewritten to maintenance.php
RewriteRule ^maintenance\.php$ - [NC,L]
# rest of your rewrite rules
I have some rules that force any http URL to be rewritten with https
These rules should only apply for a specific HTTP Host (i.e. if the user is accessing the site through a specific subdomain name).
All working good, but now I want to disable the https redirect if the user is accessing a specific URL
e.g.
http://subdomain.domain.com/test/abc.html or http://subdomain.domain.com/test/123456.html
This is my code, but Apache seems to be ignoring my 2nd last line
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP_HOST} ^subdomain\.domain\.com [NC]
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} !^/test/
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI}
Have your rule like this:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP_HOST} ^subdomain\.domain\.com$ [NC]
RewriteCond %{HTTPS} off
RewriteCond %{THE_REQUEST} !\s/+talent/ [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,NE,R=302]
Better to use %{THE_REQUEST} since THE_REQUEST variable represents original request received by Apache from your browser and it doesn't get overwritten after execution of some rewrite rules.