Pregunta

Estoy en una situación difícil en la que un extremo de servicio web en Java alojada en un servidor HTTP de IBM (IHS) requiere una cabecera Content-Length, a pesar de que supuestamente se ajusta a HTTP / 1.1. Si envío de la cabecera, todo funciona. Si lo dejo fuera, consigo una respuesta 500 de error que me informa que mi cuerpo entidad resultante estaba vacío (a pesar de que no lo era).

Hemos invertido mucho tiempo en nuestro cliente WCF para estos servicios (desarrollado por un tercero) y me parece que no puede encontrar una buena forma de añadir una cabecera Content-Length a la solicitud. Soy capaz de añadir cabeceras arbitrarias (es decir, X-Dan-Lynn-Header) a la solicitud utilizando un IClientMessageInspector como se describe en entradas de blog como este , pero WCF parece ignorar una cabecera Content-Length.

Mis opciones son:

a) encontrar la manera de forzar WCF para añadir una cabecera Content-Length a la solicitud POST HTTP o,

b) encontrar o escribir un proxy HTTP extremadamente simples pero transparente que decora la solicitud con una cabecera Content-Length.

Gracias!

IClientMessageInspector.BeforeSendRequest muestra:


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

Ejemplo de solicitud generada por WCF (y el IClientMessageInspector anterior):

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>
¿Fue útil?

Solución

descubierto. Ajuste de la unión a utilizar transferMode = "streaming" estaba causando un Transfer-Encoding: fragmentada. Necesitábamos transferencias streaming debido a muy grandes respuestas del servicio web, por lo que fue capaz de ir con:

Bad:

transferMode="Streamed"

Buena:

transferMode="StreamedResponse"

Cambio de la unión a este resolvieron el problema:

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

Otros consejos

No estoy actualmente en condiciones de tratar realmente a ejecutar el código para ver qué pasa, pero algo así como

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/ biblioteca / aa395196.aspx para más información sobre cómo se puede utilizar el objeto OperationContextScope incluir cabeceras adicionales.

actualización: Tengo que decir que me parece esto una cuestión extraña. Me pregunto por qué no se está estableciendo la longitud del contenido. No estaría surprissed si su problema real está en otra parte.

transferMode = StreamedResponse en el app.config me ha ayudado también por un problema similar al suyo. Tenía una arquitectura de WCF de Sync Framework y Squid Proxy 3.1.20 no como el streaming transferMode Muchas gracias!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top