Apache manipulating query string on https - apache

the following rules works on http but don't on https.
RewriteCond %{QUERY_STRING} "page=" [NC]
RewriteRule (.*) /$1? [L]
RewriteRule ^/path/file.html$ https://www.domain.tld/path/file/ [R=301,L]
Why the query_string part doesn't work in https?

Based on the comments of your question, it appears that you just want to remove the query string anytime there is a page parameter. This type of rewrite rule doesn't strip off or change the URL unless there is a redirect. So if you don't add R=301 or R to the rewrite rule, the query string will not be removed. All of the following worked on my server to remove the query string, and my server is 100% HTTPS:
RewriteCond %{QUERY_STRING} "page=" [NC]
RewriteRule (.*) /$1? [R=301,L]
Or you may be able to use the QSD flag instead of question mark:
RewriteCond %{QUERY_STRING} "page=" [NC]
RewriteRule (.*) /$1 [R=301,L,QSD]
Or you may be able to use something like this:
RewriteCond %{QUERY_STRING} "page=" [NC]
RewriteRule .* /? [R=301,L]
Or just R (for 302) instead of R=301:
RewriteCond %{QUERY_STRING} "page=" [NC]
RewriteRule (.*) /$1? [R,L]
But in no case was the query string removed unless I used a redirect.

Really all you need is QSD http://httpd.apache.org/docs/current/rewrite/flags.htm
RewriteCond %{QUERY_STRING} "page=" [NC]
RewriteRule (.*) /$1 [L,QSD]
I'm not sure why it would work on http but not https unless you're using separate vhosts for http and https and the settigns were slightly different
Remember that Rewrite rules are internal unless using the R flag. When you use the R flag it tells the browser to go to a different page causing a full server/client round-trip. Otherwise, it just changes the request and proceeds as normal.

I'm not really strong with .htaccess file, and I can't explain what's going on behind the scenes, but from my opinion your .htaccess file should look like this:
RewriteCond %{QUERY_STRING} page= [NC]
RewriteRule (.*) /$1? [L]
RewriteRule ^path/file.html$ https://www.domain.tld/path/file/ [R=301,L]
It work perfectly for
http://example.com?page=1
https://example.com/?page=1
http://example.com/path/file.html
https://example.com/path/file.html
Tested (with love) here

Related

Redirection is not working with mod_rewrite in htaccess

I need to redirect few URIs having query string like:
/pages/foo.bar?pageId=123456 to http://some.site/spam/egg/
/pages/foo.bar?pageId=45678 to http://another.site/spaming/egging/
I have this in my htaccess:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/pages/foo.bar$
RewriteCond %{QUERY_STRING} ^pageId=123456$
RewriteRule ^.*$ http://some.site/spam/egg/ [R=301,L]
RewriteCond %{REQUEST_URI} ^/pages/foo.bar$
RewriteCond %{QUERY_STRING} ^pageId=45678$
RewriteRule ^.*$ http://another.site/spaming/egging/ [R=301,L]
But its not working, showing 404. What am i doing wrong?
You need to move these 2 rules i.e. before all other rules just below RewriteEngine On line as other rules might be overriding this.
(Based on your comments) Your culprit rule is this rule:
RewriteRule . index.php [L]
Which is actually rewriting every request to index.php and changing value of REQUEST_URI variable to /index.php thus causing this condition to fail:
RewriteCond %{REQUEST_URI} ^/pages/foo.bar$
From your example, you get redirected to
http://some.site/spam/egg/?pageId=123456
http://another.site/spaming/egging/?pageId=45678
You can use your browser developer tools to see the redirection (in the Network tab).
Maybe the query strings in the redirected URL lead to a 404? You can add a ? at the end of your redirection to clear the query string:
RewriteCond %{REQUEST_URI} ^/pages/foo.bar$
RewriteCond %{QUERY_STRING} ^pageId=45678$
RewriteRule ^.*$ http://another.site/spaming/egging/? [R=301,L]

Simple Apache mod_rewrite remapping

I have to remap a few ID's to URL strings (301 redirect) and I have to do it with mod_rewrite:
/page.php?id=15 to /pagexy
/page.php?id=10 to /pageyz
The rule:
RewriteRule ^page.php?id=15$ /pagexy [L,R=301]
doesn't work. What am I doing wrong?
You need to inspect the query string separately. The following should work:
RewriteEngine On
RewriteCond %{QUERY_STRING} id=15\b [NC]
RewriteRule ^/page.php$ /pagexy? [L,R=301]
RewriteCond %{QUERY_STRING} id=10\b [NC]
RewriteRule ^/page.php$ /pageyz? [L,R=301]
Given you are tying ids to pages, it may also pay to look at using a RewriteMap

