使用 gzip 压缩 HttpWebRequest
Compress a HttpWebRequest using gzip
我正在开发一个 .NET 4.0
控制台应用程序作为 SOAP Web Service
客户端,它将数据 (POST) 发送到 third-party。我无法控制 server-side 上的 Web 服务。 third-party 确实提供了 WSDL's
供使用,我能够导入它们并成功使用它们。但是,需要使用 gzip
压缩请求消息,而我终究无法弄清楚如何使用代理服务来压缩请求消息。
This topic 在这里,让我相信如果不能同时控制客户端和服务器代码,就无法压缩请求。由于这一发现,我在我的应用程序中编写了代码,以在 XDocument
object 中手动创建 SOAP XML
;然后,填充 WSDL
代理 class object 中的值,我之前已对客户端应用程序进行编码以使用这些值。
此客户端的第一个要求是发送通过 gzip
压缩的消息。经过一些研究,我发现答案很简单,只需将 HttpRequestHeader.AcceptEncoding, "gzip, deflate"
添加到请求 header 即可。不幸的是,这样做似乎没有用。
目前,我正在检索的证书不是真正的证书。在部署到测试环境以进行实际服务测试之前,我正在尝试使代码尽可能合理。
- 有没有办法通过代理调用 (
wsdl
) 压缩请求?
- 为了正确压缩
HttpWebRequest
我是否遗漏了什么?
- 是否有其他错误导致返回错误消息?
如果请求本身没问题,我希望与身份验证有关的不同消息无效。
- 有没有办法通过
app.config
完成压缩?
下一组要求我对如何handle/what有点困惑。假设我已将请求的 ContentType
设置为什么,我应该如何(以及添加什么)才能将 content-transfer-encoding
部分添加到请求中?如果ContentType
不正确,我应该如何添加这些信息?
The content type for the SOAP Evenlope with MTOM encoded attachment must be "application/xop+xml" and the content-transfer-encoding must be 8-bit.
我已经对下面的代码进行了几次迭代,但是,我相信相关片段是最简单形式的代码。如果还有其他有用的信息,请告诉我。
创建 HttpWebRequest 的方法:
private static HttpWebRequest CreateWebRequest(SoapAction action)
{
string url = GetUrlAddress(action);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate");
request.Headers.Add("SOAPAction", action.ToString());
request.ContentType = "application/xop+xml";
request.Accept = "text/xml";
request.Method = "POST";
request.ClientCertificates.Add(/* Retrieve X509Certificate Object*/);
return request;
}
发送请求代码:
using (Stream stream = request.GetRequestStream())
{
soapXml.Save(stream);
}
检索响应的代码:
这就是我检索正在发生的错误消息的方式
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (StreamReader reader = new StreamReader(response, Encoding.Default))
{
File.AppendAllText(filePath, response.Headers.ToString());
File.AppendAllText(filePath, reader.ReadToEnd());
}
}
}
catch (WebException ex)
{
using (var stream = ex.Response.GetResponseStream())
{
using (var reader = new StreamReader(stream))
{
Console.WriteLine(reader.ReadToEnd());
}
}
}
收到错误消息:
The request message must be sent using HTTP compression (RFC 1952 - GZIP).
使用以下代码代替您当前的代码发送请求。
using (Stream stream = request.GetRequestStream())
using (GZipStream gz = new GZipStream(stream, CompressionMode.Compress, false))
{
soapXml.Save(gz);
}
编辑:可能需要使用 "new GZipStream(stream, CompressionMode.Compress, true)"。不能确定该构造函数参数将如何影响 Web 请求流。
我想我可以通过将以下内容添加到 HttpWebRequest
方法来解决压缩错误消息:
request.Headers.Add(HttpRequestHeader.ContentEncoding, "gzip");
更新了创建 HttpWebRequest 的方法:
private static HttpWebRequest CreateWebRequest(SoapAction action)
{
string url = GetUrlAddress(action);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate");
request.Headers.Add(HttpRequestHeader.ContentEncoding, "gzip");
request.Headers.Add("SOAPAction", action.ToString());
request.ContentType = "application/xop+xml";
request.Accept = "text/xml";
request.Method = "POST";
request.ClientCertificates.Add(/* Retrieve X509Certificate Object*/);
return request;
}
我正在开发一个 .NET 4.0
控制台应用程序作为 SOAP Web Service
客户端,它将数据 (POST) 发送到 third-party。我无法控制 server-side 上的 Web 服务。 third-party 确实提供了 WSDL's
供使用,我能够导入它们并成功使用它们。但是,需要使用 gzip
压缩请求消息,而我终究无法弄清楚如何使用代理服务来压缩请求消息。
This topic 在这里,让我相信如果不能同时控制客户端和服务器代码,就无法压缩请求。由于这一发现,我在我的应用程序中编写了代码,以在 XDocument
object 中手动创建 SOAP XML
;然后,填充 WSDL
代理 class object 中的值,我之前已对客户端应用程序进行编码以使用这些值。
此客户端的第一个要求是发送通过 gzip
压缩的消息。经过一些研究,我发现答案很简单,只需将 HttpRequestHeader.AcceptEncoding, "gzip, deflate"
添加到请求 header 即可。不幸的是,这样做似乎没有用。
目前,我正在检索的证书不是真正的证书。在部署到测试环境以进行实际服务测试之前,我正在尝试使代码尽可能合理。
- 有没有办法通过代理调用 (
wsdl
) 压缩请求? - 为了正确压缩
HttpWebRequest
我是否遗漏了什么? - 是否有其他错误导致返回错误消息?
如果请求本身没问题,我希望与身份验证有关的不同消息无效。 - 有没有办法通过
app.config
完成压缩?
下一组要求我对如何handle/what有点困惑。假设我已将请求的 ContentType
设置为什么,我应该如何(以及添加什么)才能将 content-transfer-encoding
部分添加到请求中?如果ContentType
不正确,我应该如何添加这些信息?
The content type for the SOAP Evenlope with MTOM encoded attachment must be "application/xop+xml" and the content-transfer-encoding must be 8-bit.
我已经对下面的代码进行了几次迭代,但是,我相信相关片段是最简单形式的代码。如果还有其他有用的信息,请告诉我。
创建 HttpWebRequest 的方法:
private static HttpWebRequest CreateWebRequest(SoapAction action)
{
string url = GetUrlAddress(action);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate");
request.Headers.Add("SOAPAction", action.ToString());
request.ContentType = "application/xop+xml";
request.Accept = "text/xml";
request.Method = "POST";
request.ClientCertificates.Add(/* Retrieve X509Certificate Object*/);
return request;
}
发送请求代码:
using (Stream stream = request.GetRequestStream())
{
soapXml.Save(stream);
}
检索响应的代码:
这就是我检索正在发生的错误消息的方式
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (StreamReader reader = new StreamReader(response, Encoding.Default))
{
File.AppendAllText(filePath, response.Headers.ToString());
File.AppendAllText(filePath, reader.ReadToEnd());
}
}
}
catch (WebException ex)
{
using (var stream = ex.Response.GetResponseStream())
{
using (var reader = new StreamReader(stream))
{
Console.WriteLine(reader.ReadToEnd());
}
}
}
收到错误消息:
The request message must be sent using HTTP compression (RFC 1952 - GZIP).
使用以下代码代替您当前的代码发送请求。
using (Stream stream = request.GetRequestStream())
using (GZipStream gz = new GZipStream(stream, CompressionMode.Compress, false))
{
soapXml.Save(gz);
}
编辑:可能需要使用 "new GZipStream(stream, CompressionMode.Compress, true)"。不能确定该构造函数参数将如何影响 Web 请求流。
我想我可以通过将以下内容添加到 HttpWebRequest
方法来解决压缩错误消息:
request.Headers.Add(HttpRequestHeader.ContentEncoding, "gzip");
更新了创建 HttpWebRequest 的方法:
private static HttpWebRequest CreateWebRequest(SoapAction action)
{
string url = GetUrlAddress(action);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate");
request.Headers.Add(HttpRequestHeader.ContentEncoding, "gzip");
request.Headers.Add("SOAPAction", action.ToString());
request.ContentType = "application/xop+xml";
request.Accept = "text/xml";
request.Method = "POST";
request.ClientCertificates.Add(/* Retrieve X509Certificate Object*/);
return request;
}