送信メッセージの WCF Content-Length HTTP ヘッダー
-
21-09-2019 - |
質問
IBM HTTP Server (IHS) でホストされている Java Web サービス エンドポイントには、HTTP/1.1 に準拠しているはずにもかかわらず、Content-Length ヘッダーが必要であるという厳しい状況に陥っています。ヘッダーを送信すると、すべてが機能します。これをオフのままにすると、POST エンティティ本体が空であることを通知する 500 エラー応答が返されます (空ではなかった場合でも)。
これらのサービス (サード パーティによって開発された) の WCF クライアントに多大な時間を費やしてきましたが、要求に Content-Length ヘッダーを追加する良い方法が見つからないようです。任意のヘッダーを追加できます(つまり、X-Dan-Lynn-Header) を IClientMessageInspector を使用してリクエストに送信します。 このようなブログ投稿, ですが、WCF は Content-Length ヘッダーを無視するようです。
私の選択肢は次のとおりです。
a) WCF で Content-Length ヘッダーを HTTP POST 要求に強制的に追加する方法を見つけ出すか、
b) Content-Length ヘッダーでリクエストを装飾する、非常にシンプルでありながら透過的な HTTP プロキシを見つけるか作成します。
ありがとう!
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>
解決
それを考え出しました。設定transferMode =「ストリーミング」を使用して結合転送エンコーディングを引き起こしていた:チャンク。私たちは、Webサービスから非常に大きな反応によるストリーミング転送を必要とするので、私は一緒に行くことができました。
悪い:
transferMode="Streamed"
グッド:
transferMode="StreamedResponse"
問題を解決し、このへの結合を変更します
<basicHttpBinding>
<binding name="MyBinding" closeTimeout="00:30:00" openTimeout="00:30:00"
receiveTimeout="00:30:00" sendTimeout="00:30:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="16777216"
messageEncoding="Text" textEncoding="utf-8" transferMode="StreamedResponse"
useDefaultWebProxy="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="65536"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None" />
</binding>
</basicHttpBinding>
<basicHttpBinding>
<binding name="MyBinding" closeTimeout="00:30:00" openTimeout="00:30:00"
receiveTimeout="00:30:00" sendTimeout="00:30:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="16777216"
messageEncoding="Text" textEncoding="utf-8" transferMode="StreamedResponse"
useDefaultWebProxy="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="65536"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None" />
</binding>
</basicHttpBinding>
他のヒント
現在、実際にコードを実行して何が起こるかを確認することはできませんが、次のようなものです
WCFClient client = new WCFClient();
using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
{
HttpRequestMessageProperty req = new HttpRequestMessageProperty();
req.Headers.Add("Content-Length", "YOUR CONTENT LENGTH HERE");
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = req;
}
見る http://msdn.microsoft.com/en-us/library/aa395196.aspx OperationContextScope オブジェクトを使用して追加のヘッダーを含める方法の詳細については、「OperationContextScope オブジェクトを使用して追加のヘッダーを含める方法」を参照してください。
アップデート:これは奇妙な問題だと言わざるを得ません。なぜコンテンツの長さが設定されていないのか不思議です。あなたの実際の問題が別の場所にあるとしても、私は驚かないでしょう。
transferMode = StreamedResponse app.configをであなたと同様の問題のために、あまりにも私を助けました。 Sync Frameworkのとイカプロキシ3.1.20はストリーミングtransferModeを好きではなかったため、私は、WCFのアーキテクチャを持っていました 多くの感謝!