htaccess - Stop processing - apache

I'm trying to force https on our order page and at the same time use standard http for the other pages on the site. And finally then make a internal rewrite so all requests is handled by index.php
This is what I have tried so far but my problem is that after the last RewriteRule to index.php all the rules a processed once again and the second RewriteUrl is processed since (I guess) the internal url no longer is /sv/webshop/ and I end up with something like http://www.yyyyy/?language=sv&_url=/webshop/
I have tried adding the flag END to the last RewriteUrl but then I got a Internal Server Error.
Is it possible to stop the processing or is there another solution?
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} ^(/sv/webshop/)$
RewriteRule (.*) https://yyyyyy.com/$1 [R=301,L,QSA]
RewriteCond %{SERVER_PORT} 443
RewriteCond %{REQUEST_URI} !^(/sv/webshop/)$
RewriteRule (.*) http://yyyyyy.com/$1 [R=301,L,QSA]
RewriteRule ^(sv|dk|no|en|de)/(.*)$ index.php?language=$1&_url=/$2 [QSA]

So I found a way, I'm not sure this is the best solution but it works. Please let me know if there is a better solution. This is what I do for now
# Placed before any the of the other rewrite rules
RewriteCond %{QUERY_STRING} ^(.*)language(.*)$
RewriteRule (.*) - [QSA,L]

Related

Https to http with variant exceptions

Our site is going to be switched to SSL soon but we're not ready for it. As such we are going to redirect all https URLs to http in htaccess. I've got that working but as an added complication we've got a few URLs that have to be exceptions to the redirect. These URLs are:
somebody.dev.www.example.com
example.com/top_deal
example.com/watches
I have the redirect working like so:
RewriteCond %{HTTP:X-Forwarded-Proto} =https
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=302]
but can't get the exceptions to work. I've tried literally every solution online that I can find.
You can use rule as your very first rule:
RewriteEngine On
RewriteCond %{HTTP_HOST} !=somebody.dev.www.example.com
RewriteCond %{THE_REQUEST} !\s/+(?:top_deal|watches)/?[?\s] [NC]
RewriteCond %{HTTP:X-Forwarded-Proto} =https
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
# rest of your rules go here
Make sure to clear your browser cache before testing.
First, do you want it to be a temporary rewrite (=302) or should the browser save it as permanent und thus get 301? Just asking, both works, but if you want to go for temporary, you should read this
Excerpt: HTTP/1.1 (RFC 2616) added the new status codes 303 and 307
So in your case a 307 would probably be better.
If you want to have permanent rewrite instead, use [R=301] to make the browser cache the rewrite-target instead of rewriting each time.
Now to the WRONG solution (but there is a good reason I leave in there, see here) - DON'T use that !!!
#logic is: 1 OR (2 AND 3) --> NO, it isn't, see the link right above!
#1 being hostname: somebody.dev.www.example.com
#2 being hostname: example.com
#3 being REQUEST_URI = !^/(top_deal|watches)
RewriteCond %{HTTP_HOST} ^somebody.dev.www.example.com$ [OR]
RewriteCond %{HTTP_HOST} ^example.com$
RewriteCond %{REQUEST_URI} !^/(top_deal|watches)$
RewriteRule .? - [END]
##[END] makes the rewrite-evaluation STOP, completely, not only for this turn!
#same rule as before, just changed 302 -> 307 (RFC 2616) and ^(.*)$ to .? cuz I like it better^^
RewriteCond %{HTTP:X-Forwarded-Proto} =https
RewriteRule .? http://%{HTTP_HOST}%{REQUEST_URI} [L,R=307]
Update
Here is, what really should be put into your config:
# Don't rewrite HOST 'somebody.dev.www.example.com'
RewriteCond %{HTTP_HOST} ^somebody.dev.www.example.com$
RewriteRule ^ - [END]
# Don't rewrite HOST 'example.com', if URI 'top_deal' OR 'watches'
RewriteCond %{HTTP_HOST} ^example.com$
RewriteCond %{REQUEST_URI} ^/(top_deal|watches)$
RewriteRule ^ - [END]
RewriteCond %{HTTPS} on
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=307]
That should definitely do the job :)
If it doesn't, for some reason, search for your LogLevel and add the rewrite:traceX to that line. So if your LogLevel is error it should look like this:
LogLevel error rewrite:trace2
Then restart/reload your server and test again. Error.log will now show the results of the attempted rewrites. Use tail -f error_log|fgrep '[rewrite:' to find them. If they are unclear, let us know, maybe we can help :)
What I finally did that ended up working was the following:
RewriteCond %{HTTP_HOST} !^(.*).dev.www.example.com
RewriteCond %{REQUEST_FILENAME} ! top_deal(.*)
RewriteCond %{REQUEST_FILENAME} ! watches(.*)
RewriteCond %{HTTP:X-Forwarded-Proto} =https
RewriteRule .? http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Enforce HTTPS across thousands of 301 RewriteRule entries

