
You are using GZIP compression in your ASP.NET application and need to test client requests for GZIP support. This is important because some clients don't support GZIP. Because this particular code is executed tens of thousands to millions of times a day, it pays to spend time optimizing it.
Tip: Often, HttpWorkerRequest is the easiest and fastest way to check headers. It avoids dealing with NameValueCollection.
Benchmark results RequestToolGZipSimple.HasSupport: 460 ms IsGZipSupported: 3712 ms
First, GZIP support is an optimization almost all sites should use, but sending GZIP output to all browsers will cause serious compatibility problems. Here we see a C# method that tests the HttpWorkerRequest for GZIP client support. HttpWorkerRequest gives you access to low-level ASP.NET data.
Class that tests for GZIP support [C#]
using System;
using System.Web;
public static class RequestToolGZipSimple
{
public static HttpWorkerRequest GetWorker(HttpContext context)
{
IServiceProvider provider = (IServiceProvider)context;
HttpWorkerRequest worker = (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));
return worker;
}
public static bool HasSupport(HttpContext context)
{
try
{
HttpWorkerRequest worker = GetWorker(context);
string value = worker.GetKnownRequestHeader(HttpWorkerRequest.HeaderAcceptEncoding);
if (value == null)
{
return false;
}
if (value.Length >= 4)
{
if (value[0] == 'g' && value[1] == 'z' && value[2] == 'i' && value[3] == 'p')
{
return true;
}
else
{
for (int i = 0; i < value.Length - 3; i++)
{
if ((value[i] == 'g' || value[i] == 'G') &&
(value[i + 1] == 'z' || value[i + 1] == 'Z') &&
(value[i + 2] == 'i' || value[i + 2] == 'I') &&
(value[i + 3] == 'p' || value[i + 3] == 'P'))
{
return true;
}
}
}
}
return false;
}
catch
{
return false;
}
}
}Description. This is a static class that defines one public static method that is a helper method that returns the HttpWorkerRequest, and another public static method that actually checks for GZIP support. The HttpWorkerRequest must be accessed by using the IServiceProvider interface. The GetWorker method abstracts this casting and puts it in a special method.
Static Class Interface TypesNotes on HasSupport method. You can access this method by calling RequestToolGZipSimple.HasSupport(Context). In its body, it gets the HttpWorkerRequest, and then scans strings that are 4 or more characters long. The vast majority of GZIP clients will have the first four letters of "gzip" (lowercase) in this string. This string is special-cased, which speeds up the method on most clients. The final for loop simply scans the string for GZIP in any letter casing. This code is hit by Opera. The loop here is significantly faster than IndexOf.

Overview of optimizations. The optimizations here are to avoid the slow NameValueCollection lookup. This is the most important improvement. The second optimization is to use individual character testing instead of string methods, which is between 2x and 10x faster on some micro-benchmarks.
NameValueCollection UsageThe above method has the same result as using the Headers[] lookup approach. However, internally the following method must construct an entire NameValueCollection (sometimes) and then do a hash key lookup and several string comparisons. It is also more fragile because you have to guess the case of "Accept-Encoding". The above method does not have to use this string.
Method that uses Headers collection [C#]
public static bool IsGZipSupported(HttpRequest request)
{
string encoding = request.Headers["Accept-Encoding"];
if (!string.IsNullOrEmpty(encoding) && encoding.Contains("gzip"))
{
return true;
}
else
{
return false;
}
}Resources for this method. This method is well tested and you can read much more about it and surrounding code at Rick Strahl's Web Log.
More on GZip compression with ASP.NET
By using HttpWorkerRequest wherever possible in your C# code, you can measurably improve performance to some degree. Simply by replacing Headers, PhysicalPath, and NameValueCollection usage with HttpWorkerRequest methods, I consistently measured a decrease in page load time (using Stopwatch and high-definition timers) of about 80 microseconds per page (0.08 milliseconds).
HttpWorkerRequest
Here we looked at how you can easily optimize the Accept-Encoding header check in ASP.NET, resulting in measurably but small performance increases on pages. Additionally, this method is less prone to guessing and typos, because you do not need to use the "Accept-Encoding" string at all.
Compression Tips