.htaccess redirect query strings - regex

This was kind of hard to search for, I found examples of other work but basically I have a url:
site.com/?page=test&id=3
I want to rewrite as: site.com/test:3
with 'test' being page, and 3 being id.
I have the following match for equal values:
RewriteCond %{QUERY_STRING} ^(\w+)=(\w+)$
RewriteRule ^/ /%1:%2?
But that only works for the key and the value, what regex can I use to select just the key, with %1 and %2 ?
Thanks,
My Second Attempt:
(I only need on index.php)
RewriteCond %{QUERY_STRING} ^page=(\w+)&id=([0-9]*)$
RewriteRule ^index\.php$ /%1:%2**?** [R=302,L]
but now a 404 error is occuring when I do: index.php/details:1

You can use this code in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
RewriteCond %{THE_REQUEST} \?test=([^\s&]+)&test2=([^\s&]+) [NC]
RewriteRule ^/?$ /%1:%2? [R=302,L,NE]
RewriteRule ^([^:]+):([^/]+)/?$ /?test=$1&test2=$2 [L,QSA]

Related

Handle one query parameter specifically

I need to handle one query parameter specifically.
The url can look like the following:
https://example.com/?app=egov&map=1337
https://example.com/?app=egov&map=1337&showoptions=true
https://example.com/?app=egov&map=1337&showoptions=true&anotherparam=helloWorld
The redirect should point to
https://example.com/contextName/resources/apps/egov/index.html?map=1337
https://example.com/contextName/resources/apps/egov/index.html?map=1337&showoptions=true
https://example.com/contextName/resources/apps/egov/index.html?map=1337&anotherparam=helloWorld
As you can see, the app-Parameter needs to be used as an URL-part; the others need to be used like traditional query-params.
I've figured out, how to implement the first part, where https://example.com/?app=egov points to https://example.com/contextName/resources/apps/egov/index.html using the following
RewriteCond %{REQUEST_URI} ^/$
RewriteCond %{QUERY_STRING} ^app\=(.+)
RewriteRule ^/$ "/contextName/resources/apps/%1/index.html" [R,L,QSA]
but I'm struggeling how to realize the correct handling of the other params.
All these combination of query string can be handled by a single rule loke this:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^app=([\w-]+)(?:&(.*))?$ [NC]
RewriteRule ^$ contextName/resources/apps/%1/index.html?%2 [L]
RewriteCond matches app query parameter and captures it in %1 while rest of the query string after & is captured in %2.
With your shown samples, please try following htaccess Rules file. Please make sure to clear your browser cache before testing your URLs.
RewriteEngine ON
####Apache documentation link https://httpd.apache.org/docs/trunk/rewrite/remapping.html for more info.
##Internal rewrite rule for URL https://example.com/?app=egov&map=1337
RewriteCond %{QUERY_STRING} ^app=([^&]*)&map=(\d+)$ [NC]
RewriteRule ^/?$ contextName/resources/apps/%1/index.html?map=%2 [L]
##Internal rewrite rule for URL https://example.com/?app=egov&map=1337&showoptions=true
RewriteCond %{QUERY_STRING} ^app=([^&]*)&map=(\d+)&showoptions=(.*)$ [NC]
RewriteRule ^/?$ contextName/resources/apps/%1/index.html?map=%2&showoptions=%3 [L]
##Internal rewrite rule for https://example.com/?app=egov&map=1337&showoptions=true&anotherparam=helloWorl
RewriteCond %{QUERY_STRING} ^app=([^&]*)&map=(\d+)&showoptions=([^&]*)&anotherparam=(.*)$ [NC]
RewriteRule ^/?$ contextName/resources/apps/%1/index.html?map=%2&anotherparam=%4 [L]
All of your URLs uri part is NULL, so rules are written based on that.

301 redirect with query parameters and ~ in URL

