Luckbox72
Luckbox72

Reputation: 307

500 URL ReWrite Module Error IIS 8

I have a few websites that use to be on a server using iis7 as the host.  I have moved these websites to a new server that is IIS8 and the database has been upgraded from SQL 2005 to SQL 2014.

Another part of this change is it now runs through a DMZ reverse proxy that redirects to an internal server.

This works fine in Chrome or Edge. But Firefox and IE I get a 500 URL Rewrite Module Error.  Not much more information in the error other than that.

I have other sites on the reverse proxy that work with no issue.  But all of the ones that work are .net 4.0 or higher.  The sites I  am having issue with are both 3.5 framework.

I have tried setting the app pool framework on the dmz to match the internal server.

There are currently 2 inbound rules one converts http to https and the other is the proxy rule. There is 1 Outbound rule which is also part of the revers proxy. The reverse proxy currently takes the https traffic and uses http internally and then the outbound sends it back as https. This is that same on all of the site on this server that currently work without any issues.

Some more information. I turned of error tracing and the fuller error I received is Outbound rewrite rules cannot be applied when the content of the HTTP response is encoded ("gzip").

Upvotes: 3

Views: 7034

Answers (2)

Luckbox72
Luckbox72

Reputation: 307

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

There are a number of step needed to complete this fix you can find them and all the information you need at https://blogs.msdn.microsoft.com/friis/2016/08/25/iis-with-url-rewrite-as-a-reverse-proxy-part-2-dealing-with-500-52-status-codes/ It is a 3 part post and the second post in the series was the solution.

Synopsis of link:

  1. In IIS Manager, go to URL Rewrite and first go to View Server Variables... on the right.
  2. Add two server variables, called HTTP_ACCEPT_ENCODING and HTTP_X_ORIGINAL_ACCEPT_ENCODING.
  3. Use these in your inbound rule (which is named something like Reverse Proxy Inbound Rule 1 to the effect of having this web.config file in C:\Sites\Yoursite (see below)

Note: to get the empty value into <set name="HTTP_ACCEPT_ENCODING" value="" /> you'll first have to set an arbitrary value in the IIS Manager GUI and afterwards edit the web.config file a bit.

  1. Also make a new outbound rule (see below) that will restore the Accept-Encoding HTTP header on the outbound side.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Reverse Proxy Inbound Rule 1" stopProcessing="true">
                    <match url="(.*)" />
                    <conditions>
                        <add input="{CACHE_URL}" pattern="^(https?)://" />
                    </conditions>
                    <action type="Rewrite" url="your_URL_rewrite_here" />
                    <serverVariables>
                        <set name="ORIGINAL_HOST" value="{HTTP_HOST}" />
                        <set name="HTTP_X_ORIGINAL_ACCEPT_ENCODING" value="{HTTP_ACCEPT_ENCODING}" />
                        <set name="HTTP_ACCEPT_ENCODING" value="" />
                    </serverVariables>
                </rule>
            </rules>
            <outboundRules>
                ...
                <rule name="RestoreAcceptEncoding" preCondition="NeedsRestoringAcceptEncoding">
                    <match serverVariable="HTTP_ACCEPT_ENCODING" pattern="^(.*)" />
                    <action type="Rewrite" value="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}" />
                </rule>
                <preConditions>
                    ...
                    <preCondition name="NeedsRestoringAcceptEncoding">
                        <add input="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}" pattern=".+" />
                    </preCondition>
                </preConditions>
            </outboundRules>
        </rewrite>
        <urlCompression doStaticCompression="true" />
    </system.webServer>
</configuration>

Thus, your ARR requests the backend server to not encode the response (accept-encoding HTTP header is empty) and your other outbound rules won't cause a 500.52 error anymore. You need to do this via the IIS Manager GUI because copy-pasting web.config (e.g. from one reverse proxy machine to another if you have 2 of them with a load balancer) doesn't work.

Upvotes: 3

Burndog
Burndog

Reputation: 719

Be sure that you also have the rewrite module installed on your instance or you'll face a 500 error

Upvotes: 0

Related Questions