IIS URL rewrite rule problems with non-English characters - iis

I have problems with getting my IIS URL Rewrite 2 rules to work with non-English (Swedish) characters (å ä ö). I'm on Windows Server 2012 R2 (IIS 8.5).
This rule works well with English characters:
<rule name="RedirectSubWebKeepURI" enabled="true" stopProcessing="true">
<match url="^department/lawyers/(.*)" />
<action type="Redirect" url="/section/lawyers/{R:1}" />
</rule>
But assume I would spell "lawyers" as "låwyers" (not a real word!), how can I get it to work?
Neither of the examples below work:
<match url="^department/låwyers/(.*)" /> [real character]
<match url="^department/l%C3%A5wyers/(.*)" /> [URL encoded 'å']
What am I missing? This previous question says you have to use the {UNENCODED_URL} variable, but does that mean I have to match all URL:s with ".*" and move the actual matching logic to a condition instead? If so, I can't really figure out how my rule should be rewritten accordingly...
Thanks for help!

Try using internal UrlEncode{} like this:
<action type="Redirect" url="/section/lawyers/{UrlEncode:{R:1}}" />

Related

IIS + PHP Pretty URL (key,value) removes double slashes

There has been a migration from a apache server to IIS, the base transfer was pretty easy and it is running, but I've got a rather annoying issue that I would like to solve.
The issue: They are using zii 'cgridview' to show their tables; while it's not a pretty solution (might be the implementation), it worked fine for Apache.
The pagination itself works fine but when they are filtering it; it will do a 'GET' to get all the information, this sort of works for the first time but when we paginate to another page it suddenly go haywire (because it's a GET).
The issue here is it will do a request with all the filters, so it's like:
https://example.com/controller/action/filter1/value/filter2//filter3//filter4/hallo
This is normally the correct format how it should work (with apache rewrite at least), however IIS does not seem to like this, in my opinion why?
If you like closer we got a filter1 and the next parameter is a value; filter2 does not have a value so it's empty and there now two 'slashes' (between those slashes is nothing; so it's empty) but as far I can imagine IIS is trimming those slashes away so it's a single slash.
Filter for filter1 works as expected; but filter2 will have filter3 as value; which is not correct.
Does anyone have an idea what can cause this issue?
The rewrite is like this:
<rule name="yii_rewrite" stopProcessing="true">
<match url="." ignoreCase="false" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
</conditions>
<action type="Rewrite" url="index.php" appendQueryString="true" />
</rule>
Thank you for your time, appreciate it!
At present, these double slashes will be processed by the modern IIS/Apache webserver. Only some old browsers will convert the double slashes to another meaning. thereby, we could add URL Rewrite rules in IIS/Apache server to remove the extra slash, just like below.
mod_rewrite in Apache.
# remove multiple slashes anywhere in url
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]
Equally, in the IIS URL Rewrite module.
<rewrite>
<rules>
<rule name="Imported Rule" stopProcessing="true">
<match url="." ignoreCase="false" />
<conditions>
<!--# remove multiple slashes anywhere in url -->
<add input="{URL}" pattern="^(.*)//(.*)$" ignoreCase="false" />
</conditions>
<action type="Redirect" redirectType="Permanent" url="{C:1}/{C:2}" />
</rule>
</rules>
</rewrite>
Please refer to the below link for more details.
https://webmasters.stackexchange.com/questions/8354/what-does-the-double-slash-mean-in-urls/8381#8381
I suggest to disable this behavior completely by settings CUrlManager::$appendParams to false. As a result you should get URLs like https://example.com/controller/action?filter1=value&filter2=&filter3=&filter4=hallo, which should be less confusing not create any problems.
As far I am aware the problem is caused because the 'REQUEST_URI' is encoded by default, double slashes are turned to single slashes. In order to resolve this issue; we can replace the REQUEST_URI with UNENCODED_URL; that way the double slashes remains.
This works but IIS must have had their reasons for that; it's better to fix it in code and not putting a band aid on it. If this can cause issues; I would love to hear about it - preferably I would like to resolve this cleanly even though this is old code that will stop at the end of the year.
<serverVariables>
<set name="REQUEST_URI" value="{UNENCODED_URL}" />
</serverVariables>

IIS UrlRewrite for reverse proxy only working if folder exists on primary website