mod redirect rule

I just want to redirect the URL through the mod rewrite ruls. I have applied this rule excluding (R=301)
Example :
from http:///webapp/wcs/stores/servlet/en/marksandspencer to http:///en/marksandspencer
I am using this rules for the mod redirect rules.
RewriteEngine on
RewriteCond %{REQUEST_URI} !^(/)?$
RewriteCond %{REQUEST_URI} !^/webapp.*$
RewriteCond %{REQUEST_URI} !^/wcsstore.*$
RewriteRule ^/(.*)$ /webapp/wcs/stores/servlet/$1 [PT,NC,L,QSA]
RewriteRule ^/webapp/wcs/stores/servlet/(.*) /$1 [NE,L,QSA]
RewriteRule ^(/)?$ /webapp/wcs/stores/servlet/en/marksandspencer [PT,NC,L]
No idea what you're trying to do, but if you're using Apache 2.0 or higher, the leading slash is stripped off of URI's when matching is done within a RewriteRule. Also, you have a rule that looks like you're adding a /webapp/wcs/stores/servlet/ to the beginning of a URI, then the very next rule it looks like you are removing it. This will probably cause a loop.
Taking a wild guess at what you are trying to do, I think you need to add a condition to the 2nd rule, and remove the leading slashes:
# internally rewrite URI by appending "/webapp/wcs/stores/servlet/" to the front
RewriteCond %{REQUEST_URI} !^(/)?$
RewriteCond %{REQUEST_URI} !^/webapp.*$
RewriteCond %{REQUEST_URI} !^/wcsstore.*$
RewriteRule ^(.*)$ /webapp/wcs/stores/servlet/$1 [PT,NC,L,QSA]
# if a request is made with "/webapp/wcs/stores/servlet/" in it, redirect to a URI with it stripped
RewriteCond %{THE_REQUEST} ^(GET/POST)\ /webapp/wcs/stores/servlet/
RewriteRule ^webapp/wcs/stores/servlet/(.*) /$1 [R=301,L,QSA]
RewriteRule ^$ /webapp/wcs/stores/servlet/en/marksandspencer [PT,NC,L]

Redirect Subdomain to new domain

Hi guys trying to get a 301 redirect working and having trouble. I need to redirect sub.domain1.com to www.domain2.com and make sure that any file names or parameters get sent over with it.
This is what I was trying:
RewriteCond %{HTTP_HOST} ^domain1.com [NC]
RewriteRule ^(.*)$ http://www.domain2.com/$1 [L,R=301]
I also tried this:
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^sub\.domain1\.com$ /www.domain2.com? [R=301,NE,NC,L]
Where am I messing up?
You missed the subdomain part and proper escaping.
RewriteCond %{HTTP_HOST} ^sub\.domain1\.com$ [NC]
RewriteRule ^(.*)$ http://www.domain2.com/$1 [L,R=301]
Further explain can be found in this question.
Rule of thumb for rewriterules: from the most complex to the less complex.
And don't forget the QSA directive (QSA = Query String Append = "make sure that any file names or parameters get sent over with it")
RewriteCond %{HTTP_HOST} ^sub\.domain1\.com$ [NC]
RewriteRule ^(.*)$ http://www.domain2.com/$1 [QSA,R=301,L]
Tell me if it works.

Problems with rewrite module and negation patterns

I have the following problem:
If the url contains the keyword "formulario-" and it is a http connection, I want to redirect to the https version.
If the url doesn't contain the keyword "formulario-" and it is a https connection, I want to redirecto to http version.
I tried the following .htaccess but it doens't work properly:
RewriteEngine On
RewriteCond %{HTTPS} =on
RewriteRule .* http://%{HTTP_HOST}%{REQUEST_URI}
RewriteCond %{HTTPS} !=on
RewriteRule ^formulario-(.*) http://%{HTTP_HOST}%{REQUEST_URI}
Thanks for your help!
Untested, but the general idea is:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule formulario- https://%{HTTP_HOST}%{REQUEST_URI} [R,L,QSA]
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !formulario-
RewriteRule .* http://%{HTTP_HOST}%{REQUEST_URI} [R,L,QSA]
The theory being you cannot negate a RewriteRule, but you can negate a RewriteCond.
What exactly does not work?
One thing that comes to mind is: Try using the [L] flag for the first rule, so that apache stops to process the second rule, if the first rule applies.
I am not sure that's it though. You probably need some way to test whether the user was already redirected before.