Isapi Rewrite - access query string pattern matches in RewriteRule - mod-rewrite

I'm using Isapi Rewrite 3 (mod rewrite clone for IIS) and trying to rewrite URLs based on the query string - and then pass on part of that query string in the rewrite.
So if I enter a URL like this: /test/home.cfm?page=default&arbitraryExtraArg=123
I want that to be rewritten as: /test/index.cfm?page=home&arbitraryExtraArg=123
I have the following condition/rule:
RewriteCond %{QUERY_STRING} ^page=default(.*)$ [I]
RewriteRule ^/test/home.cfm$ /test/index.cfm?page=home%1 [I,R=301]
But the extra query string variables are never passed. %1 seems to be blank.
This is how to reference a pattern match from the RewriteCond, right?
What am I missing here?
Thanks!
EDIT: It looks to me like the RewriteCond is being totally ignored. Here is what my logfile looks like:
[snip] (2) init rewrite engine with requested uri /test/home.cfm?page=default
[snip] (1) Htaccess process request C:\Inetpub\wwwroot\dev\IsapiRewrite\httpd.conf
[snip] (3) applying pattern '^/test/home\.cfm$' to uri '/test/home.cfm'
[snip] (1) escaping /test/index.cfm?page=home
[snip] (2) explicitly forcing redirect with http://www.devsite.com/test/index.cfm?page=home
[snip] (2) internal redirect with /test/home.cfm?page=default [INTERNAL REDIRECT]
[snip] (2) init rewrite engine with requested uri /test/index.cfm?page=home
[snip] (1) Htaccess process request C:\Inetpub\wwwroot\dev\IsapiRewrite\httpd.conf
[snip] (3) applying pattern '^/test/home\.cfm$' to uri '/test/index.cfm'
Should there be mention of the RewriteCond pattern check in there?

But the extra query string variables are never passed. %1 seems to be blank.
%1 is blank because according to the log the request you make is /test/home.cfm?page=default - without second parameter.
The absense of RewriteCond processing in the log may be due to low RewriteLogLevel.
And the config should be:
RewriteCond %{QUERY_STRING} ^page=default(.+)$ [NC]
RewriteRule ^/test/home.cfm$ /test/index.cfm?page=home%1 [NC,R=301,L]

I think ISAPI Rewrite is a little different to mod_rewrite:
Whenever you put parentheses in any regular expression present in a complex rule (a rule with conditions) you are marking a submatch that could be used in a format string (using $N syntax) or as a back-reference (using \N syntax) in subsequent conditions. These submathces are global for the whole complex rule (RewriteRule directive and corresponding RewriteCond directives). Submatches are numbered from up to down and from left to right beginning from the first RewriteCond directive (if such directive exists) corresponding to the RewriteRule.
So try $1 to get the match of the first group no matter where it appears:
RewriteCond %{QUERY_STRING} ^page=default(.*)$ [I]
RewriteRule ^/test/home\.cfm$ /test/index.cfm?page=home$1 [I,R=301]
ISAPI Rewrite 3 seems to be more compatible to Apache’s mod_rewrite.

I believe this works also:
RewriteRule ^/test/home.cfm\?page=default(.*)$ /test/index.cfm?page=home%1 [I,R=301]

Related

Replace html encoding with url encoding

We are getting random hits like:
/abc?p=2&utm_campaign=xyz-campaign&utm_medium=email&utm_source=newsletter
Notice & which is html encoding for &. I have checked the possible sources but they all contain '&' only.
I want replace all & with &. Is there a way to achieve it? I have removed complete string as of now using below given rule. But this is not right!
RewriteCond %{QUERY_STRING} (&)
RewriteRule (.*?) https://%{HTTP_HOST}%{REQUEST_URI}? [R=302,L]
Capture the referer in your logs so you can find the source of the problem and (also) fix it there.
RewriteCond %{THE_REQUEST} ^\S++\s++([^\s?]*+\?\S*?&)amp;(\S*+)
RewriteRule ^ %1%2 [DPI,L,R=301]
That will do one redirect per ampersand without messing about decoding and re-encoding the URL. Less efficient but more reliable.

mod_rewrite, help me forward a page

