500.52: IIS URL rewrite errors if acting as a proxy for a site which uses the content encoding "identity"

Ian Newson 1 Reputation point
2022-04-08T15:50:10.58+00:00

I have downloaded and installed https://www.iis.net/downloads/microsoft/url-rewrite

I have created the following web.config:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.)" />
<action type="Rewrite" url="http://localhost:6006/{R:1}" />
<serverVariables>
<set name="HTTP_X_ORIGINAL_ACCEPT_ENCODING" value="{HTTP_ACCEPT_ENCODING}" />
<set name="HTTP_ACCEPT_ENCODING" value="" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
<match filterByTags="A, Form, Img" pattern="^http(s)?://localhost:6006/(.
)" />
<action type="Rewrite" value="http{R:1}://iansdesktop/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>

This errors with:

HTTP Error 500.52 - URL Rewrite Module Error.
Outbound rewrite rules cannot be applied when the content of the HTTP response is encoded ("identity").

The value identity effectively means no encoding according to the RFC:

The "identity" content-coding is always acceptable, unless
specifically refused because the Accept-Encoding field includes
"identity;q=0", or because the field includes "*;q=0" and does
not explicitly include the "identity" content-coding. If the
Accept-Encoding field-value is empty, then only the "identity"
encoding is acceptable.

https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

So this appears to be a bug in the URL rewrite module.

I have temporarily solved this by removing the line from the third party code: https://github.com/tensorflow/tensorboard/blob/master/tensorboard/plugins/core/core_plugin.py#L171

However this will break when the code is updated. How can I fix this permanently?

Internet Information Services
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Sam Wu-MSFT 5,931 Reputation points Microsoft Vendor
    2022-04-11T02:14:49.107+00:00

    @Ian Newson

    This is because the responses that are coming from the back-end server are using HTTP Compression, and URL rewrite cannot modify a response that is already compressed. This causes a processing error for the outbound rule resulting in the 500.52 status code.

    There are two ways to work around this: either you turn off compression on the backend server that is delivering the HTTP responses (which may or may not be possible, depending on your configuration), or we attempt to indicate to the backend server the client does not accept compressed responses by removing the header when the request comes into the IIS reverse proxy and by placing it back when the response leaves the IIS server.

    With regards to the removal and re-instatement of the HTTP header, you need to add two variables named HTTP_ACCEPT_ENCODING and HTTP_X_ORIGINAL_ACCEPT_ENCODING in URL Rewrite, once this is complete, you need to use these variables both in the inbound rules, to remove the Accept-Encoding header and in the Outbound Rules to place this header back again.
    The final rule should be as follows:

    <rule name="ReverseProxyInboundRule1" stopProcessing="true">  
         <match url="(.*)" />  
         <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />  
         <serverVariables>  
             <set name="HTTP_X_ORIGINAL_ACCEPT_ENCODING"    value="{HTTP_ACCEPT_ENCODING}" />  
             <set name="HTTP_ACCEPT_ENCODING" value="" />  
         </serverVariables>  
    </rule>  
    

    Then you need to modify the outbound rules, when you receive the responses from the backend server, you need to forward them back to the browser. To be able to correctly do this, you will need to restore the value of the HTTP_ACCEPT_ENCODING variable to what it was before you changed it to empty. Create a new Outbound Rule from the URL Rewrite Pane, by clicking the ‘Add Rule’ action link on the right hand side pane, and then selecting the ‘Blank Rule’ from the Outbound Rules section of the ‘Add Rule(s)’ Window.

    <outboundrules>  
             <rule name="ReverseProxyOutboundRule1" precondition="ResponseIsHtml1">  
                    <match filterbytags="None" pattern="href=(.*?)http://privateserver:8080/(.*?)\s">  
      
                           <action type="Rewrite" value="href={R:1}http://www.mypublicserver.com/{R:2} ">  
                            </action>  
                     </match>  
               </rule>  
               <rule name="Restore-AcceptEncoding"  precondition="NeedsRestoringAcceptEncoding">  
                     <match servervariable="HTTP_ACCEPT_ENCODING" pattern="^(.*)"></match>  
                      <action type="Rewrite" value="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}"> </action>  
              </rule>  
             <preconditions>  
                  <precondition name="ResponseIsHtml1">  
                       <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/(.+)"></add>  
                   </precondition>  
                   <precondition name="NeedsRestoringAcceptEncoding">  
                          <add input="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}" pattern=".+"></add>  
                   </precondition>  
              </preconditions>  
      </outboundrules>  
    

    By configuring the Inbound and Outbound rules, you are now able to mitigate the 500.52 status code if our backend server was compressing the responses as a result of the client browser sending ‘Accept-Encoding’ headers in the incoming requests.

    More information you can refer to this link: https://techcommunity.microsoft.com/t5/iis-support-blog/iis-acting-as-reverse-proxy-where-the-problems-start/ba-p/846259.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

  2. Ian Newson 1 Reputation point
    2022-04-11T08:14:03.473+00:00

    @Sam Wu-MSFT Hi, I have already tried that, and also verified that no compression is being used by connecting to the backend web server with telnet to make the request, which will do no automatic decompression of the response.

    According to the RFC, "identity" means no encoding.