I have a redirect problem where I would like to redirect a url with query parameters to another PDF entirely, e.g.:
Original URL:
https://www.foo.bar.com/~/bar.pdf?la
Redirect URL:
https://www.bar.foo.com/foo.pdf
Currently my rewrite rule is as shown below:
RewriteRule ^/~/bar.pdf?la https://www.bar.foo.com/foo.pdf [R=301,L,NC]
How can I write a 301 redirect that both accounts for the tilde and the query parameter?
Thanks in advance for your help!
First your rule RewriteRule ^/~/bar.pdf?la https://www.bar.foo.com/foo.pdf [R=301,L,NC] has several issues .
First , RewriteRule ^/ it is not applicable here so RewriteRule ^ is enough.
Second , you should escape ~ like this RewriteRule ^\~
and finally , dont't write query string with RewriteRule like bar.pdf?la because it is not a pert of URI.
The line should look like this :
RewriteRule ^\~/bar.pdf https://www.bar.foo.com/foo.pdf [R=301,L,NC]
But the query string may append to new target , to prevent that add ? at the end of target this :
RewriteRule ^\~/bar.pdf https://www.bar.foo.com/foo.pdf? [R=301,L,NC]
If you want to use query string value , you may add condition before that to utilize it:
RewriteCond %{QUERY_STRING} ^(.*)$
you could change ^(.*)$ to whatever you want and you could use it in target like this example :
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^(.*)$ https://www.whatever.com/%1/$1 [R=301,L,NC]
So , %1 refer to this condition RewriteCond %{QUERY_STRING} ^(.*)$ and $1 refer to this condition RewriteRule ^(.*)$ and so on.
You need to use RewriteCond
directive to check the url query string. You can not do that in RewriteRule . The querystring in your url is la .
RewriteEngine on
RewriteCond ℅{QUERY_STRING} ^la$ [NC]
RewriteRule ^.*bar\.pdf$ /foo.pdf? [L,R=301]

Match string in REQUEST_URI and redirect to that match

I want to redirect the old URL /bakery/pie?id=55 or /bakery/cake?id=433 to /bakery/pie or /bakery/cake. I tried to redirect on match but I'm error log shows "Request exceeded the limit of 10 internal redirects"
This is running on WordPress.
RewriteEngine On
RewriteBase /
RewriteCond %{$REQUEST_URI} (pie|cake) [NC]
RewriteRule . /bakery/%1? [R,L]
What is wrong with the above configuration?
This finally gave me the result I was looking for and works with WordPress:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^id [NC]
RewriteCond %{REQUEST_URI} (cake|pie.*|des.*) [NC]
RewriteRule . /bakery/%1? [R,L]
%{$REQUEST_URI} is not correct variable it is %{REQUEST_URI}. Also you must check QUERY_STRING condition.
You can use:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^id=\d+ [NC]
RewriteRule ^bakery/(pie|cake)/?$ %{REQUEST_URI}? [NC,R,L]

How to remove any query except `callback` for specific URLs with RewriteRule?

The current RewriteRule removes any query except query callback for any URL.
# Remove question mark and parameters
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^?#\ ]*)\?[^\ ]*\ HTTP/ [NC]
# Query rewrite exceptions
##RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !^/api.*?callback=.* #does not work
RewriteCond %{QUERY_STRING} !callback=
RewriteRule .*$ %{REQUEST_URI}? [R=301,L]
How to avoid query callback rewrite just from URL ^api\/?([^\/]*)$? Excepted result:
no rewrite for /api?callback=1, /api/user?callback=1, /api/user/2?callback=1
rewrite for /apis?callback=1, /user?callback=1, /api/user?foo=1 etc.
I finally understood your question...
Replace these lines:
##RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !^/api.*?callback=.* #does not work
RewriteCond %{QUERY_STRING} !callback=
with this line:
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !^/api(/.*)?\?callback=.*
Important notice:
if your script isn't located in the document root, but, i.e., in dir /htest,
and full URL looks like mine: http://localhost/htest/api/?callback=1, then you have to put full path to API in your RewriteCond:
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !^/htest/api(/.*)?\?callback=.*
You can overcome that by beginning your regex with !/api instead of ^/path/to/api, but /foo/api and /bar/api will be skipped from rewriting too.
Update:
this .htaccess works fine in document root:
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^?#\ ]*)\?[^\ ]*\ HTTP/ [NC]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !^/api(/.*)?\?callback=.*
RewriteRule .*$ %{REQUEST_URI}? [R=temporary,L]
you may try using it without any other rules to check what is wrong
Update 2
If you have other condition, i.e.,
RewriteRule ^([^.]*)$ index.php?url=$1 [QSA,L]
repeat RewriteCond before it:
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !^/api(/.*)?\?callback=.*
RewriteRule ^([^.]*)$ index.php?url=$1 [QSA,L]
also to be able to use these rules in /foo subdir, replace ^/api with ^/foo/api
To enable RewriteRule for index.php, need to add in query rewrite exceptions.
This rules works fine and fixes this issue:
# Remove question mark and parameters
RewriteCond %{QUERY_STRING} .+
# Query rewrite exceptions
RewriteCond %{REQUEST_FILENAME} !index.php
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !/api(/.*)?\?callback=.*
RewriteRule .*$ %{REQUEST_URI}? [R=301,L]

