2015-02-09 2 views
3

Я работаю над получением сжатия gzip/deflate, работающей с ответами веб-API. Я использую код от Github - MessageHandlers.Compression. Однако он не работал. Не было заголовка Content-Encoding, появляющегося в консоли разработчика Google или Firebug в Firefox, и Content-Length последовательно устанавливал несжатый размер данных. Поэтому я продолжал зачистки код, пока я не закончил с следующее:Проблема веб-API с отправкой сжатого ответа

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
{ 
    // Send the request to the web api controller 
    var response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); 

    // Compress uncompressed responses from the server 
    if (response.Content != null && request.Headers.AcceptEncoding.IsNotNullOrEmpty()) 
    { 
     var content = response.Content; 
     var bytes = content.ReadAsByteArrayAsync().Result; 

     if (bytes != null && bytes.Length > 1024) 
     { 
      // The data has already been serialised to JSon by this point 
      var compressedBytes = Compress(bytes); 
      response.Content = new ByteArrayContent(compressedBytes); 

      var headers = response.Content.Headers; 
      headers.Remove("Content-Type"); 
      headers.ContentLength = compressedBytes.Length; 
      headers.ContentEncoding.Clear(); 
      headers.ContentEncoding.Add("gzip"); 
      headers.Add("Content-Type", "application/json"); 
     } 
    } 

    return response; 
} 

private static byte[] Compress(byte[] input) 
{ 
    using (var compressStream = new MemoryStream()) 
    { 
     using (var compressor = new GZipStream(compressStream, CompressionMode.Compress)) 
     { 
      compressor.Write(input, 0, input.Length); 
      compressor.Close(); 
      return compressStream.ToArray(); 
     } 
    } 
} 

Когда я сначала сделал это, я сделал ошибку, и установить кодировку содержимого в заголовке, чтобы «Gzip», когда я использовал DeflateStream в метод сжатия. Как и следовало ожидать, я получил ошибку в браузере, однако заголовки ответов были правильными (!). То есть заголовок Content-Encoding был установлен, и Content-Length был правильным. Кроме того, глядя на необработанные данные, я мог ясно видеть, был ли сжат. Как только я исправил свою ошибку, хотя проблема вернулась.

Что мне интересно, так это то, что последние версии браузера декомпрессируют содержимое за кулисами или что-то не так с моим кодом? Ответы отправляются в формате Json

Любая помощь очень ценится.

EDIT

Я попытался демпинг заголовки в файл журнала в следующих методов в Global.asax (перечислены в порядке их появления в журнале):

Application_PreSendRequestHeaders

Application_EndRequest

Application_PreSendRequestContent

В каждом случае требуемые заголовки были там, хотя они не отображались в консоли разработчика Google. Затем я взглянул на решение по адресу Code Project. При запуске из командной строки все работало так, как ожидалось. Однако, когда я позвонил веб-серверу из Google Chrome, я получил тот же результат. То есть, нет заголовка Content-Encoding и никаких указаний относительно того, было ли содержимое сжато или нет. Однако при открытии консоли разработчика легко увидеть этот заголовок на других сайтах (например, переполнение стека). Я должен предположить, что это связано с сжатыми ответами от веб-сервисов api. Это так сложно понять, если это действительно работает на стороне клиента.

+0

Вы когда-нибудь получали какое-либо из этого, чтобы правильно работать в рамках ASP .Net Web API? До сих пор у меня не было никакой удачи, возвращающей ответ JSON gzip'а - значение заголовка ответа Content-Encoding всегда удаляется этим бесполезным API, и независимо от того, что я пытаюсь, заголовок всегда удаляется. Еще один пример того, насколько ужасно нарушен этот API. Если я добавлю что-то в заголовок ответа, то ** ОСТАВЬТЕ ЭТО ОН! **. – jerhewet

+0

Другое дело. Пожалуйста, никаких указателей на другие сообщения здесь, на SO, или сообщения от пяти лет назад в Интернете. Ни один из них не работает. Все они заканчиваются тем, что заголовок Content-Encoding удаляется из ответа. Все они. – jerhewet

+0

К сожалению, нет, я никогда не выходил за рамки того, что вы видите здесь. Из-за временных ограничений мне просто пришлось двигаться дальше. – fhevol

ответ

3

В случае, если кто-либо не хочет читать все комментарии, ответ пришел от Джерри Хьюетта (jerhewet). А именно, что антивирусное программное обеспечение перехватывает ответ, прежде чем он попадет в браузер. Антивирусное программное обеспечение распаковывает данные, без сомнения, как часть процесса сканирования. Огромное спасибо Джерри за помощь здесь.

+0

У меня тоже была проблема с антивирусом. Огромное спасибо! – RaptisV

Смежные вопросы