Как сжать POST HttpWebRequest - PullRequest
       9

Как сжать POST HttpWebRequest

14 голосов
/ 11 ноября 2010

Я пытаюсь отправить данные на сервер, который принимает сжатые данные. Код ниже работает просто отлично, но это несжатый. Я не работал со сжатием или Gzip, поэтому любая помощь приветствуется.

HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
  request.Timeout = 600000;
  request.Method = verb;  // POST    
  request.Accept = "text/xml";

  if (!string.IsNullOrEmpty(data))
  {
    request.ContentType = "text/xml";        

    byte[] byteData = UTF8Encoding.UTF8.GetBytes(data);
    request.ContentLength = byteData.Length;       

    // Here is where I need to compress the above byte array using GZipStream

    using (Stream postStream = request.GetRequestStream())
    {
      postStream.Write(byteData, 0, byteData.Length);         
    }
  }      

  XmlDocument xmlDoc = new XmlDocument();
  HttpWebResponse response = null;
  StreamReader reader = null;
  try
  {
    response = request.GetResponse() as HttpWebResponse;
    reader = new StreamReader(response.GetResponseStream());
    xmlDoc.LoadXml(reader.ReadToEnd());
  }

Должен ли я сжать весь байтовый массив? Нужно ли добавить другие заголовки или удалить уже существующий?

Спасибо!

-Скотт

Ответы [ 4 ]

13 голосов
/ 11 ноября 2010

Чтобы ответить на вопрос, который вы задали, для сжатых данных POST все, что вам нужно сделать, это обернуть поток запроса потоком gzip

 using (Stream postStream = request.GetRequestStream())
 {
    using(var zipStream = new GZipStream(postStream, CompressionMode.Compress))
    {
        zipStream.Write(byteData, 0, byteData.Length);         
    }
 }

Это полностью отличается от запроса ответа gzip, которыйгораздо более распространенная вещь.

4 голосов
/ 14 апреля 2014

Я также получил сообщение об ошибке «Невозможно закрыть поток, пока не будут записаны все байты», используя код, похожий на tnyfst.Проблема была в том, что у меня было:

request.ContentLength = binData.Length;

, где binData - мои необработанные данные перед сжатием.Очевидно, что длина сжатого содержимого будет другой, поэтому я просто удалил эту строку и получил следующий код:

using (GZipStream zipStream = new GZipStream(request.GetRequestStream(), CompressionMode.Compress))
{
    zipStream.Write(binData, 0, binData.Length);
}
3 голосов
/ 11 ноября 2010

В Page_Load событие:

        Response.AddHeader("Content-Encoding", "gzip");

И для выполнения сжатых запросов:

HttpWebRequest и GZip Http Responses от Рик Штрал

0 голосов
/ 08 марта 2014

Попробуйте этот метод расширения.Поток останется открытым (см. Конструктор GZipStream).Положение потока устанавливается на 0 после того, как сжатие выполнено.

public static void GZip(this Stream stream, byte[] data)
{
    using (var zipStream = new GZipStream(stream, CompressionMode.Compress, true))
    {
        zipStream.Write(data, 0, data.Length);
    }
    stream.Position = 0;
}

Вы можете использовать следующий тест:

[Test]
public void Test_gzip_data_is_restored_to_the_original_value()
{
    var stream = new MemoryStream();
    var data = new byte[]{1,2,3,4,5,6,7,8,9,10};

    stream.GZip(data);

    var decompressed = new GZipStream(stream, CompressionMode.Decompress);

    var data2 = new byte[10];
    decompressed.Read(data2,0,10);

    Assert.That(data, Is.EqualTo(data2));
}

Для получения дополнительной информации см .: http://msdn.microsoft.com/en-us/library/hh158301(v=vs.110).aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...