Handle query parameters recursively using htaccess

I am here again with the query of re-writing URL :(.
I am using htaccess for re-writing, below is my htaccess code:
RewriteEngine On
RewriteBase /
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
RewriteCond %{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} !\.\w+$
RewriteCond %{REQUEST_URI} !/$
RewriteRule (.*) /$1/ [R,L]
RewriteCond %{REQUEST_URI} ^/([\w\d-]+)/$ [NC]
RewriteRule ^ /?file_name=%1 [L,QSA]
RewriteCond %{QUERY_STRING} !^$
RewriteCond %{QUERY_STRING} (?:(.*)&)?file_name=([\w\d-]+)(.*) [NC]
RewriteRule ^ %2/?%1%3 [L,R]
Before asking my queries let me give you short explanation about how above code is working. I have a URL like http://www.mysite.com/ (for index) and other pages could be executed by using a parameter called file_name=page_name like http://www.mysite.com/?file_name=my_blog. My htaccess is helping me to exclude the file_name parameter and make a new URL like http://www.mysite.com/my_blog/.
Now I do have a query:
Right now there is already a parameter file_name and now I want to give extra parameters like http://www.mysite.com/?file_name=my_blog&blog_alias=welcome-to-new-generation and wanted this to look like http://www.mysite.com/my_blog/welcome-to-new-generation/. So if I add any number of parameter there parameter name should be removed and only parameter value comes with slash.
Please note: Parameter name could be anything.
Please please please help.
This is a very interesting problem that requires recursive implementation of mod_rewrite rules. Put this code in your .htaccess:
Update II As per further comments, redirects /?file_name=my_blog&blog_alias=welcome-to-new-generation&foo=bar&n=v URI to /file_name+my_blog/blog_alias+welcome-to-new-generation/foo+bar/n+v
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# forwards ?file_name=my_blog&blog_alias=welcome-to-new-generation to
# /file_name=my_blog&blog_alias=welcome-to-new-generation
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+\?([^\s]+)\s [NC]
RewriteRule ^$ %1? [L]
# redirects /file_name=my_blog&blog_alias=welcome-to-new-generation&foo=bar&n=v
# to /file_name+my_blog/blog_alias+welcome-to-new-generation/fo+barn+/v
RewriteRule ^(.*/)?([^=]+)=([^&]+)&(.*)$ $1$2+$3/$4 [L]
RewriteRule ^(.*/)?([^=]+)=(.*)$ $1$2+$3 [L,R]
# internal forward from /file_name+my_blog/blog_alias+welcome-to-new-generation to
# /?file_name=my_blog&blog_alias=welcome-to-new-generation
RewriteRule ^([^\+]+)\+([^/]+)/(.*)$ $3?$1=$2 [L,QSA]
RewriteRule ^([^\+]+)\+([^/]+)/?$ /?$1=$2 [L,QSA]
Once you're sure it is working change R to R=301