community. I'm migrating an ancient ColdFusion site (seriously), and we have literally thousands of 301 redirects from old versions of pages like
index.cfm?id=1&this=that
to more reasonable counterparts like
/what-this-page-really-is
Google says to list them out one by one, so that's what I'm doing. However, on ALL of these redirects we also want to enforce HTTPS. What we have now is this:
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
RewriteRule ^thing.cfm$ /thing/? [R=301,L,NC]
RewriteCond %{QUERY_STRING} id=1 [NC]
RewriteRule ^blah.cfm$ /awesome-sauce/? [R=301,L,NC]
It works fine, but Google complains that it's technically two redirects for these old links. A possible solution would be to exclude *.cfm files from the HTTPS redirect and explicitly make every single *.cfm redirect go to the HTTPS version of the page, like so:
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} !(.*)cfm$
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
RewriteRule ^thing.cfm$ https://%{HTTP_HOST}/thing/? [R=301,L,NC]
RewriteCond %{QUERY_STRING} id=1 [NC]
RewriteRule ^blah.cfm$ https://%{HTTP_HOST}/awesome-sauce/? [R=301,L,NC]
But over thousands of lines, that's a lot of extra characters in an .htaccess file. I know this is better in apache config, but I don't have that option right now.
My question: is there a way to set a flag that's going to apply the HTTPS parameter to ALL of the subsequent *.cfm 301 redirects?
Thank you!
Rather than enforcing https:// in each 301 handler you can move your http->https rule at the bottom and remove R flag from your redirect flags so that Google (or any external client) gets only one single redirect.
RewriteEngine On
RewriteRule ^thing\.cfm$ /thing/? [L,NC]
RewriteCond %{QUERY_STRING} id=1 [NC]
RewriteRule ^blah\.cfm$ /awesome-sauce/? [L,NC]
# all other rules here but remove R=301 flag
# finally do a http->https with rewritten URI
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L,NE]
Make sure to clear your browser cache before testing.

.htaccess Redirect/Rewrite Issue

