.htaccess RewriteRule - matching patterns & forwarding posts - regex

I'm trying to write a rule that maintains legacy urls with a rule that matches a pattern but I would like to add something that redirects url posts as well. I'm not good a this htaccess stuff. Here is a scenario:
Legacy URL:
www.blah.com/register/player
Legacy RewriteRule:
RewriteRule ^register/(.*)/?$ /account/register.php?type=$1 [NC,L]
New URL:
www.blah.com/register/player?email=bob#g.com
New RewriteRule???
RewriteRule ^register/(.*)/?$ /account/register.php?type=$1 [NC,P]
I found this post Is it possible to redirect post data? that helped me find the P flag which works without the pattern match but it doesn't work when I try to do both.
I don't want to just add another pattern match because my url post data can be arbitrary with more then one param (the case described above is simplified). It seems like this should be doable. Is it? Thanks.

Seems like you need the query string attached on redirect, hence the QSA flag
Try:
RewriteRule ^register/(.*)/?$ /account/register.php?type=$1 [QSA,NC,P]

Related

Redirect Query String via .htaccess

I'm trying to redirect the user via the .htaccess file to create friendly URL example:
UI URL: https://example.com/courses/1
htaccess role
RewriteEngine On
RewriteRule ^courses/([0-9]{1})$ /courses.php?page=$1
Output URL: https://example.com/courses.php?page=1
And everything is working fine, Now I need to add other query params to the URL like this http://smart-courses.com/courses/1?p1=1&p2=2 so, I need htaccess to redirect me to https://example.com/courses.php?page=1&p1=1&p2=2
I tried to create a new role to check if p1 and p2 are exists and rewrite the URL
RewriteRule ^courses/([0-9]{1,5})?lid=([0-9]{1,})&did=([0-9]{1,})$ /courses.php?page=$1&p1=$2&p1=$3
Also, I tried to take any chars after ([0-9]{1,5}) (page number) and put it after ?page=1 but it did not worked
RewriteRule ^courses/([0-9]{1})\?(.*)$ /courses.php?page=$1&$2
The query string is not part of the path section of the URL that the rule pattern is matched against. If you'd have to capture something from the query string you need to use a RewritetCond, that is documented. In this case however you don't even need to capture anything:
RewriteEngine On
RewriteRule ^/?courses/(\d)$ /courses.php?page=$1 [QSA]
The QSA flag adds a potential query string to the (rewritten) target URL. The rewriting module takes care to use the correct concatenation here (the & character). Again, this behavior is documented: https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html
Take a look yourself: htaccess.madewithlove.com

Apache2: Rewrite url containing question mark

I am using Apache 2.4.7. I use mod_rewrite to alter some urls.
I want to rewrite http://example.com/servicename/oldpage?id=abcto http://example.com/servicename/newpage.
Other similar rewrites work so I belive the ? inside url is causing problems.
I have tried escaping it with \.
This works as there is no ? in url:
RewriteRule ^/servicename/old /servicename/new
But these don't work:
RewriteRule ^/servicename/oldpage?id=abc /servicename/newpage
RewriteRule ^/servicename/oldpage\?id=abc /servicename/newpage
I have also tried using RewriteCond from examples like this: .htaccess rewrite URL with a question mark "?" but I didn't manage to get them work.
How should rewrite url that contains question mark?
EDIT: I tried solutions given in Match Question Mark in mod_rewrite rule regex but was not able to make them work for me. That question is about preserving query string when rewrite while I want to remove it when rewriting.
RewriteRule pattern is matched against the part of the URL after the hostname and port, and before the query string.
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.
So, this should work:
RewriteRule ^/servicename/oldpage /servicename/newpage [QSD]

Conditional htaccess RewriteRule

I'm trying to create a rewrite rule to redirect to a URL based on a conidtion.
I have had a look on-line for similar questions but am finding myself confused.
My rewrite rule looks like follows:
RewriteRule ^rates/(\w+)/?$ http://www.url.co.uk/rates/result.php?quotenum=$1 [R,L]
For example, this will redirect any combination of characters after the URL
www.url.co.uk/rates/1234
to
www.url.co.uk/rates/result.php?quotenum=1234
I am creating an admin page as well which will sit at the URL:
www.url.co.uk/rates/admin
How do I modify my rewrite rule to prevent the redirection of the URL to
www.url.co.uk/rates/result.php?quotenum=admin
When the URL is equal to
www.url.co.uk/rates/admin
This should work:
RewriteRule ^rates/((?!admin/?$)\w+)/?$ http://www.url.co.uk/rates/result.php?quotenum=$1 [R,L,NC]
(?!admin/?$) is a negative lookahead that will not match given regex if URI is /rates/admin OR /rates/admin

How to rewrite this URL to a redirect page?

