简体   繁体   English

如何压缩HttpWebRequest POST

[英]How to compress a HttpWebRequest POST

I am trying to post data to server that accepts compressed data. 我试图将数据发布到接受压缩数据的服务器。 The code below works just fine, but it is uncompressed. 下面的代码工作正常,但它是未压缩的。 I have not worked with compression or Gzip beofre, so any help is appriciated. 我没有使用压缩或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());
  }

Do I gzip the entire byte array? 我是否gzip整个字节数组? Do I need to add other headers or remove the one that is already there? 我是否需要添加其他标题或删除已存在的标题?

Thanks! 谢谢!

-Scott 斯科特

To answer the question you asked, to POST compressed data, all you need to do is wrap the request stream with a gzip stream 要回答您提出的问题,要POST压缩数据,您需要做的就是使用gzip流包装请求流

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

This is completely different than requesting a gzip response, which is a much more common thing to do. 这与请求gzip响应完全不同,这是一个更常见的事情。

I also received the "Cannot close stream until all bytes are written" error using code similar to tnyfst's. 我还使用类似于tnyfst的代码收到“无法关闭流直到写入所有字节”错误。 The problem was that I had: 问题是我有:

request.ContentLength = binData.Length;

where binData is my raw data before the compression. 其中binData是压缩前的原始数据。 Obviously the length of the compressed content would be different, so I just removed this line and ended up with this code: 显然,压缩内容的长度会有所不同,所以我只是删除了这一行并最终得到了这段代码:

using (GZipStream zipStream = new GZipStream(request.GetRequestStream(), CompressionMode.Compress))
{
    zipStream.Write(binData, 0, binData.Length);
}

In Page_Load event: Page_Load事件中:

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

And for making compressed requests: 并且用于制作压缩请求:

HttpWebRequest and GZip Http Responses by Rick Strahl Rick Strahl的 HttpWebRequest和GZip Http响应

Try this extension method. 试试这个扩展方法。 The stream will be left open (see the GZipStream constructor). 流将保持打开状态(请参阅GZipStream构造函数)。 The stream position is set to 0 after the compression is done. 压缩完成后,流位置设置为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;
}

You can use the following test: 您可以使用以下测试:

[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));
}

For more information see: http://msdn.microsoft.com/en-us/library/hh158301(v=vs.110).aspx 有关详细信息,请参阅: http//msdn.microsoft.com/en-us/library/hh158301(v = vs.110).aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM