如何在传输级别压缩来自WCF .NET的HTTP请求?

时间:2010-12-11 09:57:51

标签: .net wcf compression httpwebrequest gzip

我已经设法enable inbound HTTP compression on ASP.NET(即压缩HTTP 请求,而不仅仅是响应)但我现在正在客户端(C#/ .NET 4.0应用程序)上苦苦挣扎。

我想:

  • 添加HTTP标头Content-Encoding: gzip
  • 使用GZip压缩HTTP正文

到WCF通道发出的所有出站HTTP请求。

到目前为止无效的解决方案:

  • with IClientMessageInspector我可以压缩邮件,但它不会占用整个HTTP正文,因为信封没有被压缩。
  • 对于自定义消息编码器,压缩消息而不是信封,对HTTP请求标头没有影响。

知道如何在客户端模仿IHttpModule行为(请参阅初始响应)吗?

2 个答案:

答案 0 :(得分:5)

描述的消息编码器here应该完成这项工作。

我已经使用从上面文章中提供的链接下载的示例(来自this的InstallDrive \ WF_WCF_Samples \ WCF \ Extensibility \ MessageEncoder \ Compression项目)和Fiddler进行了测试。

请注意,MSDN示例有一个错误,您需要修复该错误才能使其正常工作。在GZipMessageEncoderFactory类,CompressBuffer方法中,以下行

ArraySegment<byte> byteArray = new ArraySegment<byte>(bufferedBytes, messageOffset, bufferedBytes.Length - messageOffset);

应替换为

ArraySegment<byte> byteArray = new ArraySegment<byte>(bufferedBytes, messageOffset, totalLength);

应用上述修复后,整个邮件正文将被压缩。

为了检查压缩是否正确,您可以使用Fiddler的AutoDecode选项。但是,如果消息具有Content-Encoding: gzip HTTP标头,则AutoDecode将仅解压缩该消息。

向WCF消息调用添加HTTP标头并不是一个前沿,因为WCF被设计为与传输无关,而WCF应用程序不应处理特定于某种传输方法的元素。

但是,出于本申请的目的,我能够使用以下代码进行操作:

public string Echo(string input)
{
    using (OperationContextScope opScope = new OperationContextScope((IContextChannel)base.Channel))
    {
        HttpRequestMessageProperty reqProps = new HttpRequestMessageProperty();
        reqProps.Headers["Content-Encoding"] = "gzip";
        OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = reqProps;

        return base.Channel.Echo(input);
    }
}

Echo是MSDN示例中的客户端方法之一,我在其中访问当前操作上下文以添加HTTP头。

如果您需要其他帮助,请与我们联系。

答案 1 :(得分:-1)

我原以为你可以启用加密来实现压缩。我认为我说的是所有常见的加密算法都会压缩数据以避免在压缩数据中产生明显的模式。作为副作用,您的服务将更安全:)