I am using Microsoft-IIS/7.5 on a hosted server (Hostek.com)
I have an existing site with 2,820 indexed links in Google. You can see the results by searching Google with this: site:flyingpiston.com Most of the pages use a section, makerid, or bikeid to get the right information. Most of the links look like this:
flyingpiston.com/?BikeID=1068
flyingpiston.com/?MakerID=1441
flyingpiston.com/?Section=Maker&MakerID=1441
flyingpiston.com/?Section=Bike&BikeID=1234
On the new site, I am doing URL rewriting using .htaccess. The new URLs will look like this:
flyingpiston.com/bike/1068/
flyingpiston.com/maker/1123/
Basically, I just want to use my htaccess file to direct any request with a "?" question mark in it directly a coldfusion page called redirect.cfm. On this page, I will use ColdFusion to write a custom 301 redirect. Here's what ColdFusion's redirect looks like:
<cfheader statuscode="301" statustext="Moved Permanently">
<cfheader name="Location" value="http://www.newurl/bike/1233/">
<cfabort>
So, what does my htaccess file need to look like if I want to push everything with a question mark to a particular page? Here's what I have tried, but it's not working.
RewriteEngine on
RewriteRule ^? /redirect.cfm [NS,L]
Update. Using the advice from below, I am using this rule:
RewriteRule \? /redirect/redirect.cfm [NS,L]
To try to push this request
http://flyingpiston2012-com.securec37.ezhostingserver.com/?bikeid=1235
To this page:
http://flyingpiston2012-com.securec37.ezhostingserver.com/redirect/redirect.cfm
There's a couple of reasons what you're trying isn't working.
The first one is that RewriteRule uses a regex, and ? is a regex metacharacter, which therefore needs be escaped with a backslash (\?) to tell it to match the literal question mark character.
However, the second part of the problem is that the regex for RewriteRule is only tested against the filename part of the URL - it specifically excludes the query string.
In order to match against the query string you need to use the RewriteCond directive, placed on the line before the rule (but applied in between the RewriteRule matching and replacing), acting as an additional filter. The useful bit is that you can specify which part of the URL to match against (as well as having the option for using non-regex tests).
Bearing all this in mind, the simplest way to match/rewrite a request with a query string is:
RewriteCond %{QUERY_STRING} .
RewriteRule .* /redirect/redirect.cfm
The %{QUERY_STRING} is what the regex is tested against (everything in CF's CGI scope can be used here, and some other stuff too - see the Server Variables box in the docs).
The single . just says "make sure the matched item has any single character"
At the moment, this rule will preserve the existing query string - if you want to discard it, you can place a ? onto the end of the replacement URL. (If you need to use a query string on the URL and not discard the old version, use the [QSA] flag.)
In the opposite direction, you're losing the filename part of the URL - to preserve this, you probably want to append it onto the replacement as PATH_INFO, using the automatic whole-match capture $0.
These two things together provides:
RewriteCond %{QUERY_STRING} .
RewriteRule .* /redirect/redirect.cfm/$0?
One final thing is that you'll want to guard against infinite loops - the above rule strips the query string so it will always fail the RewriteCond, but better to be safe (especially if you might need to add a query string), which you can do with an extra RewriteCond:
RewriteCond %{QUERY_STRING} .
RewriteCond %{REQUEST_URI} !/redirect/redirect\.cfm
RewriteRule .* /redirect/redirect.cfm/$0?
Multiple RewriteCond are combined as ANDs, and the ! negates the match.
You can of course add whatever flags are required to the RewriteRule to have it behave as desired.

Apache mod_rewrite encoded URLs

I'm working on a webpage that takes a URL as a parameter, and would like it to be easily indexed by search engines. One requirement is that each URL appears as a directory.
My script is in the format:
myscript?url=<a url>&page=1
I'd like redirects to look something like:
lookup/<a url>/page:1/
The URL is predictably giving me trouble... I just want to tell mod_rewrite to select anything after "lookup/" and before "/page:". Of course, nothing is ever as simple as it could be.
Here's the rewrite as it is now:
RewriteEngine on
RewriteRule ^/lookup/(.+)/page:([0-9]+)(/?)$ /myscript?url=$1&page=$2 [L]
This works great, except it fails when URLs are properly encoded. Take the example of "www.google.com/finance". Here's what happens when I enter these URLs into my browser's address bar:
#this works
lookup/www.google.com/finance/page:1/
#this doesn't work. url is cut off before the ?
lookup/www.google.com/finance?foo=bar/page:1/
#doesn't match rewrite at all!
lookup/www.google.com%2Ffinance/page:1/
I'm at a loss as to how to do this... Shouldn't (.+) select anything? Do I need to tell mod_rewrite to ignore query parameters somehow?
Try this:
RewriteCond %{THE_REQUEST} ^GET\ /lookup/([^\s]+)/page:([0-9]+)/[?\s]
RewriteRule ^/lookup/ /myscript?url=%1&page=%2 [L]
But you should really consider encoding that embedded URL properly instead of just guessing where it might end. So /lookup/www.google.com/finance?foo=bar/page:1/ should be at least /lookup/www.google.com/finance%3Ffoo=bar/page:1/ so the ? is part of the URI path and not the indicator for the query.