Troubleshooting IIS Compression issues in IIS6/IIS7.x

Tools Used in this Troubleshooter:

This material is provided for informational purposes only. Microsoft makes no warranties, express or implied.

Overview

Enabling HTTP Compression for your IIS6/7 web applications is one way of increasing site performance.

Unfortunately IIS admin GUI doesn't expose many of the compression properties needed to fully administer it. In it only lets us turn it on or off. So it is important to note that to configure http compression to its full extent you'll need to edit the metabase.xml using a tool other than the IIS Manager. The most common tool we use is adsutil.vbs, which is included in the IIS installation

This troubleshooter will help you to configure compression & identify common reasons why IIS compression may not work in IIS6 and IIS 7.x

Verification

Determining if compression is working

The only way of determining whether the IIS server sent a compressed response is by analyzing a network trace of the client request/server response. The request from the client needs to contain the following HTTP Request Header:

HTTP: Accept-Encoding =gzip, deflate

This tells the server that the client supports compression and will accept a compressed response. In return, a compressed response from the server will contain the following HTTP Response header and a value:

HTTP: Content-Encoding = gzip

Fiddelr output when compression is not working:

Troubleshooting

Enable Compression in IIS6/IIS7: From the IIS Manager, right-click on the Web Sites node, Properties and click on Services.

Compression folder and permissions on it: IIS stores compressed files in a folder which can be configured. By default, it is “%windir%\IIS Temporary Compressed Files” for IIS 6, and “%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files” for IIS 7.

IIS_WPG(IIS_IURS for IIS 7) must have full control permission for this folder. Process Monitor is a great tool to troubleshooting this type of permission issue.

Check if compression is enabled in Metabase.xml: Compression is not turned on in the metabase at the right locations. There are three metabase locations for Compression configuration:

w3svc/filters/compression/parameters

w3svc/filters/compression/gzip

w3svc/filters/compression/deflate

Configuring at the /parameters location is *mandatory*. Then, you need to configure at either /gzip *or* /deflate, *or* both. This means that configuring at just /gzip will not work, at just /deflate will not work, and just /parameters will not work. But, configuring at /parameters and /gzip will enable the Gzip compression scheme. And, configuring /parameters and /deflate will enable the Deflate compression scheme. Finally, configuring at all three will enable both GZip compression and Deflate compression.

Check the metabase permission for IIS 6: By default, IIS_WPG has Read, Unsecure Read, Enumerate Keys and Write permission to the /LM/W3SVC/Filters.

IIS is unable to initialize the compression if the permissions were removed due to unexpected change or security hardens.

If the application pool identity (or the IIS_WPG group in general) does not have Read and Write access to the metabase key W3SVC/Filters a failure condition of COMPRESSION_DISABLED will be logged in an Enterprise Tracing for Windows (ETW) trace.

Check if Dynamic or Static compression is turned off in Metabase.xml: At each of the three configuration locations (/parameters, /gzip, and /deflate), you have the option of enabling Static and/or Dynamic compression. For static files like txt and html to be compressed, you need to set the HcDoStaticCompression key to 1 (or TRUE). To enable Dynamic compression (for things like asp, aspx, asmx, exe) you need to have HcDoDynamicCompression set to 1 (or TRUE).

For example, to set dynamic compression at the /parameters node using adsutil.vbs, run this command:

Check if file type you want to compress is listed in the appropriate File Extensions sections at the /gzip and /deflate nodes: Once you turn on compression with the HcDoDynamicCompression and/or HcDoStaticCompression keys, you have to make sure to tell IIS which file types to actually compress. By default, we compress htm, html, and txt for STATIC compression, and asp, dll, and exe for DYNAMIC compression. If you want different file types compressed, for example aspx, you need to add it to the appropriate file extension section in the /gzip and-or /deflate nodes, depending on the type of compression you're using. For static file compression (like html, txt, and xml), you add the file extensions to the HcFileExtensions property. For dynamic compression (like asp, aspx, asmx) you add it to the HcScriptFileExtension property.

