3

私は、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) 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>
4

3 に答える 3

5

理解した。transferMode="Streamed" を使用するようにバインディングを設定すると、Transfer-Encoding: chunked が発生していました。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>
于 2009-09-02T01:21:18.017 に答える
1

現在、実際にコードを実行して何が起こるかを確認することはできませんが、

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;      
}

OperationContextScope オブジェクトを使用して追加のヘッダーを含める方法の詳細については、 http://msdn.microsoft.com/en-us/library/aa395196.aspxを参照してください。

更新: これは奇妙な問題だと言わざるを得ません。コンテンツの長さが設定されていないのはなぜでしょうか。あなたの実際の問題がどこかにあるとしても、私は驚かないでしょう。

于 2009-09-02T00:34:34.507 に答える
0

app.config の transferMode=StreamedResponse は、あなたと同様の問題にも役立ちました。Sync Framework 用の WCF アーキテクチャがあり、Squid プロキシ 3.1.20 は Streamed transferMode が好きではありませんでした。

于 2015-03-05T08:23:26.617 に答える