Как я должен изменить этот код сжатия, чтобы предотвратить двойное кодирование? - PullRequest
1 голос
/ 20 октября 2011

Я использую довольно стандартный код сжатия, который я видел, плавающий по многим местам онлайн:

HttpRequestBase request = context.HttpContext.Request;

string acceptEncoding = request.Headers["Accept-Encoding"];

if (string.IsNullOrEmpty(acceptEncoding))
    return;

acceptEncoding = acceptEncoding.ToUpperInvariant();

HttpResponseBase response = context.HttpContext.Response;

if (acceptEncoding.Contains("GZIP"))
{
    response.AppendHeader("Content-encoding", "gzip");
    response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
}
else if (acceptEncoding.Contains("DEFLATE"))
{
    response.AppendHeader("Content-encoding", "deflate");
    response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
}

В некоторых случаях у меня есть два отдельных фрагмента кода, которые пытаются сжимать поток, но не знают, что он уже сжат. В результате мой заголовок выглядит так:

{Server=Microsoft-IIS%2f7.5&Content-encoding=gzip&Content-encoding=gzip&Location=%2fcsweb_IISVS2010%2fLogIn%3fReturnUrl%3d%252fcsweb_IISVS2010%252f&Set-Cookie=.ASPXFORMSAUTH%3d%3b+expires%3dTue%2c+12-Oct-1999+07%3a00%3a00+GMT%3b+path%3d%2f%3b+HttpOnly&X-AspNetMvc-Version=2.0}    System.Collections.Specialized.NameObjectCollectionBase {System.Web.HttpHeaderCollection}

Где вы можете увидеть Content-encoding = gzip был написан дважды.

Этот сценарий отлично обрабатывается некоторыми браузерами, но не всеми, а именно FireFox и Safari. Поэтому мне нужно проверить заголовок для этого. Я просто хочу убедиться, что я делаю это правильно.

Кажется, лучший способ сделать это - просто пойти:

if( response.Headers.Keys["Content-encoding"] ) { do stuff }

, но KeysCollection не имеет метода "HasKey". Таким образом, я мог видеть, что этот подход работает, только если я использую обработку исключений как часть навигации по коду - я действительно не хочу этого делать.

Моя следующая мысль состояла в том, что, возможно, я смогу очистить заголовки и затем снова добавить их, но, глядя на то, сколько информации уже хранится в заголовке, я думаю, что это будет плохой выбор.

Итак ... эту проблему, кажется, очень легко решить, но я не уверен, что это правильный путь. Любая помощь?

РЕДАКТИРОВАТЬ: Просто чтобы быть кристально чистым ...

В моем файле web.config я включил "RadCompression", который является реализацией сжатия Telerik для их элементов управления. Это вызывает сжатие некоторых ответов (но не всех). Затем запускается вышеуказанный код C # - мне нужно обнаружить, что он уже закодирован.

EDIT2: Ох ... проще, чем ожидалось. Response.Headers на самом деле содержит две вещи - «headers.Keys [index], а также headers.AllKeys»

Достаточно сделать что-то вроде response.Headers.AllKeys.Contains ("Content-Encoding").

1 Ответ

3 голосов
/ 20 октября 2011

Возможно, коллекция ServerVariables была бы лучшим местом для отслеживания того, было ли это сделано по этому запросу уже?

context.HttpContext.Request.ServerVariables["gzip-header-added"] = true;

Обновление

Headers.Keys поддерживается NameValueCollection, чей индексатор строк возвращает ноль, если рассматриваемый элемент не найден: http://msdn.microsoft.com/en-us/library/8d0bzeeb.aspx

Так что вам стоит проверить:

if( response.Headers.Keys["Content-encoding"] != null ) { do stuff }
...