RewriteCond: 2 parameters for QUERY_STRING - .htaccess

I am dealing with an API that is accessing an URL on my website and adding
/?parameter1=value&parameter2=value to the url. I want my htaccess to handle this request and only keep the parameter's values. The API is also adding many other parameters in the query string but I just want to keep two of them.
The following does not work:
RewriteCond %{QUERY_STRING} ^parameter1=([^&]+)
RewriteCond %{QUERY_STRING} ^parameter2=([^&]+)
RewriteRule ^my-url/?$ controller.php?parameter1=%1&parameter2=%2
How can I do that correctly?
EDIT:
Here is an example.
The url is:
http://example.com/my-url/?parameter1=value1&stuff=1&stuff2=2&parameter2=value2
The htaccess should get the parameter1 & parameter2 values.

Try this and just grab the two parameters in your server side code. e.g. $_GET. If they are always in the query string, you can just check for parameter1 and then it will append the other parameters and you can get what you need.
RewriteCond %{QUERY_STRING} ^\bparameter1=
RewriteRule ^my-url/?$ controller.php [QSA,L]

Try the following:
RewriteEngine On
RewriteCond %{THE_REQUEST} ^(GET|POST)\ /my-url/\?parameter1=(.*)&stuff=(.*)&stuff2=(.*)&parameter2=(.*)\ HTTP
RewriteRule ^ /controller.php?parameter1=%2&parameter2=%5\? [R,L]
Mind it will only get the two parameters if there are always &stuff=1&stuff2=2 those two values in the url.

I've had to do a similar setup with key/value pairs in the GET which could come in any order depending on the client platform.
Based on useful pointers in this thread, this is what I came up with based on the question above:
#= 1. Catch parameter1, append querystring as "p1=". Rewrite to "/parameter1" below:
RewriteCond %{REQUEST_URI} ^/my-url/$
RewriteCond %{QUERY_STRING} ^parameter1=([^&]+)
RewriteRule (.*) /parameter1?%{QUERY_STRING}&p1=%1 [P,QSD]
#= 2. Catch parameter2, append querystring as "p2=". Rewrite to "/parameter2" below:
RewriteCond %{REQUEST_URI} ^/parameter1$
RewriteCond %{QUERY_STRING} ^parameter2=([^&]+)
RewriteRule (.*) /parameter2?%{QUERY_STRING}&p2=%1 [P,QSD]
#= 3. Now explicitly catch p1,p2 and feed to them to the back-end url:
RewriteCond %{REQUEST_URI} ^/parameter2$
RewriteCond %{QUERY_STRING} p1\=([^&]+)&p2\=([^&]+)$
RewriteRule (.*) controller.php?parameter1=%1&parameter2=%2 [P,L,QSD]
The above works fine for me but I do notice it a tiny bit slow to process, so if anyone has any criticism then I would be glad to hear it!

Related

.htaccess - How to remove an end part of a url?

I would like to redirect the following urls from:
http://example.com/index.php/item123-detail?tmpl=component&format=pdf
to:
http://example.com/index.php/item123-detail
In essence removing the "?tmpl=component&format=pdf" from all urls.
I have tried multiple different examples from other Stack questions without luck so far. Any help would be much appreciated. Thank you.
This part of URL ?tmpl=component&format=pdf called QUERY_STRING and if you want to remove it from any request you could do several scenarios like putting this code at main directory .htaccess this :
RewriteEngine On
RewriteCond %{THE_REQUEST} \?
RewriteRule ^(.*)$ /$1? [L,R=301]
So , by the code above you will be able to remove even request with ? only.
If you want to match only this query string and keep others , let me know to give you another scenario with another condition RewriteCond %{QUERY_STRING}
Ok , to match only this query string , replace the code with :
RewriteEngine On
RewriteCond %{QUERY_STRING} ^tmpl=component&format=pdf$
RewriteRule ^(.*)$ /$1? [L,R=301]
And if tmpl & format values not fixed and come only into letters, replace the code with:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^tmpl=([a-zA-Z]+)&format=([a-zA-Z]+)$
RewriteRule ^(.*)$ /$1? [L,R=301]
Solution found on another post as follows:
remove query string from end of url URL using .htaccess
RewriteCond %{QUERY_STRING} "post_type=" [NC]
RewriteRule (.*) /$1? [R=301,L]

