Apache redirect only part of a query - regex

I'm trying to redirect a query string to a non query url. It looks something like this.
Original
http://searchtest.help.org/search?client=Cool_Sub&site=Cool_Sub&proxystylesheet=Cool_Sub&q=stackoverflow
Expected result
https://searchtest.help.org/cool-search/stackoverflow
I only want to grab the last part of the query. In this case stackoverflow.
This part will always be static.
search?client=Cool_Sub&site=Cool_Sub&proxystylesheet=Cool_Sub&q=
I'm using this in my apache vhost
RewriteEngine On
RewriteCond %{REQUEST_URI} ^\/search$
RewriteCond %{QUERY_STRING} ^client=Cool_Sub&site=Cool_Sub&proxystylesheet=Cool_Sub&q=(.*)
RewriteRule ^(.*)$ https://searchtest.help.org/cool-search/%1 [R=301,L]
However the results with that is
https://searchtest.help.org/cool-search/stackoverflow?client=Cool_Sub&site=Cool_Sub&proxystylesheet=Cool_Sub&q=stackoverflow
I've tried many variations of the above rule but no dice. Any assistance would be grateful.

Add QSD flag to your RewriteRule
RewriteRule ^(.*)$ https://searchtest.help.org/cool-search/%1 [R=301,QSD,L]
According to Apache 2.4 documentation:
When the requested URI contains a query string, and the target URI
does not, the default behavior of RewriteRule is to copy that query
string to the target URI. Using the [QSD] flag causes the query string
to be discarded.

Related

htaccess change url parameter

I have a WP site which uses a calendaring plugin - currently the url the calendar system creates to change the month view of the calendar is hitting a url which fails to advance the month view of the calendar... I have worked out what the correct url should be - but need a way of redirecting from the incorrect url to the correct one...
So...
The incorrect url is: /calendar/?date=2018-04
The correct url is /calendar/?tribe-bar-date=2018-04
So, I am basically looking for a way to redirect / rewrite the url so that "?date=2018-04" becomes "?tribe-bar-date=2018-04" bearing in mind the year-month after the "=" element in the parameter will change all the time. So need to change "?date" to become "?tribe-bar-date"...
I have had a go using the redirection WP plugin with a rule as below:
/calendar/?date=(.*)
/calendar/?tribe-bar-date=(.*)
but it doesn't work... not sure why... I thought it would but I don't know regex very well!
Any ideas?
Try:
RewriteCond %{QUERY_STRING} (?:^|&)date=(.*)$
RewriteRule ^calendar/(.*)$ /calendar/$1?tribe-bar-date=%1 [L,R]
This assumes that the "date" parameter will be the first in the query string, otherwise you can add an additional grouping in front to try to capture that as well. This is doing a 302 (not permanent) redirect, you can change that if you want by changing the R to R=301.
Make sure this rule is before any wordpress rules.
If you want to redirect externally only , do this :
RewriteEngine On
RewriteCond %{QUERY_STRING} ^date=(.+)$
RewriteRule ^calendar/$ /calendar/?tribe-bar-date=%1 [QSD,R=301,L,NE]
Or this :
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(/calendar/)\?date=(.+)\sHTTP.*$
RewriteRule ^ %1?tribe-bar-date=%2 [QSD,R=301,L,NE]
If it is externally for that target then internally to same path , do this :
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(/calendar/)\?date=(.+)\sHTTP.*$
RewriteRule ^ %1?tribe-bar-date=%2 [QSD,R=301,L,NE]
RewriteCond %{QUERY_STRING} ^tribe-bar-date=(.+)$
RewriteRule ^calendar/$ /calendar/?date=%1 [L,NE]
To prevent query string from being appended you should put ? at the end of RewriteRule substitution
In apache 2.4 and later you could discard query string by this flag [QSD] https://httpd.apache.org/docs/2.4/rewrite/flags.html

Any idea why this regex doesn't work?

I'm using the code below in my .htaccess
RewriteEngine on
RewriteCond %{QUERY_STRING} (?:^|&)prod=\d+(?:&|$) [NC]
RewriteRule ^dumbwaiters/proddetail\.php\?* https://www.example.com/dumbwaiters/compare-dumbwaiters/ [NC,R=301,L]
It redirects to:
https://www.example.com/dumbwaiters/compare-dumbwaiters/?prod=143
But I don't want the trailing ?/prod=143
Any idea what I'm doing wrong?
http://httpd.apache.org/docs/current/rewrite/flags.html#flag_qsd
When the requested URI contains a query string, and the target URI
does not, the default behavior of RewriteRule is to copy that query
string to the target URI. Using the [QSD] flag causes the query string
to be discarded.
This flag is available in version 2.4.0 and later.
So if your Apache version is sufficient, I think the below untested code would work:
RewriteRule ^dumbwaiters/proddetail\.php.* https://www.example.com/dumbwaiters/compare-dumbwaiters/ [QSD,NC,R=301,L]

How do I strip all query string besides one directory from URL?

