2010-12-11 10 views
7

He logrado enable inbound HTTP compression on ASP.NET (es decir, compresión de HTTP solicitudes, no solo respuestas) pero ahora estoy luchando en el lado del cliente (aplicación C#/.NET 4.0).Cómo comprimir las solicitudes HTTP de WCF .NET en el nivel de transporte?

me gustaría:

  • añadir la cabecera HTTP Content-Encoding: gzip
  • cuerpo compresa HTTP con GZip

a todas las peticiones HTTP salientes emitidas por un canal de WCF.

Las soluciones que no funcionan hasta ahora:

  • con IClientMessageInspector que puede comprimir el mensaje, pero no da cuenta de todo el cuerpo HTTP como el sobre no se comprime.
  • mismo que para un codificador de mensajes personalizado, comprima el mensaje, no el sobre, no afecte a los encabezados de solicitud de HTTP.

¿Alguna idea de cómo imitar el comportamiento de IHttpModule (ver la respuesta inicial) en el lado del cliente?

+2

No es realmente una respuesta directa (por lo que no se publicó como uno), pero dejaría de lado esto enviando menos bytes, en mi caso cambiando el serializador por algo mucho más compacto (los mismos datos, mucho más pequeño en el cable) –

+0

(avíseme si quiere más detalles, es un tema del que puedo hablar durante horas) –

+0

Marc, sí, el serializador menos prolijo también es un opción. Un beneficio del enfoque aquí es que desacopla completamente el problema de compresión de la codificación del mensaje, más o menos lo que la compresión HTTP clásica logra para las respuestas. –

Respuesta

5

El codificador de mensaje descrito here debería hacer el trabajo.

He probado utilizando el ejemplo descargado del enlace disponible en el artículo anterior (el proyecto InstallDrive \ WF_WCF_Samples \ WCF \ Extensibility \ MessageEncoder \ Compression desde this) y Fiddler.

Tenga en cuenta que el ejemplo de MSDN tiene un error que deberá corregir para que funcione correctamente. En el GZipMessageEncoderFactory clase, CompressBuffer método, la siguiente línea

ArraySegment<byte> byteArray = new ArraySegment<byte>(bufferedBytes, messageOffset, bufferedBytes.Length - messageOffset); 

debe sustituirse con

ArraySegment<byte> byteArray = new ArraySegment<byte>(bufferedBytes, messageOffset, totalLength); 

Después de aplicar la anteriormente fijar todo el cuerpo del mensaje se comprime.

Para comprobar que la compresión es correcta, puede utilizar la opción AutoDecode de Fiddler. Sin embargo, AutoDecode solo descomprimirá el mensaje si tiene un encabezado HTTP Content-Encoding: gzip.

Agregar encabezados HTTP a llamadas de mensajes WCF no es estrecho, dado que WCF fue diseñado para ser independiente del transporte y las aplicaciones WCF no deben manejar elementos específicos de un determinado método de transporte.

Sin embargo, para el propósito de esta aplicación pude hacerlo utilizando el siguiente fragmento de código:

public string Echo(string input) 
{ 
    using (OperationContextScope opScope = new OperationContextScope((IContextChannel)base.Channel)) 
    { 
     HttpRequestMessageProperty reqProps = new HttpRequestMessageProperty(); 
     reqProps.Headers["Content-Encoding"] = "gzip"; 
     OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = reqProps; 

     return base.Channel.Echo(input); 
    } 
} 

Echo es uno de los métodos de cliente a partir de la muestra de MSDN y en su interior que estoy con el acceso a contexto de operación actual para agregar un encabezado HTTP.

Háganme saber si necesita ayuda adicional.

+1

FYI - No encontré el error con el ejemplo de MSDN, pero perdí tiempo suponiendo que ... – hB0

-1

Hubiera pensado que podría habilitar el cifrado para lograr la compresión. Creo que tengo razón al decir que todos los algoritmos de encriptación comunes también comprimen los datos para evitar producir patrones obvios en los datos comprimidos. Como efecto colateral, su servicio será más seguro :)

+0

Creo que es incorrecto: https://security.stackexchange.com/a/19970/45228 – DarcyThomas

Cuestiones relacionadas