I've got two websites on the same box and I want to reverse proxy a folder on one to the other. It is only working for directories if I create the directory on the parent website.
so i want http://site/odata/Books
to go to
http://myodatasite/odata/Books
Pretty straightforward, but it is not working unless I go to wwwroot/site and create the /odata/Books folders there. If I do this, the rewrite works. If I call /odata/Authors, again it will 404 unless I create an Authors folder.
It seems like I need to have a wilcard mapping in place in IIS or something else is causing the rewrite to fail. I have tried adding a wildcard mapping pointing to aspnet_isapi and had no changes, possibly because of integrated mode but I haven't found anything that is helpful online yet for this.
Does anyone know why my rewrite is not working for directories but a redirect works fine?
<rewrite>
<rules>
<!-- Does Not Work unless folders exist on current site! -->
<rule name="OdataRoutes" stopProcessing="true">
<match url="^odata/(.*)" />
<action type="Rewrite" url="http://myodatasite/odata/{R:1}" />
</rule>
<!-- Works -->
<rule name="OdataRoutes2" stopProcessing="true">
<match url="odata2/(.*)" />
<action type="Redirect" url="http://myodatasite/odata/{R:1}" />
</rule>
<!-- Works -->
<rule name="OdataRoutes3" stopProcessing="true">
<match url="(.*)\.odata" />
<action type="Rewrite" url="http://myodatasite/odata/{R:1}" />
</rule>
</rewrite>
Looks like it wasn't the mappings at all. Turning on Failed request tracing and monitoring the successful request and the failed request, it seemed the directory rewrite was being passed from ARR to the MvcHandler. Not sure why the redirect wasnt and the rewrite was, but after seeing that, the fix was pretty easy.
routes.IgnoreRoute("odata/{*pathInfo}");

IIS URL Rewrite with a pound/number sign "#"

I have a need to rewrite a url for an invoice that has a "#" in the querystring. Evidently the "#" is causing IIS to balk somehow. The rule I have currently is:
^invoice/([_0-9a-z-#]+)
and the action is:
invoice.aspx?id={R:1}
Pretty simple and works fine so long as there's no "#" in the invoice number. Is there any way to include this so it works?
Hash Tags in the URL serve a special purpose to the client browser, not to the server.so Browser did not anything after the '#' character.
To resolve this issue you can try this below url rewrite rule:
<rule name="test # in query string" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{REQUEST_URI}" pattern="invoice/(.+)" />
</conditions>
<action type="Redirect" url="invoice.html?id={UrlEncode:{C:1}}" />
</rule>
(.+) accessts all the chracter and {UrlEncode:{}} encode the url in the orignal manner.
Regards,
Jalpa

IIS Rewrite Rule - how to manipulate {HTTP_HOST} string

I've just started using iis rewrite rules for the first time and I'm struggling with what I imagine is an easy rule.
Basically, I wish to use this rule
<rule name="redirect">
<match url="^(one$|two$|three$)" />
<action type="Redirect" url="{HTTP_HOST}{REQUEST_URI}" />
</rule>
But have the redirect {HTTP_HOST} string minus the extension [.co.uk / .com etc.].
e.g.
bigsite.co.uk/one
would redirect to:
bigsite.co.uk/bigsite/one
How does one go about this - for I can only find Tolower / UrlEncode / UrlDecode string manipulators?
[Ultimately, I would also like to then use a rewrite rule to hide the fact that the redirect has occurred, i.e. the address would remain as bigsite.co.uk/one after the redirect.]
Well I eventually came up with this (hope it may help someone):
<rule name="redirect">
<match url="^(one$|two$|three$)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^(www.)?(.*).co.uk" />
</conditions>
<action type="Redirect" url="{C:2}{REQUEST_URI}" />
</rule>
...not sure if there is a better way, but it works perfectly for me - thanks all, PP

Rewrite rules in ISS's web.config

I'm just trying to get some code running on ISS that has been running on Apache for a long time.
A particular mod_rewrite rule is proving difficult to get working.
In Apache I've used:
RewriteRule ^media/(js|css|img|font)/(.+)\.(\d+)\.(js|css|png|jpg|gif)$ /media/$1/$2.$4
[L]
To turn a URL like /media/css/style.1367406756.css into /media/css/style.css, letting me put timestamps in the files to avoid caching issues.
In my web.config file I've added:
<rule name="Cache bust assets" stopProcessing="true">
<match url="^(.*)$"/>
<conditions>
<add input="{URL}" pattern="^media/(js|css|img|font)/(.+)\.(\d+)\.(js|css|png|jpg|gif)$"/>
</conditions>
<action type="Rewrite" url="/media/{R:1}/{R:2}.{R:4}" appendQueryString="true" />
</rule>
Which, looks like it should work. (It's alongside another rule, which works fine, so it's not that the server isn't parsing it or anything).
I don't get any errors, other than visiting /media/css/style.1367406756.css gives me a 404 error.
How Can I make this work?
You use {R:N} back references in your action when you should use {C:N} since the information comes from the conditions. See Using Back-references in Rewrite Rules for more information.
You can see this error if you open the iismanager console:
To get your rule to work you have 2 solutions.
First you can change your action to (using {C:N}):
<action type="Rewrite" url="/media/{C:1}/{C:2}.{C:4}" appendQueryString="true" />
Or (and I do think it is a better solution), you can use the Import mod_rewrite Rules tool.
In the iismanager console, click on Import Rules... (on the right tab) and paste your apache rule:
This will create for you the following rule:
<rule name="Imported Rule 1" stopProcessing="true">
<match url="^media/(js|css|img|font)/(.+)\.(\d+)\.(js|css|png|jpg|gif)$" ignoreCase="false" />
<action type="Rewrite" url="/media/{R:1}/{R:2}.{R:4}" />
</rule>

Resources