RewriteCond - rewrite query if it contains "bar" and "foo" - mod-rewrite

This rule will rewrite the query if it contains "foo" anywhere in the string.
RewriteCond %{QUERY_STRING} ^(.*)foo(.*)$
RewriteRule ^(.*)$ $1?%1qux%2 [R=301,L]
What should be added to make it rewrite "foo" only if the string contains "bar" somewhere before "foo". A real-life example would be
/bar?a=x&foo=y

Your question is more a question about RegEx (regular expressions), actually.
You would need to change your rewrite condition to the following to also match for bar somewhere before foo in the same query string:
RewriteCond %{QUERY_STRING} ^(.*)bar(.*)foo(.*)$

Related

ISAPI_REWRITE a simple search and replace?

Using ISAPI REWRITE v3
I need to replace a string in an URL. The old string is 'p=type1_' and the new is 'p=type2_'. So
http://www.somesite.com/cgi-bin/script.pl?t=something&p=type1_abcde
becomes
http://www.somesite.com/cgi-bin/script.pl?t=something&p=type2_abcde
I reckon this should work:
RewriteRule ^(.*)p=type1_(.*)$ $1p=type2_$2 [NC]
But I get a 'Pattern Not Matched' in the ISAPI_REWRITE RegexTest app as soon as the original string contains a '?' - which, in practice, it always would.
How do I do this simple search and replace?
You will need to use RewriteCond %{QUERY_STRING} to search the querystring.
Try something like this:
RewriteCond %{QUERY_STRING} t=(.*)&p=type1_(.*)
RewriteRule ^cgi-bin/script.pl$ cgi-bin/script.pl?t=$1&p=type2_$2 [NC]

Rewrite URL so that query string is in path

I'm trying to get the following path: /faculty/index.php?PID=FirstLast&type=alpha
To rewrite to this: /faculty/FirstLast
Am I correct to assume the following would be acceptable to put in .htaccess?
# Rewrite old URLS
RewriteCond %{QUERY_STRING} ^PID=([0-9a-zA-Z]*)$
RewriteRule ^/faculty/index.php$ /faculty/%1 [R=302,L]
I'm okay to throw away any other query string variables. I'm applying these rules at the .htaccess file level. This project is a migration from an older system into Drupal.
Outcome:
My .htaccess looks like
# Rewrite old URLS
RewriteCond %{QUERY_STRING} PID=([0-9a-zA-Z]*)
RewriteRule ^faculty/ /faculty/%1/? [R=301,L]
RewriteCond %{QUERY_STRING} vidID=([0-9]*)
RewriteRule ^videos/ /video/id/%1/? [R=301,L]
I also found this wonderful tool -- a mod_rewrite tester
http://htaccess.madewithlove.be/
All good!
Try this instead:
RewriteRule ^faculty/index.php$ /faculty/%1? [R=302,L]
The leading slash is not in the URI-path tested in the rule, so can't be in the regex either.
As the query is automatically appended to the substitution URL (passed through unchanged) unless a new query is created in the rule, the trailing question mark ? erases the existing query string when the rule is used.

.htaccess $_GET['p'] not working

With this url http://www.example.com/cp/pending/thepage, when i $_GET['p']; i should get thepage returned. Nothing is being returned, How do i solve this?
Here is the mod rewrite.
RewriteRule ^cp/([A-Za-z0-9-]+)(&type=[A-Za-z0-9-]+)?(/[A-Za-z0-9-]+)?(&to=[A-Za-z0-9-]+)?(&r=[A-Za-z0-9-]+)?(&g=[A-Za-z0-9-]+)?(&page=[A-Za-z0-9-]+)?/?$ /cp.php?o=$1&type=$2&c=$3&p=$4&r=$5&g=$6&page=$7 [L]
Here is php
$p = $_GET['p'];
echo $p;
The query string is not part of the URL.
Your code should be like the following:
RewriteCond %{QUERY_STRING} RegexHere
RewriteRule URLRegexHere NewURL
If you use any part of the URL to create a new query string, you need to use the [QSA] flag to append the other parameters. E.g:
RewriteRule ^cp/pending/([^/])/?$ page.php?page=$1 [L,QSA]
More on Mod_Rewrite here.
Also, just as $n back-references are for patterns matched in the RewriteRule regex, %n back-references are for pattern matched in the RewriteCond regex.

mod_rewrite RewriteRule pattern match fails when query string is URL-encoded

I am trying to use mod_rewrite RewriteRule, and in my RewriteRule, I am trying to match a URL that has query string that looks like:
http:///myfakeoam/obrareq.cgi?....
My RewriteRule looks like:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^wh=(.*)$ [NC]
RewriteRule ^/myfakeoam/obrareq.cgi$ http://apache1.whatever.com/formbasicprotected/index.html [CO=wh:%1:.whatever.com:1440:/]
When I test manually, by manually typing the URL into the browser, that RewriteRule seems to be able match a request if the request looks like:
http:///myfakeoam/obrareq.cgi?wh=xxx&ru=yyyy&....
but, in my actual system, the request is being created by anoher app, and it appears to be URL-encoding (actually URL-encoding twice) the query string (e.g, replacing equal with "%3D", etc.), i.e.:
http:///myfakeoam/obrareq.cgi?wh%3Dxxx....
And if the query string part is URL-encoded like that the pattern match in my RewriteRule is not failing...
Is there any way to handle this situation?
Thanks,
Jim
Answering my own question, I just realized that the RewriteCond was just doing a regex match for the query string, so I changed that to:
RewriteCond %{QUERY_STRING} ^wh%3D(.*)$ [NC]
and then it worked.
Jim

mod_rewrite: match only if no previous rules have matched?

I've got a large set of rewrite rules like the following:
RewriteRule ^foo foo.php?blah [L]
RewriteRule ^bar foo.php?baz [L]
And then I have a sort of catch-all rule that I want to only apply if the above rules don't match (e.g. for, say /blatz). As long as I remember to include the [L], that works fine -- but I've already had issues twice with accidentally forgetting it.
Is there any easy way to to force my catch-all rule to not match if an earlier rule has matched? (ideally, without appending something to every rule)
The only solution that I can image is to either use the S flag to skip the last rule:
RewriteRule ^foo foo.php?blah [L,S=999]
RewriteRule ^bar foo.php?baz [L,S=999]
RewriteRule …
Or to set an environment variable:
RewriteRule ^foo foo.php?blah [L,E=FLAG:1]
RewriteRule ^bar foo.php?baz [L,E=FLAG:1]
RewriteCond %{ENV:FLAG} ^$
RewriteRule …
Edit    Alright, here’s another solution that compares the current URL with the originally requested one:
RewriteCond %{THE_REQUEST} ^[A-Z]+\ (/[^?\s]*)\??([^\s]*)
RewriteCond %{REQUEST_URI}?%{QUERY_STRING}<%1?%2 ^([^<]*)<\1$
RewriteRule …
But I think that requires at least Apache 2 because Apache 1.x used POSIX ERE and POSIX ERE don’t support the \n backreferences in the pattern.

Resources