Using htaccess to redirect anything after a parameter - regex - regex

Id like to have the following URL(s) redirect to the same URL just without the ?
For example:
https://www.example.com/this-is-static?numbersletterssymbols
goes to
https://www.example.com/this-is-static
"numbersletterssymbols" can be anything
Id like this to be a 301 , using htaccess ( apache )
I came across the following, however, the variable seems to be in parentheses
RewriteCond %{QUERY_STRING} ^product=(.*)$
RewriteRule ^test.php$ %1/? [R=301,L]
Any insight is appreciated

To remove the query string (any query string) from any URL you could do the following using mod_rewrite, near the top of your .htaccess file:
RewriteEngine On
RewriteCond %{QUERY_STRING} .
RewriteRule ^ %{REQUEST_URI} [QSD,R=301,L]
The condition (RewriteCond directive) simply asserts that there is a query string consisting of at least 1 character (determined by the regex . - a single dot).
The QSD (Query String Discard) flag removes the original query string from the redirected response. The QSD flag requires Apache 2.4 (which you are most probably using). The method used on earlier versions of Apache, as in your example, is to append a ? to the susbstitution string (essentially an empty query string).
Note that you should test first with a 302 (temporary) redirect to avoid potential caching issues.
however, the variable seems to be in parentheses
The parentheses in the regex simply creates a "capturing group" which can be referenced later with a backreference. eg. In your example, the value of the product URL parameter is referenced in the RewriteRule substitution string using the %1 backreference in order to redirect to the value of the URL parameter. This is very different to what you are trying to do and is arguably a security issue. eg. It would redirect a request for /test.php?product=https://malicious.com to https://malicious.com/, allowing a potential hacker to relay traffic via your site.
UPDATE: is it possible to make this work only for when the URL begins with "this-is-static" (for example)
Yes, the RewriteRule pattern (1st argument) matches the URL-path, less the slash prefix. For example:
RewriteCond %{QUERY_STRING} .
RewriteRule ^this-is-static %{REQUEST_URI} [QSD,R=301,L]
Matches all URLs that start with /this-is-static.

Related

RewriteRule redirect URL with query string in htaccess

I've no experience with regex, and the redirect rule I'm trying to put in my .htaccess file for a WordPress site is having no effect.
I want to redirect:
https://example.com/example/?person=name
to
https://example.com/example/people/name
From reading, I figure my rule ought to be:
RewriteRule \?person=(.*) https://example.com/example/people/$1 [R=301,L]
What am I missing/doing wrong?
From reading, I figure my rule ought to be:
RewriteRule \?person=(.*) https://example.com/example/people/$1 [R=301,L]
You can't match the query string part of the URL using the RewriteRule pattern. The RewriteRule pattern matches against the requested URL-path only. To match the query string you need to use a condition and check the QUERY_STRING server variable.
For example:
RewriteCond %{QUERY_STRING} ^person=([^&]*)
RewriteRule ^example/$ /example/people/%1 [QSD,R=302,L]
This needs to go before the existing WordPress directives.
This matches the URL-path exactly as stated in your question, ie. /example/.
%1 (as opposed to $1) is a backreference to the last matched condition, ie. the value of the person URL parameter, that occurs as the first URL parameter.
The QSD (Query String Discard) flag (Apache 2.4+) is required to remove the query string from the target URL. If you are still on Apache 2.2 then append an empty query string (ie. append a ?) to the end of the subsitution string instead.

RewriteRule to remove superfluous single "?" in URL

I am using IBM HTTP server configuration file to rewrite a URL redirected from CDN.
For some reason the URL comes with a superfluous single question mark even when there are no any query string. For example:
/index.html?
I'm in the process of making the 301 redirect for this. I want to remove the single "?" from the url but keep it if there is any query string.
Here's what I tried but it doesn't work:
RewriteRule ^/index.html? http://localhost/index.html [L,R=301]
update:
I tried this rule with correct regular expression but it never be triggered either.
RewriteRule ^/index.html\?$ http://localhost/index.html [L,R=301]
I tried to write another rule to rewrite "index.html" to "test.html" and I input "index.html?" in browser, it redirected me to "test.html?" but not "index.html".
You need to use a trick since RewriteRule implicitly matches against just the path component of the URL. The trick is looking at the unparsed original request line:
RewriteEngine ON
# literal ? followed by un-encoded space.
RewriteCond %{THE_REQUEST} "\? "
# Ironically the ? here means drop any query string.
RewriteRule ^/index.html /index.html? [R=301]
Question-mark is a Regular Expression special character, which means "the preceding character is optional". Your rule is actually matching index.htm or index.html.
Instead, try putting the question-mark in a "character class". This seems to be working for me:
RewriteRule ^/index.html[?]$ http://localhost/index.html [L,R=301]
($ to signify end-of-string, like ^ signifies start-of-string)
See http://publib.boulder.ibm.com/httpserv/manual60/mod/mod_rewrite.html (for your version of Apache, which is not the latest)
Note from our earlier attempts, escaping the question-mark doesn't seem to work.
Also, I'd push the CDN on why that question-mark is being sent. This doesn't seem a normal pattern.

mod_rewrite change a variable content

I am having a little trouble with apache mod_rewrite, I need to be able to modify (append) a variable name to something else depending the regex in another variable in the URL:
https://localhost:85/fight?shoes=baby.firstlove&type=textype&awesome=23481234
By this i mean that if "awesome=" is 234[8,7]1234, shoes=baby.firstlove should become shoes=baby.firstlovefirsttry, OR if awesome=234[1,2]1234, then shoes=baby.firstlove, should become shoes=baby.firstlovesecondtry .
My rewrites rule are something like this (trying to capture awesome=23411234 or awesome=23425678):
RewriteCond %{QUERY_STRING} shoes=(.+)\&awesome=(\b234(1|2)\d{4}\b)
RewriteRule ^(.*)$ http://localhost:85/fight?shoes=baby.firstloveactual&subscriber=%2 [P]
But they are not changing the "shoes=" variable content as expected.
The URL remains the same:
http://localhost:85/fight?shoes=baby.firstlove&type=textype&awesome=23481234
Please what am I doing wrong?
RewriteCond %{QUERY_STRING} shoes=(.*)\&awesome=(\b234(1|2)\d{4}\b)
Your regex does not match your example URL:
https://localhost:85/fight?shoes=baby.firstlove&type=textype&awesome=23481234
You have an 8 where your regex is expecting a 1 or 2. However, if you need to match one of a series of characters then you should use a character class (eg. [12]) rather than a parenthesised/capturing group. Also, I'm not sure what you are trying to do with the word boundaries (ie. \b)? What is the intention of using the P flag? Presumably you need to externally redirect?
But also, your code sample does not seem to match your textual description of the problem?
if "awesome=" is 234[8,7]1234, shoes=baby.firstlove should become shoes=baby.firstlovefirsttry
Try the following (assuming "1234" is the literal string, rather than any 4 digits):
RewriteCond %{QUERY_STRING} shoes=.+&awesome=(234[87]1234)
RewriteRule ^/?fight http://localhost:85/fight?shoes=baby.firstloveactual&subscriber=%1 [R,L]
You've used https in your example URLs, but http in your rewrite?

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.

How can I match query string variables with mod_rewrite?

Suppose I have URLs with query string parameters like these:
/index.php?book=DesignPatterns&page=139
/index.php?book=Refactoring&page=285
Using mod_rewrite, how can I redirect them to SES URLs like these?
/DesignPatterns/139
/Refactoring/285
RewriteCond %{QUERY_STRING} book=(\w+)&page=(\d+)
RewriteRule ^index.php /%1/%2? [L,R=301]
Because RewriteRule only looks at the path (up to but not including the question mark), use RewriteCond to capture the values in the query string.
Note that the matches from RewriteCond are captured in %1,
%2, etc., rather than $1, $2, etc.
Also note the ? at the end of RewriteRule. It tells mod_rewrite
not to append the original query string to the new URL, so you end up with
/DesignPatterns/151 intead of
/DesignPatterns/151?book=DesignPatterns&page=151.
The [L,R=301] flags do two things:
L ensures that no other rules that might otherwise match will be processed (in other words, it ensures this is the "last" rule processed).
R=301 causes the server to send back a redirect response.
Instead of rewriting, it tells the client to try again with the new
URL. The =301 makes it a permanent redirect, so that, among other things, search engines will know to replace the old URL with the new URL in their indexes.