System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage C# (CSharp) Method

ProcessMessage() private method

private ProcessMessage ( IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage &responseMsg, ITransportHeaders &responseHeaders, Stream &responseStream ) : ServerProcessing
sinkStack IServerChannelSinkStack
requestMsg IMessage
requestHeaders ITransportHeaders
requestStream Stream
responseMsg IMessage
responseHeaders ITransportHeaders
responseStream Stream
return ServerProcessing
        public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack,
            IMessage requestMsg,
            ITransportHeaders requestHeaders, Stream requestStream,
            out IMessage responseMsg, out ITransportHeaders responseHeaders, 
            out Stream responseStream)
        {
            if (requestMsg != null)
            {
                // The message has already been deserialized so delegate to the next sink.
                return _nextSink.ProcessMessage(
                    sinkStack,
                    requestMsg, requestHeaders, requestStream, 
                    out responseMsg, out responseHeaders, out responseStream);
            }
        
            if (requestHeaders ==  null)
                throw new ArgumentNullException("requestHeaders");

            BaseTransportHeaders wkRequestHeaders = requestHeaders as BaseTransportHeaders;
        
            ServerProcessing processing;
        
            responseHeaders = null;
            responseStream = null;

            String verb = null;
            String contentType = null;

            bool bCanServiceRequest = true;

            // determine the content type
            String contentTypeHeader = null;
            if (wkRequestHeaders != null)
                contentTypeHeader = wkRequestHeaders.ContentType;
            else
                contentTypeHeader = requestHeaders["Content-Type"] as String;
            if (contentTypeHeader != null)
            {
                String charsetValue;
                HttpChannelHelper.ParseContentType(contentTypeHeader,
                                                   out contentType, out charsetValue);
            }

            // check to see if Content-Type matches
            if ((contentType != null) &&
                (String.CompareOrdinal(contentType, CoreChannel.BinaryMimeType) != 0))
            {
                bCanServiceRequest = false;                
            }

            // check for http specific verbs
            if (_protocol == Protocol.Http)
            {
                verb = (String)requestHeaders["__RequestVerb"];    
                if (!verb.Equals("POST") && !verb.Equals("M-POST"))
                    bCanServiceRequest = false;
            }

            // either delegate or return an error message if we can't service the request
            if (!bCanServiceRequest)
            {
                // delegate to next sink if available
                if (_nextSink != null)
                {
                    return _nextSink.ProcessMessage(sinkStack, null, requestHeaders, requestStream,   
                        out responseMsg, out responseHeaders, out responseStream);
                }
                else
                {
                    // send back an error message
                    if (_protocol == Protocol.Http)
                    {
                        // return a client bad request error     
                        responseHeaders = new TransportHeaders();
                        responseHeaders["__HttpStatusCode"] = "400";
                        responseHeaders["__HttpReasonPhrase"] = "Bad Request";
                        responseStream = null;
                        responseMsg = null;
                        return ServerProcessing.Complete;
                    }
                    else
                    {
                        // The transport sink will catch this and do something here.
                        throw new RemotingException(
                            CoreChannel.GetResourceString("Remoting_Channels_InvalidRequestFormat"));
                    }
                }
            }
            

            try
            {
                String objectUri = null;

                bool bIsCustomErrorEnabled = true;
                object oIsCustomErrorEnabled = requestHeaders["__CustomErrorsEnabled"];
                if (oIsCustomErrorEnabled != null && oIsCustomErrorEnabled is bool){
                    bIsCustomErrorEnabled = (bool)oIsCustomErrorEnabled;
                }
                CallContext.SetData("__CustomErrorsEnabled", bIsCustomErrorEnabled);
              
                if (wkRequestHeaders != null)
                    objectUri = wkRequestHeaders.RequestUri;
                else
                    objectUri = (String)requestHeaders[CommonTransportKeys.RequestUri];              
            
                if (objectUri != lastUri && RemotingServices.GetServerTypeForUri(objectUri) == null)
                    throw new RemotingException(
                        CoreChannel.GetResourceString("Remoting_ChnlSink_UriNotPublished"));
                else
                    lastUri = objectUri;
            
                PermissionSet currentPermissionSet = null;                  
                if (this.TypeFilterLevel != TypeFilterLevel.Full) {                    
                    currentPermissionSet = new PermissionSet(PermissionState.None);                
                    currentPermissionSet.SetPermission(new SecurityPermission(SecurityPermissionFlag.SerializationFormatter));                    
                }
                                    
                try {
                    if (currentPermissionSet != null)
                        currentPermissionSet.PermitOnly();
                        
                    // Deserialize Request - Stream to IMessage
                    requestMsg = CoreChannel.DeserializeBinaryRequestMessage(objectUri, requestStream, _strictBinding, this.TypeFilterLevel);                    
                }
                finally {
                    if (currentPermissionSet != null)
                        CodeAccessPermission.RevertPermitOnly();
                }                                    
                requestStream.Close();

                if(requestMsg == null)
                {
                    throw new RemotingException(CoreChannel.GetResourceString("Remoting_DeserializeMessage"));
                }
                

                // Dispatch Call
                sinkStack.Push(this, null);
                processing =                    
                    _nextSink.ProcessMessage(sinkStack, requestMsg, requestHeaders, null,
                        out responseMsg, out responseHeaders, out responseStream);
                // make sure that responseStream is null
                if (responseStream != null)
                {
                    throw new RemotingException(
                        CoreChannel.GetResourceString("Remoting_ChnlSink_WantNullResponseStream"));
                }
                
                switch (processing)
                {

                case ServerProcessing.Complete:
                {
                    if (responseMsg == null)
                        throw new RemotingException(CoreChannel.GetResourceString("Remoting_DispatchMessage"));

                    sinkStack.Pop(this);

                    SerializeResponse(sinkStack, responseMsg,
                                      ref responseHeaders, out responseStream);
                    break;
                } // case ServerProcessing.Complete

                case ServerProcessing.OneWay:
                {
                    sinkStack.Pop(this);
                    break;
                } // case ServerProcessing.OneWay:

                case ServerProcessing.Async:
                {
                    sinkStack.Store(this, null);
                    break;   
                } // case ServerProcessing.Async
                    
                } // switch (processing)                
            }
            catch(Exception e)
            {
                processing = ServerProcessing.Complete;
                responseMsg = new ReturnMessage(e, (IMethodCallMessage)(requestMsg==null?new ErrorMessage():requestMsg));
                //TODO, sowmys: See if we could call SerializeResponse here
                //We always set __ClientIsClr here since interop is not an issue
                CallContext.SetData("__ClientIsClr", true);
                responseStream = (MemoryStream)CoreChannel.SerializeBinaryMessage(responseMsg, _includeVersioning);
                CallContext.FreeNamedDataSlot("__ClientIsClr");                
                responseStream.Position = 0;
                responseHeaders = new TransportHeaders();

                if (_protocol == Protocol.Http)
                {
                    responseHeaders["Content-Type"] = CoreChannel.BinaryMimeType;
                }
            }
            catch {
                processing = ServerProcessing.Complete;
                responseMsg = new ReturnMessage(new Exception(CoreChannel.GetResourceString("Remoting_nonClsCompliantException")), (IMethodCallMessage)(requestMsg==null?new ErrorMessage():requestMsg));
                //TODO, sowmys: See if we could call SerializeResponse here
                //We always set __ClientIsClr here since interop is not an issue
                CallContext.SetData("__ClientIsClr", true);
                responseStream = (MemoryStream)CoreChannel.SerializeBinaryMessage(responseMsg, _includeVersioning);
                CallContext.FreeNamedDataSlot("__ClientIsClr");                
                responseStream.Position = 0;
                responseHeaders = new TransportHeaders();

                if (_protocol == Protocol.Http)
                {
                    responseHeaders["Content-Type"] = CoreChannel.BinaryMimeType;
                }
            }
            finally{
                CallContext.FreeNamedDataSlot("__CustomErrorsEnabled");
            }

            return processing;
        } // ProcessMessage