WebHttpResponse 中的 GZipStream 不产生数据

发布于 2024-10-09 02:30:34 字数 1496 浏览 0 评论 0原文

我想为支持它的客户端压缩我的 HTTP 响应。我正在使用 C# Web 服务器

以下是用于发送标准响应的代码:

IHttpClientContext context = (IHttpClientContext)sender;
IHttpRequest request = e.Request;

string responseBody = "This is some random text";

IHttpResponse response = request.CreateResponse(context);

using (StreamWriter writer = new StreamWriter(response.Body))
{
    writer.WriteLine(responseBody);
    writer.Flush();
    response.Send();
}

上面的代码工作正常。现在我在下面添加了 gzip 支持。当我使用支持 gzip 或自定义方法的浏览器对其进行测试时,它返回一个空字符串。我确信我错过了一些简单的东西,但我就是找不到它......

IHttpClientContext context = (IHttpClientContext)sender;
IHttpRequest request = e.Request;

string acceptEncoding = request.Headers["Accept-Encoding"];
string responseBody = "This is some random text";

IHttpResponse response = request.CreateResponse(context);

if (acceptEncoding != null && acceptEncoding.Contains("gzip"))
{
    byte[] bytes = ASCIIEncoding.ASCII.GetBytes(responseBody);
    response.AddHeader("Content-Encoding", "gzip");

    using (GZipStream writer = new GZipStream(response.Body, CompressionMode.Compress))
    {
         writer.Write(bytes, 0, bytes.Length);
         writer.Flush();
         response.Send();
    }
 }

 else
 {
     using (StreamWriter writer = new StreamWriter(response.Body))
     {
           writer.WriteLine(responseBody);
           writer.Flush();
           response.Send();
      }
 }

I want to compress my HTTP Responses for client that supports it. I'm using C# Webserver.

Here is the code used to send a standard response:

IHttpClientContext context = (IHttpClientContext)sender;
IHttpRequest request = e.Request;

string responseBody = "This is some random text";

IHttpResponse response = request.CreateResponse(context);

using (StreamWriter writer = new StreamWriter(response.Body))
{
    writer.WriteLine(responseBody);
    writer.Flush();
    response.Send();
}

The code above works fine. Now I added gzip support below. When I test it with a browser that supports gzip or a custom method, it returns an empty string. I'm sure I'm missing something simple, but I just can't find it...

IHttpClientContext context = (IHttpClientContext)sender;
IHttpRequest request = e.Request;

string acceptEncoding = request.Headers["Accept-Encoding"];
string responseBody = "This is some random text";

IHttpResponse response = request.CreateResponse(context);

if (acceptEncoding != null && acceptEncoding.Contains("gzip"))
{
    byte[] bytes = ASCIIEncoding.ASCII.GetBytes(responseBody);
    response.AddHeader("Content-Encoding", "gzip");

    using (GZipStream writer = new GZipStream(response.Body, CompressionMode.Compress))
    {
         writer.Write(bytes, 0, bytes.Length);
         writer.Flush();
         response.Send();
    }
 }

 else
 {
     using (StreamWriter writer = new StreamWriter(response.Body))
     {
           writer.WriteLine(responseBody);
           writer.Flush();
           response.Send();
      }
 }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

迎风吟唱 2024-10-16 02:30:34

皮埃尔,皮埃尔,皮埃尔......

您的代码无法按预期工作。

GZipStream 在从底层流读取数据之前必须关闭。因为GZipStreamGZipStream.Dispose中写入了强制的gzip页脚。

以下代码将起作用:

using (MemoryStream stream = new MemoryStream())
{
     using (GZipStream gZipStream = new GZipStream(stream, CompressionMode.Compress))
     gZipStream.Write(bytes, 0, bytes.Length);

     byte[] compressed = stream.ToArray();
     response.Body.Write(compressed, 0, compressed.Length);

     response.Send();
}

Pierre, pierre, pierre....

Your code can't work as expected.

GZipStream must be closed before you read from the underlying stream. Because GZipStream write the mandatory gzip footer in GZipStream.Dispose.

The following code will work:

using (MemoryStream stream = new MemoryStream())
{
     using (GZipStream gZipStream = new GZipStream(stream, CompressionMode.Compress))
     gZipStream.Write(bytes, 0, bytes.Length);

     byte[] compressed = stream.ToArray();
     response.Body.Write(compressed, 0, compressed.Length);

     response.Send();
}
尐偏执 2024-10-16 02:30:34

也许我错了,但是您不需要 Content-Transfer-Encoding 标头吗? WebResponse 内部不提供这个吗?

Maybe I'm wrong, but don't you need a Content-Transfer-Encoding header? Doesn't WebResponse provide this internally?

为你鎻心 2024-10-16 02:30:34

尝试添加

response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);

try to add

response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
梦旅人picnic 2024-10-16 02:30:34

在与 WebForms 相关的情况下,我最终得到的结果是:

  • 不使用 .NET 的内置 GZip,而是使用 codeplex 中的 DotNetZip 库。转换很容易,因为它模仿内置的 GZip 类。
  • 首先将压缩数据写入 MemoryStream,然后才将其重新写入 Response 流。

然而,我并没有针对网络浏览器:我只对通过 http 发送压缩数据进行性能测试感兴趣。

如果问题出在您的问题的压缩部分,也许这会对您有所帮助。

In a related situation with WebForms I ended up:

  • Not using .NET's build-in GZip but the DotNetZip library from codeplex. Transition was easy as it mimics the built-in GZip classes.
  • Writing the zipped data to a MemoryStream first and only then re-write it to the Response stream.

I did not, however, target webbrowsers with that: I was only interested in sending zipped data for a performance test over http.

If the issue lies withing the zipping part of your problem, maybe this will help you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文