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.
Related
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]
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]
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.
Basicly i'm working on my site to be SEO-friendly. I wanted to achieve following:
Rewrite urls to pretty ones
Remove multiple slashes (eg. example.com/////something/// to example.com/something/
Redirect www version to a non-www version.
Hide index.php file from all urls
Redirect from old (/?id=something/ to new urls /something/)
I came up with this .htaccess code:
RewriteCond %{THE_REQUEST} //
RewriteRule .* $0 [R=301]
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteCond %{QUERY_STRING} ^id=([a-z0-9\/-]+)
RewriteRule ^(.*)$ http://example.com/%1? [R=301]
RewriteRule ^index.php(.*)$ /$1 [R=301]
RewriteRule ^([a-z0-9\/-]+)$ /?id=$1 [L]
...and though it's working it has a side effect: chain redirects, eg. example.com/?id=something////// -> example.com/something////// -> example.com/something/
So is there a way to rewrite or modify this code so it'll be redirecting just once to the preferred version of the url?
Trying to interpret what you want, let's look at the rules in your question:
.1 Can't understand the purpose of this:
RewriteCond %{THE_REQUEST} //
RewriteRule .* $0 [R=301]
.2 This rule-set in your question removes www and converts the query string ?id=val to /val, but only when the incoming URI has www AND there is a query string as both conditions must be met:
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteCond %{QUERY_STRING} ^id=([a-z0-9\/-]+)
RewriteRule ^(.*)$ http://example.com/%1? [R=301]
.3 This rule
RewriteRule ^index.php(.*)$ /$1 [R=301]
Hides index.php, but only when it is in the root directory. Example:
http://www.example.com/index.php?id=val
Does not work when it is in a subdirectory. Example:
http://www.example.com/folder/index.php?id=val
.4 Can't understand the purpose of this:
RewriteRule ^([a-z0-9\/-]+)$ /?id=$1 [L]
I suggest this instead:
RewriteEngine On
RewriteBase /
#Redirects all www to non-www
RewriteCond %{HTTP_HOST} www\.example\.com$ [NC]
RewriteRule ^(.*)/?$ http://example.com/$1 [R=301,L]
#Hides "index.php" keeping the query if present
RewriteRule ^(.*)/index\.php$ $1/ [R=301,QSA,L]
#Converts query string `?id=val` to `/val`
RewriteCond %{QUERY_STRING} id=([^/]+)
RewriteRule .* /%1? [R=301,L]
Remember spiders will "adapt" to the correct new structure after a few months, and the problem may ultimately be a whole lot less severe than what it looks like initially. You can leave all the .htaccess code in place, knowing it always be there to correct any "old" references yet will in fact hardly ever actually be used.
I've never found an easy way to avoid multiple round trips back to the client when "fixing up" a URL to be in some sort of canonical form. mod_rewrite seems to be more focussed on the "local" redirect case where the client has no idea that the content it got back came out of a file structure that doesn't perfectly match that implied by the URL.
It is possible to save up all the URL mods locally, then provoke only one round trip to the client that delivers all the URL corrections all at once by setting everything in newly created "environment" variables then at the end asking basically "has anything changed?" However doing so is notably verbose and rather awkward and quite error-prone and has never become a "recommended technique".
As the title says, I need a quite complex url rewrite mechanism for a web-app as .htaccess rule.
I've searched quite a lot now and tried hundred of different rewrite rules.
So, basically this is what I need:
User goes to: http://www.site.com/product.php?id=12
Server should redirect to: http://site.com/product/12
Once thing to mention:
not all pages do append id's.
So I also have: http://www.site.com/some/page.php
which then should redirect to: http://site.com/some/page
or from http://site.com/anotherone.php to http://site.com/anotherone
You help is much appreciated and thank you a lot in advance for you help!
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)\.php$ http://%1/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)\.php\?id=([0-9]+)$ http://%1/$1/$2 [R=301,L]
I supose that you, previously have this mod_rewrite rule active:
Users goes to http://site.com/product/12 and in the browser is showed this URL, and internaly, and only internaly, server serve http://www.site.com/product.php?id=12
Put the first RewriteCond and Rule this:
RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteRule ^(\w+)\.php\?id=(\d*)$ /$1/$2 [R=301]
And add another to remove the .php when ends with .php
RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteRule ^(\w+)\.php$ /$1 [R=301]