I want to force rewrite all url using queries /?campaign=whatever etc.
I wrote something like this (I'm not sure if it's the best way to do it):
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^?]*)\?
RewriteRule (.*) /$1? [R=301,L]
How can I tell apache not to rewrite only directory /admin/ ?
Also, if anyone knows if it's possible to mess up some other services using this technique? I don't need analytics campaigns etc, people just link with their own stupid tracking urls to my blog and it bypasses the cache but I can't change the cache system currently.
Example:
http://www.example.com/admin/
http://www.example.com/admin/pages.php?var=blabla
(anything after or /admin/) - ignore
Else - clean the query strings.
RewriteCond %{QUERY_STRING} .+
RewriteCond %{REQUEST_URI} !^/admin(?:/.*)?$
RewriteRule (.*) /$1? [R=301,L]
Check if query string contains something.
Check the request URI if it does not start with /admin/.
If all conditions are met, redirect URL - remove query string.

rewritecond with query string works, but when i submit a new query from the clean url, it just appends the url with the old query string

Here is are my rewrite rules and conditions
#link ReWrite
RewriteRule ^searchresults/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /searchresults.php?search=1&year_search_type=single&isused=$1&year=$2&make=$3&model=$4&price=$5 [L]
#query Rewrite
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]
RewriteCond %{REQUEST_URI} ^/searchresults.php [NC]
RewriteCond %{QUERY_STRING} ^.*[&]?isused=(\w+).*&year=(\w+).*&make=(\w+).*&model=(\w+).*&price=(\w+).*$ [NC]
RewriteRule . /searchresults/%1/%2/%3/%4/%5? [R=301,L]
Situation -
i have a search page that searches the database and shows results. This setup catches the Query and rewrites it to clean urls (awesome!) BUT if i run a query a second time, aka from the cleaned url, the search request now just adds the original ?key=value&key=value to the clean url to make the request.
searchresults.php?make=value&model=value turns into searchresults/value/value as i want it to
but when i run the second query from searchresults/value/value it ends up turning it into
/searchresults/value/value?make=value&model=value
any way to defeat that from within .htaccess as the search query itself is in some deep php crazy land of code, and i honestly cant even find the thing, so editing the php is not in the cards.
ALSO, as a bonus, if anyone can tell me what edits to make so that when the query sends a request that looks like key=value+with+spaces i get the correct clean url back? right now it takes key=value+with+spaces and gives me back "value" but drops off with+spaces and moves onto the next key value pair....
THANKS
Not sure why you're having the problem, your rules worked perfectly fine for me on a vanilla apache install in a blank htaccess file. But you can try changing your rules a little:
The first thing you need to do is swap the order of your two rules. The redirect rule must be before any internal rewrites. This prevents two rules from being applied to the same request (the rewrite engine loops through all the rules until the URI stops changing). Second, you need to match against the actual request instead of the %{QUERY_STRING} match against the %{THE_REQUEST} variable:
RewriteCond %{THE_REQUEST} \ /+searchresults\.php\?.*[&]?isused=(\w+).*&year=(\w+).*&make=(\w+).*&model=(\w+).*&price=(\w+).*$ [NC]
RewriteRule ^ /searchresults/%1/%2/%3/%4/%5? [R=301,L]
RewriteRule ^searchresults/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /searchresults.php?search=1&year_search_type=single&isused=$1&year=$2&make=$3&model=$4&price=$5 [L]

htaccess 301 redirect - Remove query string (QSA)

I've been struggling with some htaccess redirects. I just spent some time reading and searching on stack and couldn't get an anwser that works with my scenario.
I'm in the process of making the 301 redirect for an old client website to a new one. The old pages has parameters query which I want to remove from the url.
/menu.php?idCategorie=29&idDetail=172
to
/new-website-page/
I have multiple queries to do, here's a couple example:
/menu.php?idCategorie=29&idDetail=172
/menu.php?idCategorie=29&idDetail=182
/menu.php?idCategorie=29&idDetail=184
/menu.php?idCategorie=29&idDetail=256
Which all link to different new pages.
Here's what I tried:
RewriteCond %{QUERY_STRING} idDetail=172
RewriteRule ^menu.php(.*) /new-page/? [R=301,L]
I get redirected correctly, but the URL keeps the query string:
http://website.com/new-page/?idCategorie=29&idDetail=172
I also tried this:
RewriteRule ^menu.php?idCategorie=29&idDetail=172$ http://website.com/new-page/? [L,R=301]
And this:
RewriteCond %{QUERY_STRING} idDetail=172(.*)$
RewriteRule ^menu.php /new-page-name?$1 [L,R=301]
And it didn't work (Still have the query string at the end)
Thanks!
You can use this rule:
RewriteRule ^menu\.php$ /new-page-name? [L,R=301]
Take note of trailing ? in the end which is used for stripping off any existing query string in the original URI.
In addition to anubhava's answer you can alternatively use the QSD flag from Apache 2.4.0
RewriteRule ^menu\.php$ /new-page-name [L,R=301,QSD]
http://httpd.apache.org/docs/current/en/rewrite/flags.html#flag_qsd