NOTE: Configuring the HcFileExtensions or HcScriptFileExtensions properties needs to be done with the exact right syntax. Any trailing spaces or unnecessary quotes/carriage returns will cause the property to be misconfigured. Unfortunately adsutil.vbs does not throw an error if you add an extra space, so you need to be very careful. Also, copy/pasting the values into a command prompt or into the metabase.xml file (metabase direct-edit) is a bad idea....always type it manually!

Check if compression is set at the master level, but is getting overridden by a setting at a child level: Compression would be enabled at the w3svc/filters/compression level, however if may be possible that it’s getting overridden by a setting at the web site/application level.

For eg: If you have HcDoDynamicCompression set to TRUE at w3svc/filters/compression level, and for the default web site have DoDynamicCompression set to FALSE, dynamic compression will NOT occur for responses to requests for the Default Web Site.

Check if an anti-virus program has scanned the directory where the compressed files get stored:

When compression is enabled on a server running Internet Information Services (IIS), and an HTTP request is served from the IIS compression directory, a 0-byte file may be returned instead of the expected file.

Note: You may only see these symptoms if HTTP Static Compression is enabled.

This happens because of an Antivirus software running on the IIS server is scanning the IIS compression directory.

Hence you would need to exclude the IIS compression directory from the antivirus software's scan list.

Check if the URL being requested contains a slash as part of the parameters passed to the executing DLL file.

ISAPI filters modifying the request/response headers:

An ISAPI is doing the send operation and is not sending the complete set of HTTP headers along with the entity to HTTP_COMPRESSION::DoDynamicCompression. Since DoDynamicCompression doesn't receive all the data it should from the ISAPI, we cannot compress the response. Third party and/or non-Microsoft ISAPIs have been seen to do this by putting the headers in the function meant for the entity body or the entity body in the function meant for the HTTP headers, or by not providing any headers whatsoever. When this happens, things like the ISAPI filter SF_NOTIFY_SEND_RESPONSE, or AddResponseHeaders, or dynamic compression will fail. The ISAPI needs to put the headers and the entity in the right locations, respectively.

The response status code is something other than 200. In IIS 6/7, only responses with an HTTP 200 status will get compressed.

Yes this is true in both IIS6 & IIS 7.x, Response with status codes other than 200 will not be compressed. We will have to write an HTTPModule to achieve the same.

If the request contains a Via: header: The Via headers indicates that the request is coming to IIS via a Proxy. Many proxies don't handle the compression header correctly and give compressed data to clients when they aren't supposed to, so by default we don't allow compressed responses when the request has a Via header. You can override this by setting the HcNoCompressionForProxies metabase key to True.

The request is for a static page, and the response contains document footer. Document footers will cause static compression to fail.

Static compression not working: This may happen if you have a wild card application mapping installed at the root level in IIS. For eg. We have application mappings for the .html or .txt extensions) on the server and this will make IIS consider your requests to .txt as Dynamic requests instead of Static and since .txt is not an extension in the dynamic compression list, it does not get compressed.

IIS Compression and “Accept-Encoding: identity”:

According to RFC2616 :

"If an Accept-Encoding field is present in a request and if the server cannot send a response which is acceptable according to the Accept-Encoding header, then the server SHOULD send an error response with the 406 (Not Acceptable) status code. If no Accept-Encoding field is present in a request, the server MAY assume that the client will accept any content coding. In this case, if "identity" is one of the available content-coding’s, then the server SHOULD use the "identity" content-coding, unless it has additional information that a different content-coding is meaningful to the client."

Using ETW trace to troubleshooting IIS compression issue

Event Tracing for Windows (ETW) is a feature of the Windows operating system that allows you to troubleshoot issues with HTTP requests.

Here are the steps to troubleshooting IIS compression issue.

Create a text file named IISProviders.txt and put follow content into the file.”IIS: WWW Server” is the provider name, 0xFFFFFFFE means trace for all events, and 5 means verbose level.