Reference capture groups of multiple RewriteCond in RewriteRule

When I have multiple RewriteCond chained together, only the capture groups of the last RewriteCond can be referenced with %0-%9.
In the following problem the parameters in the query string of the url can be in any order. To parse them into a fancy url I would need to match each parameter in the query string individually:
RewriteCond %{QUERY_STRING} param1=([^&]+)
RewriteCond %{QUERY_STRING} param2=([^&]+)
RewriteCond %{QUERY_STRING} param3=([^&]+)
RewriteRule ^foo$ bar/%1/%2/%3/ [R]
Like I pointed out... this doesn't work. To fix this, I could reference the capture group of the previous RewriteCond in the next RewriteCond and 'propagate' each parameter to the actual RewriteRule:
RewriteCond %{QUERY_STRING} param1=([^&]+)
RewriteCond %1&%{QUERY_STRING} ^([^&]*)&.*param2=([^&]+)
RewriteCond %1&%2&%{QUERY_STRING} ^([^&]*)&([^&]*)&.*param3=([^&]+)
RewriteRule ^foo$ bar/%1/%2/%3/ [R]
This should work, but for each additional parameter it get's messier. An other solution could possibly be parsing one parameter and redirecting the client after each parameter (resulting in a lengthy chain of redirects, which I would like to avoid).
Is there an cleaner way of accessing the capture groups of all RewriteCond's in the RewriteRule (e.g. is it possible to name them or assign them to a variable so I can reference them somewhere else?)
You could try constructing the target URL inside the rewrite conditions:
RewriteCond ##%{QUERY_STRING} (.*)##(|.*&)param1=([^&]+)
RewriteCond %1/%3##%{QUERY_STRING} (.*)##(|.*&)param2=([^&]+)
RewriteCond %1/%3##%{QUERY_STRING} (.*)##(|.*&)param3=([^&]+)
RewriteCond %1/%3##%{QUERY_STRING} (.*)##(|.*&)param4=([^&]+)
RewriteCond %1/%3##%{QUERY_STRING} (.*)##(|.*&)param5=([^&]+)
RewriteCond %1/%3##%{QUERY_STRING} (.*)##(|.*&)param6=([^&]+)
RewriteRule ^foo$ /bar%1/%3? [L,R]
When I try to request:
/foo?param1=a&param2=b&param6=3&param3=4&param5=5&param4=6
I get redirected to:
/bar/a/b/4/6/5/3
Adding any additional required query string parameters won't make it look any more messy than it already is.
After experimenting some more, it would be possible to parse all parameters as environment variables and use them like that. I doubt it is very efficient though and I think any use-case that would need such a construction would be better of using a php page router. For fancy url's Jon Lin's solution would probably work better. It does however sort-of mimic what I had in mind.
I'll, however, put the code in here for demonstration:
#Parse all query key-value pairs to an environment variable with the q- prefix
RewriteCond %{QUERY_STRING} ^([^=]*)=([^&]*)(&(.*)|$)$
RewriteRule ^(.*)$ $1?%4 [E=q-%1:%2,N]
#If 'param1' existed in the query string...
RewriteCond %{ENV:q-param1} !^$
RewriteRule ^foo$ bar/%{ENV:q-param1} [END]
or even...
#Keep the original query string
RewriteCond %{ENV:qstring} ^$
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule .* - [E=qstring:#%1]
#parse the query parameters to environment variables
RewriteCond %{ENV:qstring} ^#([^=]*)=([^&]*)(&(.*)|$)$
RewriteRule ^(.*)$ - [E=q-%1:%2,E=qstring:#%4,N]
#See that the original query string is still intact
RewriteCond %{ENV:q-param1} !^$
RewriteRule ^foo$ bar/%{ENV:q-param1} [QSA]

Having Difficulty Getting a Proper Redirect from .htaccess

I am having difficulty getting a proper redirect from .htaccess. The redirect that I am attempting is the following:
Original URL:
http://www.mysite.com/index.php/contact-us?id=12
Should Direct to:
http://www.mysite.com/index.php/new-contact-request-form
I have attempted a variety of variations on the following samples with no luck. Any ideas on where I’m going wrong?
Example 1:
Redirect /index.php/contact-us?id=12 http://www.mysite.com/index.php/new-contact-request-form
Example 2:
RewriteCond %{QUERY_STRING} ^index.php/contact-us?id=12$
RewriteRule ^index\.php\/new\-contact\-request\-form$ http://www.mysite.com/? [R=301,L]
Example 3:
RewriteCond %{HTTP_HOST} ^mysite\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.mysite\.com\/index\.php\/contact\-us\?id\=12$
RewriteRule ^/?$ "http\:\/\/www\.mysite\.com\/index\.php\/new\-contact\-request\-form" [R=301,L]
URL structure:
%{QUERY_STRING} variable contains the url query string (which is in our case id=12),
in the other hand, RewriteRule operates on the url path only (not including the query string),
so basically , the code below check if the query string is equal to id=12 and if the url path is equal to index.php/contact-us , if so, a redirection will take place
RewriteEngine on
RewriteCond %{QUERY_STRING} ^id=12$
RewriteRule ^index\.php/contact\-us$ /index.php/new-contact-request-form? [R=301,L]

URL rewriting via my .htaccess file

How do I change example.com/1 to example.com/?id=1
I've tried googling but I can only find code for example.com/?id=1 to example.com/1
I used a generator and got this, but it didn't work
RewriteEngine On
RewriteRule ^\?get\=$ / [L]
Thanks,
Isaac
It kind of depends on which way you want to do the rewrite - ie, what does the user type see, and what does the server do.
If you want the user to see "http://example.com/1" and internally the server provides "http://example.com/?id=1", then the following should work:
RewriteRule ^([0-9]+)$ /?id=$1
However, if you want the user see "http://example.com/?id=1", and internally the server provides "http://example.com/1", then the following, as per Jon Lin's answer, should do it:
RewriteCond %{QUERY_STRING} ^id=([0-9]+)$
RewriteRule ^$ /%1?
You can't match against the query string in a RewriteRule statement, you need to use a RewriteCond and the %{QUERY_STRING} variable:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^id=([0-9]+)$
RewriteRule ^$ /%1? [L]
The ? is needed in the rule's target to remove the query string.

PHP RewriteRule detect if url contain "string" and replace

This may be a basic question regarding RewriteRule but I just counldn't make it work.
What I want to do is detect urls like:
mydomain/myapp/id/some/random/url.html?param=somethingThatIdoUse
mydomain/myapp/id/other/randomabc/perrito.php?param=somethingThatIdoUse
...
The part that I need to discart is from the /id/[all this]?param=somethingIdoUse and use the param if is possible or send the complete url as param so I can regex to get the param.
And have a rule that detect that /id/ exist and redirect to something like:
mydomain/myapp/other/manageRequest.php?params=somethingThatIdoUse
(the params I could get the whole url and strip it as string is no problem)
As well the application have different modules like:
mydomain/myapp/moduleOne/index.php
mydomain/myapp/moduleTwo/index.php
This have to keep working the same.
As far I've tried some of them like:
RewriteEngine On
RewriteCond %{THE_REQUEST} ^GET /.*;.* HTTP/
RewriteCond %{QUERY_STRING} !^$
RewriteRule .* http://localhostdev/app/index.php %{REQUEST_URI}? [R=301,L]
RewriteEngine On
RewriteBase /spt/
RewriteCond %{REQUEST_FILENAME} !^id$ [NC]
RewriteRule ^(.*)$ index.php [R=301,L]
RewriteEngine On
RewriteCond %{REQUEST_URI} !/campaings/response\.php$
RewriteRule ^/something/(.*) /other/manageRequest.php? [L]
But nothing seamed to do kind of what I needed.
Thanks in advice
mydomain/myapp/id/some/random/url.html?param=somethingThatIdoUse
Here is an example using the above URL:
RewriteRule ^id/some/random/url.html/? /myapp/other/manageRequest.php [L,NC]
The query will be passed through unchanged to the substitution URL
well actually end up being really basic it worked with:
RewriteRule ^.*id.*$ handleRequest.php [NC,L]
I do get the params as they are sent!

Resources