I'm sorry but I don't really completely understand how mod_rewrite works but I'd like to basically change the url:
/index.php?category=value1&video=value2
to be accessed via /value1/value2
could anybody tell me how to do this? thanks^^
Try this one here:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/?(.*)/(.*)$ index.php?category=$1&video=$2 [L]
The first line enabled the usage from the mod_rewrite.
The second line is a condition which checks if there is a file with that name. If not continue with the next line.
The third one is a regular expression. The ^ markes the beginning and the $ the end of it. The /? means that at the beginning should be a optional / (this depends on the server configuration). The (.*) meanes a range of chars which from 0 until n. The brackets meanes that there is a group which can be called as $n here as $1 and $2.
Please note that AllowOverride All must be enabled in the server configuration.

Trying to write a mod_rewrite rule

I've changed my CMS and need to write a mod_rewrite rule to help redirect some of the old URLs.
What I'd like to do is:
remove "blog/archives"
replace underscores with dashes
replace ".html" with a trailing slash
The old link:
http://example.com/blog/archives/the_post_title.html
The new link
http://example.com/the-post-title/
To address 1 & 3 I thought something along the lines of this might work, but it's not.
RewriteRule ^/blog/archives/([A-Za-z0-9-]+)/?.html$ $1 [L]
Thanks for your suggestions.
For 1 and 3
RewriteRule ^/blog/archives/(.*?).html$ /$1/ [L,R=permanent]
(note that R=permanent use a 301 redirect, which will be cached for long time but does move your pagerank to the new URL. Use [L,R] to use normal redirection)

Explain this rewrite rule?

I have managed to put this condition and rule below together to redirect a page to include index.shtml at the end of it but I dont understand what this part of the Rewrite means - the ^$ part. I believe ^ means start and $ is end but in this context I dont understand its meaning in "English" and how it works:
RewriteCond %{HTTP_HOST} ^www\.example1\.test\.com [NC]
RewriteRule ^$ http://www.example1.test.com/index.shtml [R,L]
Thanks.
^ is the start of the string, $ is the end. If there's nothing in between, as in the case of ^$, that means an empty string. Since the path leading up to the current directory is ignored, the part of the URL that matches is after the http://www.example1.test.com/. Matching an "empty string" after that means matching the URL itself, as in: with no file or anything else specified. So, this redirects the root URL to index.shtml
If a user visits the exact URL www.example1.test.com he or she is redirected to http://www.example1.test.com/index.shtml.
Useful tool: http://martinmelin.se/rewrite-rule-tester/

why doesn't this rewrite the url properly?

RewriteCond %{REQUEST_URI} !^/?new.php?url
RewriteRule ^/?(.+)\.?(.+)$ new.php?url=$0 [L]
its supposed to take any URL
mysite.com/someurl
and convert it to
new.php?url=someurl
however it keeps going to just new.php
You need to escape the second question mark in the first line so it matches a literal question mark:
RewriteCond %{REQUEST_URI} !^/?new.php\?url
Also you are not using the parenthesized groups on the second line. $0 is okay, or you may want $1 instead. If you use $0 you could simplify it a bunch:
RewriteRule ^.*$ new.php?url=$0 [L]
Or on the other hand if you're breaking apart the URL for a reason I would suggest some fixup. You're not matching the file name and extension exactly right. A little more complex regex like this would probably do you better:
RewriteRule ^/?(.*?)(?:\.([^.]*))?$ new.php?path=$1&extension=$2 [L]
Explanation:
(.*?) matches the directory and file name. The ? means match non-greedily, so stop as soon as the next part matches. The parentheses cause it to be captured and stored in $1.
(?:\.([^.]*))? matches the file extension. ?: turns says to not capture the outer set of parentheses, so the dot is not captured in $2. ([^.]*) matches the extension and ensures that it does not contain a dot. The final ? makes the file extension part optional, just cause not all URLs have file extensions. Thus there will only be a $2 if there is a file extension.
The first back-reference is $1 not $0 AFAIK. If that doesn't do it try specifying [QSA] as well, though I doubt that's it.
RewriteCond %{REQUEST_URI} !^/?new.php?url
RewriteRule ^/?(.+)\.?(.+)$ new.php?url=$1 [L]
The first back reference should be $1 instead of $0.
RewriteCond %{REQUEST_URI} !^/?new.php?url
RewriteRule ^/?(.+)\.?(.+)$ new.php?url=$1 [L]
It also depends on what other lines of code you have in the file. It's also possible to mess up rewrites if you have another code that conflicts with it.

Resources