Как сжать HttpWebRequest POST
Я пытаюсь отправить данные на сервер, который принимает сжатые данные. Код ниже работает очень хорошо, но он несжатый. Я не работал с сжатием или Gzip beofre, поэтому любая помощь аппроксимируется.
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());
}
Я собираю весь массив байтов? Нужно ли добавлять другие заголовки или удалять ту, которая уже существует?
Спасибо!
-Скотт
Ответы
Ответ 1
Чтобы ответить на заданный вами вопрос, с помощью сжатых данных POST, все, что вам нужно сделать, это обернуть поток запросов потоком gzip
using (Stream postStream = request.GetRequestStream())
{
using(var zipStream = new GZipStream(postStream, CompressionMode.Compress))
{
zipStream.Write(byteData, 0, byteData.Length);
}
}
Это совсем другое, чем запрос на ответ gzip, что гораздо более распространено.
Ответ 2
В Page_Load
событие:
Response.AddHeader("Content-Encoding", "gzip");
И для создания сжатых запросов:
HttpWebRequest и GZip Http Responses от Рика Стралла
Ответ 3
Я также получил сообщение "Не могу закрыть поток до тех пор, пока все байты не записаны", используя код, похожий на tnyfst. Проблема заключалась в том, что у меня было:
request.ContentLength = binData.Length;
где binData - это мои сырые данные перед сжатием. Очевидно, что длина сжатого содержимого будет отличаться, поэтому я просто удалил эту строку и закончил с этим кодом:
using (GZipStream zipStream = new GZipStream(request.GetRequestStream(), CompressionMode.Compress))
{
zipStream.Write(binData, 0, binData.Length);
}
Ответ 4
Попробуйте этот метод расширения.
Поток будет оставлен открытым (см. Конструктор 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