Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IIS Reverse Proxy Re-Encoding URLs Containing Percent Sign (%)

I am trying to set up a reverse proxy for Jenkins using IIS 7.5, Application Request Routing 3.0 (ARR), and URL Rewrite 2.0.

I have the proxy mostly working, but am running into issues with URLs that contain the percent symbol (%).

No matter what I try, the proxy insists on either de-encoding or re-encoding the percent sign in the rewritten URL.

This is how I want the URLs rewritten:

http://my.proxy/a%2Fb -> http://my.host:8080/a%2Fb

This is how the URLs are actually being rewritten:

http://my.proxy/a%2Fb -> http://my.host:8080/a/b
- or -
http://my.proxy/a%2Fb -> http://my.host:8080/a%252Fb

How can I get IIS\ARR\Rewrite to stop re-encoding my rewritten URLs?

Things I've tried:

  1. A normal reverse-proxy (rewrites the URL as http://my.host:8080/a/b):

    <rule name="ReverseProxyInboundRule1" stopProcessing="true"> <match url="(.*)" ignoreCase="true" /> <action type="Rewrite" url="http://my.host:8080/{R:1}" /> </rule>

  2. Using the UNENCODED_URL server variable (rewrites the URL as http://my.host:8080/a%252Fb):

    <rule name="ReverseProxyInboundRule1" stopProcessing="true"> <match url="(.*)" ignoreCase="false" /> <conditions logicalGrouping="MatchAll"> <add input="{UNENCODED_URL}" pattern="/(.*)" /> </conditions> <action type="Rewrite" url="http://my.host:8080/{C:1}" /> </rule>

  3. Just entering the URL in straight (as a test - also rewrites the URL as http://my.host:8080/a%252Fb):

    <rule name="ReverseProxyInboundRule1" stopProcessing="true"> <match url="(.*)" ignoreCase="false" /> <action type="Rewrite" url="http://my.host:8080/a%2Fb" /> </rule>

  4. All the ideas in Scott Hanselman's excellent "Experiments in Wackiness: Allowing percents, angle-brackets, and other naughty things in the ASP.NET/IIS Request URL"

    1. <httpRuntime requestValidationMode="2.0" requestPathInvalidCharacters="*,:,&amp;,\" relaxedUrlToFileSystemMapping="true" />
    2. <security> <requestFiltering allowDoubleEscaping="true" /> </security>'

Note: I ran into this behavior when my IIS reverse proxy ran afoul of Jenkins' built-in reverse proxy checking system which attempts to do an HTTP redirect to a URL of this form.

like image 664
Joseph Sturtevant Avatar asked Mar 04 '14 00:03

Joseph Sturtevant


1 Answers

Joseph, that is a great summary of all the ways I've tried to resolve the exact same issue, having IIS with SSL routing traffic to my Gerrit instance. When I found your post I hoped that maybe someone figured out a magic way to configure it but I guess it's not possible. I have tried one more thing, I've written a custom rewrite provider for IIS so that I can undecode the percent signs before routing is done, but then I realized that the encoding takes place later and this is pointless (I forgot about your step nr 3 that shows it very good).

I couldn't however get rid of IIS like out did, so I have figured a workaround. I have implemented a simple service that acts as additional proxy between IIS and Gerrit. When you configure IIS like in step 2, requests that are forwarded will get %25 in place of percent characters in the urls. Instead of reaching Gerrit, IIS forwards the requests to the proxy service. The service changes all occurrences of %25 to % (decodes percents) and forwards it to Gerrit. Nothing needs to be done with the response. For those who want to go this way you can start from my simple implementation of the proxy in C#:

https://gist.github.com/gralin/b5edfd908a41fc7268a7757698af1e66

like image 142
Gralin Avatar answered Sep 27 '22 19:09

Gralin