Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get HTTP Header in WCF MessageEncoder

Tags:

rest

c#

.net

http

wcf

I'm currently writing a GZIP compression for my selfhosted WCF REST application. I have a custom implementation of the .NET 'MessageEncoder' class and a custom implementation of the 'WebContentTypeMapper' class .

How can I retrieve the http headers in the 'ReadMessage' function and in the 'GetMessageFormatForContentType' function? I'd like to check the incoming request for the 'Content-Encoding' header before decompressing the input.

Thank You.

like image 310
Mimefilt Avatar asked Aug 20 '12 13:08

Mimefilt


3 Answers

This is what you can do

if (WebOperationContext.Current.IncomingRequest.Headers["Content-Encoding"] == WHAT YOU WANT)
{
            // Do what you like to do here
}

Hope this helps.

Thanks.

like image 107
Tabish Sarwar Avatar answered Nov 02 '22 22:11

Tabish Sarwar


You could try with WebOperationContext.Current or OperationContext.Current (depending of your binding). But unfortunately i think you cannot do this within the MessageEncoder implementation itself because it's too late in the process because by the time the MessageEncoder is asked to write the message contents the message frame, in this case the HTTP headers, has already been written. So, you would also need additional behavior, in the form of an IOperationBehavior, applied to your operations that sets the headers accordingly. In one of my personnal implementation, i have solved this by adding a GzipExtension in OperationContext with a custom message inspector. As Alex said, IIS already have a feature called dynamic compression that can compression any configured content type.

like image 20
Cybermaxs Avatar answered Nov 02 '22 23:11

Cybermaxs


I don't believe you will be able to get directly to the header from the CustomMessageEncoder. What you may be able to do is leverage the updated .NET 4.5 WCF BinaryMessageEncoderBindingElement. This now allows you to specify the compression type (such as Gzip) and automatically detects if the message body is compressed before attempting to decompress. See Whats's New in Windows Communication Foundation 4.5 for more details.

If you want to get to the header, one way you could try is to leverage HttpRequestMessageProperty in an implementation of IDispatchMessageInspector.

Simple example:

    public class MyDispatchMessageInspector : IDispatchMessageInspector
    {
        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            object obj;
            if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out obj))
            {
                 var httpRequestMessageProperty = obj as HttpRequestMessageProperty;

                 if (httpRequestMessageProperty != null 
                         && !string.IsNullOrEmpty(httpRequestMessageProperty.Headers["content-encoding"]))
                 {
                    ...
                 }
            }
            return null;
     }
     ...
}

Another option is to access the OperationContext using the following:

int index = System.ServiceModel.OperationContext.Current.IncomingMessageHeaders.FindHeader("content-encoding", "");
string contentEncodeHeaderValue = System.ServiceModel.OperationContext.Current.IncomingMessageHeaders.GetHeader<string>(index);
like image 29
Capps Avatar answered Nov 02 '22 23:11

Capps