HTTP-заголовок длиной с содержимое WCF в исходящем сообщении

StackOverflow https://stackoverflow.com/questions/1365295

Вопрос

Я нахожусь в сложной ситуации, в которой конечная точка веб-службы Java, размещенная на IBM HTTP Server (IHS), требует заголовка Content-Length , хотя он предположительно соответствует HTTP / 1.1.Если я отправляю заголовок, все работает.Если я оставлю его выключенным, я получу ответ с ошибкой 500, информирующий меня о том, что мое тело объекта POST было пустым (хотя это было не так).

Мы потратили значительное время на наш клиент WCF для этих сервисов (разработанный третьей стороной), и, похоже, я не могу найти хорошего способа добавить заголовок Content-Length к запросу.Я могу добавлять произвольные заголовки (т.е.X-Dan-Lynn-Header) на запрос с использованием IClientMessageInspector, как описано в записи в блоге, подобные этому, но WCF, похоже, игнорирует заголовок Content-Length .

Мои варианты таковы:

a) выясните, как заставить WCF добавить заголовок Content-Length к HTTP POST-запросу или,

б) найдите или напишите чрезвычайно простой, но прозрачный HTTP-прокси, который украшает запрос заголовком длиной с содержимое.

Спасибо!

Пример IClientMessageInspector.Перед отправкой запроса:


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="Streamed" приводила к кодированию передачи:разрезанный на куски.Нам нужны были потоковые передачи из-за очень больших откликов от веб-сервиса, поэтому я смог перейти с:

Плохой:

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>

Другие советы

В настоящее время я не могу на самом деле попытаться запустить код, чтобы посмотреть, что произойдет, но что-то вроде

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 для включения дополнительных заголовков.

Обновить: Я должен сказать, что нахожу это странной проблемой.Интересно, почему длина содержимого не задается.Я не был бы удивлен, если бы ваша настоящая проблема была где-то в другом месте.

TransferMode=StreamedResponse в app.config тоже помог мне с проблемой, похожей на вашу.У меня была архитектура WCF для Sync Framework, и Squid proxy 3.1.20 не понравился потоковый режим передачи Большое спасибо!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top