I am having a hard time figuring out how I can do this.
I want all requests to www.mydomain.com/manager to redirect to m.mydomain.com
I am trying:
# Friendly URLs for the manager
RewriteCond %{HTTP_HOST} ^(www.)?cloudcms.co$
RewriteRule ^manager/?$ http://m.cloudcms.co/ [NC,L,R]
RewriteCond %{HTTP_HOST} ^(m.|manager.)?cloudcms.co$
RewriteRule ^(/)?$ manager/ [L,QSA,NC]
However, the only real one that is properly rewriting is the second condition.
I have also tried the following
# Friendly URLs for the manager
RewriteCond %{HTTP_HOST} ^(www.)?cloudcms.co$
Redirect 301 /manager http://manager.cloudcms.co
RewriteCond %{HTTP_HOST} ^(m.|manager.)?cloudcms.co$
RewriteRule ^(/)?$ manager/ [L,QSA,NC]
But it ignores the second rewrite
As per my comment above:
Is there another .htaccess in /manager folder or any other in present .htaccess`
I suspect OP has another .htaccess somewhere inside your DOCUMENT_ROOT. Try removing that and this simple redirect will start working.
OP asked:
How would I be able to do this for any domain that could come in and
try hitting the /manager folder?
Just change your first redirect rule to:
# if not already on mobile domain
RewriteCond %{HTTP_HOST} !^m\. [NC
RewriteRule ^manager/?$ http://m.cloudcms.co/ [NC,L,R=301]
You probably don't want to P flag, which is reverse proxying for you. Try replacing that with an R:
RewriteRule ^manager/?$ http://m.mydomain.com/ [NC,L,R]

htaccess from https to http

I have these vales in my htacces file it all works fine except when i try to go back to http from https i have tried swapping the rules around with no success, any help would be awsome
I have tried all the sujestion with still no suucess so maybe i need to show you guys the entire thing.
Still not going back to http from https, here is the whole thing
Have i got the rules in the wrong order? im lost
<ifModule mod_rewrite.c>
RewriteEngine on
# For Sales:
RewriteRule ^shop/sales/?$ sales.php
# For the primary categories:
RewriteRule ^shop/([A-Z-Aa-z\+]+)/?$ shop.php?type=$1
# For specific products:
RewriteRule ^browse/([A-Za-z\+]+)/([A-Za-z\+\-]+)/([0-9]+)$ browse.php?type=$1&category=$2&id=$3
#For https pages:
#RewriteCond %{HTTPS} on
#RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L=301]
#RewriteCond %{HTTPS} off
#RewriteRule ^(checkout\.php|final\.php|admin/(.*))$ https://{HTTP_HOST}/$1[R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1 [L,QSA]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.*)/index\.php [NC]
RewriteRule ^ /%1 [R=301,L]
</ifModule>
I am not able to test the rules, but I think you need to change the following:
In the first rule your flag is attached to the 2nd argument. This should create an internal error. Your second rule would rewrite all url's to their http equivalent, making an infinite loop. You need to make sure it doesn't match url's that you want to be in https. You can do this with %{REQUEST_URI} and a negation (!). As far as I am aware, L=301 is an invalid flag too. You probably meant to make it R=301.
RewriteCond %{HTTPS} off
RewriteRule ^(checkout\.php|final\.php|admin/(.*))$ https://{HTTP_HOST}/$1 [R,L]
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !/(checkout\.php|final\.php|admin/(.*))$
RewriteRule ^http://%{HTTP_HOST}%{REQUEST_URI} [R,L]
Last but not least an word of advice. Don't test your .htaccess with permanent redirects until everything works as expected. The browser will cache permanent redirects, not picking up further tries to make your .htaccess work as you want.

htaccess for redirect to SSL

For the past few hours (days) I have been having some trouble redirecting a
page to SSL.
My setup is as follows: I have the following .htaccess for an e-commerce site
on Apache 2.2.16 on Debian (all required mods enabled)
RewriteEngine On
RewriteBase /shop
RewriteCond $1 !^(index\.php|products|img|theme\.php|checkout\.php)
RewriteRule ^(.*)$ index.php?/$1 [L]
all requests are passed to index.php which acts as my controller and includes
other .php files as necessary.
I now want to use HTTPS for the checkout process which is a php script
cleverly called checkout.php
I thought it would be as easy as changing my .htaccess to:
RewriteEngine On
RewriteBase /shop
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{SERVER_URI} checkout\.php
RewriteRule ^checkout.php?/$1 https://localhost/shop/checkout.php?/$1 [L,R]
RewriteCond $1 !^(index\.php|products|img|theme\.php|checkout\.php)
RewriteRule ^(.*)$ index.php?/$1 [L]
so that checkout.php is not processed by index.php.
Apparently it is not that simple. I could probably do it by using a hardcoded
https link to checkout but I would prefer to do it with mod_rewrite.
If anyone can share some insight into
this it would be really appreciated.
Thanks in advance
There are a few problems. First, the pattern in your first RewriteRule
RewriteRule ^checkout.php?/$1 https://localhost/shop/checkout.php?/$1 [L,R]
is written incorrectly. $1 isn't meaningful there (it's a capture result, but no capture has happened yet), and also the query string (part of the request after the ?) isn't part of what's matched, as the RewriteRule documentation says.
Second, I think you meant to use REQUEST_URI instead of SERVER_URI.
So I think you want something like this:
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/checkout\.php
RewriteRule .* https://localhost/shop/checkout.php [L,R]
RewriteCond %{REQUEST_URI} !^/(index\.php|products|img|theme\.php|checkout\.php)
RewriteRule ^(.*)$ /index.php?/$1 [L]
A few notes:
You don't need to match or add back in the query string in the first RewriteRule; mod_rewrite will automatically add it back in.
It's conventional to test RewriteCond %{HTTPS} off instead of
RewriteCond %{SERVER_PORT} !443, as #Jon Lin suggests.
You may want to add the QSA flag in your second RewriteRule.