title: IIS Reverse Proxy Re-Encoding URLs Containing Percent Sign (%)
body: <p>I am trying to set up a reverse proxy for <a href="http://jenkins-ci.org/" rel="noreferrer">Jenkins</a> using IIS 7.5, <a href="http://www.iis.net/downloads/microsoft/application-request-routing" rel="noreferrer">Application Request Routing</a> 3.0 (ARR), and <a href="http://www.iis.net/downloads/microsoft/url-rewrite" rel="noreferrer">URL Rewrite</a> 2.0.</p>
  
  <p>I have the proxy mostly working, but am running into issues with URLs that contain the percent symbol (%).</p>
  
  <p>No matter what I try, the proxy insists on either de-encoding or re-encoding the percent sign in the rewritten URL.</p>
  
  <p><strong>This is how I want the URLs rewritten:</strong></p>
  
  <pre><code>http://my.proxy/a%2Fb -&gt; http://my.host:8080/a%2Fb
  </code></pre>
  
  <p><strong>This is how the URLs are <em>actually</em> being rewritten:</strong></p>
  
  <pre><code>http://my.proxy/a%2Fb -&gt; http://my.host:8080/a/b
  - or -
  http://my.proxy/a%2Fb -&gt; http://my.host:8080/a%252Fb
  </code></pre>
  
  <p>How can I get IIS\ARR\Rewrite to stop re-encoding my rewritten URLs?</p>
  
  <p><strong>Things I've tried:</strong></p>
  
  <ol>
  <li><p>A normal reverse-proxy (rewrites the URL as <code>http://my.host:8080/a/b</code>):</p>
  
  <p><code>&lt;rule name="ReverseProxyInboundRule1" stopProcessing="true"&gt;
      &lt;match url="(.*)" ignoreCase="true" /&gt;
      &lt;action type="Rewrite" url="http://my.host:8080/{R:1}" /&gt;
  &lt;/rule&gt;</code></p></li>
  <li><p>Using the <code>UNENCODED_URL</code> server variable (rewrites the URL as <code>http://my.host:8080/a%252Fb</code>):</p>
  
  <p><code>&lt;rule name="ReverseProxyInboundRule1" stopProcessing="true"&gt;
      &lt;match url="(.*)" ignoreCase="false" /&gt;
      &lt;conditions logicalGrouping="MatchAll"&gt;
          &lt;add input="{UNENCODED_URL}" pattern="/(.*)" /&gt;
      &lt;/conditions&gt;
      &lt;action type="Rewrite" url="http://my.host:8080/{C:1}" /&gt;
  &lt;/rule&gt;</code></p></li>
  <li><p>Just entering the URL in straight (as a test - also rewrites the URL as <code>http://my.host:8080/a%252Fb</code>):</p>
  
  <p><code>&lt;rule name="ReverseProxyInboundRule1" stopProcessing="true"&gt;
      &lt;match url="(.*)" ignoreCase="false" /&gt;
      &lt;action type="Rewrite" url="http://my.host:8080/a%2Fb" /&gt;
  &lt;/rule&gt;</code></p></li>
  <li><p>All the ideas in Scott Hanselman's excellent "<a href="http://www.hanselman.com/blog/ExperimentsInWackinessAllowingPercentsAnglebracketsAndOtherNaughtyThingsInTheASPNETIISRequestURL.aspx" rel="noreferrer">Experiments in Wackiness: Allowing percents, angle-brackets, and other naughty things in the ASP.NET/IIS Request URL</a>"</p>
  
  <ol>
  <li><code>&lt;httpRuntime requestValidationMode="2.0" requestPathInvalidCharacters="*,:,&amp;amp;,\" relaxedUrlToFileSystemMapping="true" /&gt;</code></li>
  <li><code>&lt;security&gt;
      &lt;requestFiltering allowDoubleEscaping="true" /&gt;
  &lt;/security&gt;'</code></li>
  </ol></li>
  </ol>
  
  <p><em>Note: I ran into this behavior when my IIS reverse proxy ran afoul of <a href="https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+says+my+reverse+proxy+setup+is+broken" rel="noreferrer">Jenkins' built-in reverse proxy checking system</a> which attempts to do an HTTP redirect to a URL of this form.</em></p>