出站消息上的 WCF Content-Length HTTP 标头
我遇到了一个棘手的情况,IBM HTTP Server (IHS) 上托管的 Java Web 服务端点需要 Content-Length 标头,尽管它应该符合 HTTP/1.1。如果我发送标头,一切正常。如果我将其关闭,我会收到 500 错误响应,通知我我的 POST 实体主体为空(即使它不是)。
我们在 WCF 客户端上投入了大量时间来提供这些服务(由第三方开发),但我似乎找不到将 Content-Length 标头附加到请求的好方法。我可以使用 IClientMessageInspector 将任意标头(即 X-Dan-Lynn-Header)添加到请求中,如 类似这样的博客文章,但 WCF 似乎忽略了 Content-Length 标头。
我的选择是:
a) 弄清楚如何强制 WCF 将 Content-Length 标头附加到 HTTP POST 请求,或者
b) 查找或编写一个极其简单但透明的 HTTP 代理,用 Content-Length 标头装饰请求。
谢谢!
示例 IClientMessageInspector.BeforeSendRequest:
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
var buffer = request.CreateBufferedCopy(Int32.MaxValue);
var tempRequest = buffer.CreateMessage();
HttpRequestMessageProperty httpRequest = GetHttpRequestProp(tempRequest);
if (httpRequest != null)
{
if (string.IsNullOrEmpty(httpRequest.Headers[HttpRequestHeader.ContentLength]))
{
httpRequest.Headers.Add(HttpRequestHeader.ContentLength, GetMessageLength(buffer).ToString());
httpRequest.Headers.Add("X-Dan-Lynn-Header", "abcdefghijk");
}
}
request = tempRequest;
request.Properties[HttpRequestMessageProperty.Name] = httpRequest;
return null;
}
WCF 生成的示例请求(以及前面的 IClientMessageInspector):
POST /path/to/service HTTP/1.1
Content-Type: text/xml; charset=utf-8
X-Dan-Lynn-Header: abcdefghijk
SOAPAction: "http://tempuri.org/path/to/service/action"
Host: service.host.tld
Transfer-Encoding: chunked
Connection: Keep-Alive
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
.......body removed for clarity......
</s:Body>
</s:Envelope>
I'm in a tough situation in which a Java web service endpoint hosted on an IBM HTTP Server (IHS) requires a Content-Length header, although it supposedly conforms to HTTP/1.1. If I send the header, everything works. If I leave it off, I get a 500 error response informing me that my POST entity body was empty (even though it was not).
We've invested significant time into our WCF client for these services (developed by a third party) and I can't seem to find a good way to append a Content-Length header to the request. I am able to add arbitrary headers (i.e. X-Dan-Lynn-Header) to the request using an IClientMessageInspector as described in blog posts like this, but WCF seems to ignore a Content-Length header.
My options are:
a) figure out how to force WCF to append a Content-Length header to the HTTP POST request or,
b) find or write an extremely simple-yet-transparent HTTP proxy that decorates the request with a Content-Length header.
Thanks!
Sample IClientMessageInspector.BeforeSendRequest:
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
var buffer = request.CreateBufferedCopy(Int32.MaxValue);
var tempRequest = buffer.CreateMessage();
HttpRequestMessageProperty httpRequest = GetHttpRequestProp(tempRequest);
if (httpRequest != null)
{
if (string.IsNullOrEmpty(httpRequest.Headers[HttpRequestHeader.ContentLength]))
{
httpRequest.Headers.Add(HttpRequestHeader.ContentLength, GetMessageLength(buffer).ToString());
httpRequest.Headers.Add("X-Dan-Lynn-Header", "abcdefghijk");
}
}
request = tempRequest;
request.Properties[HttpRequestMessageProperty.Name] = httpRequest;
return null;
}
Sample request generated by WCF (and the preceding IClientMessageInspector):
POST /path/to/service HTTP/1.1
Content-Type: text/xml; charset=utf-8
X-Dan-Lynn-Header: abcdefghijk
SOAPAction: "http://tempuri.org/path/to/service/action"
Host: service.host.tld
Transfer-Encoding: chunked
Connection: Keep-Alive
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
.......body removed for clarity......
</s:Body>
</s:Envelope>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
想通了。将绑定设置为使用transferMode =“Streamed”会导致Transfer-Encoding:分块。由于网络服务的响应非常大,我们需要流式传输,因此我能够选择:
坏:
好:
更改对此的绑定解决了问题:
Figured it out. Setting the binding to use transferMode="Streamed" was causing a Transfer-Encoding: chunked. We needed streamed transfers due to very large responses from the web service, so I was able to go with:
Bad:
Good:
Changing the binding to this solved the problem:
我目前无法实际尝试运行代码来查看会发生什么,但类似
请参阅 http://msdn.microsoft.com/en-us/library/aa395196.aspx 了解有关如何使用 OperationContextScope 对象包含其他标头的详细信息。
更新:
我不得不说我觉得这是一个奇怪的问题。我想知道为什么没有设置内容长度。如果您的实际问题在其他地方,我不会感到惊讶。
I am not currently able to actually try to run the code to see what happens but something like
see http://msdn.microsoft.com/en-us/library/aa395196.aspx for more information on how you can use the OperationContextScope object to include additional headers.
update:
I do have to say I find this a strange issue. I wonder why the content length isn't being set. I wouldn't be surprissed if your actual problem is somewhere else.
app.config 中的transferMode=StreamedResponse 也帮助我解决了与您类似的问题。
我有一个用于同步框架的 WCF 架构,而 Squid 代理 3.1.20 不喜欢流式传输模式
非常感谢!
transferMode=StreamedResponse in the app.config helped me too for an issue similar to yours.
I had a WCF architecture for Sync Framework and Squid proxy 3.1.20 didn't like the Streamed transferMode
Many thanks !