Pop() public méthode

public Pop ( IServerChannelSink sink ) : Object
sink IServerChannelSink
Résultat Object
        internal void ServiceRequest(object state)
        {
            IMessage message;
            ITransportHeaders headers2;
            Stream stream2;
            HttpServerSocketHandler handler = (HttpServerSocketHandler) state;
            ITransportHeaders requestHeaders = handler.ReadHeaders();
            Stream requestStream = handler.GetRequestStream();
            requestHeaders["__CustomErrorsEnabled"] = handler.CustomErrorsEnabled();
            ServerChannelSinkStack sinkStack = new ServerChannelSinkStack();
            sinkStack.Push(this, handler);
            ServerProcessing processing = this._nextSink.ProcessMessage(sinkStack, null, requestHeaders, requestStream, out message, out headers2, out stream2);
            switch (processing)
            {
                case ServerProcessing.Complete:
                    sinkStack.Pop(this);
                    handler.SendResponse(stream2, "200", "OK", headers2);
                    break;

                case ServerProcessing.OneWay:
                    handler.SendResponse(null, "202", "Accepted", headers2);
                    break;

                case ServerProcessing.Async:
                    sinkStack.StoreAndDispatch(this, handler);
                    break;
            }
            if (processing != ServerProcessing.Async)
            {
                if (handler.CanServiceAnotherRequest())
                {
                    handler.BeginReadMessage();
                }
                else
                {
                    handler.Close();
                }
            }
        }
Exemple #2
0
        void ProcessMessage(IPEndPoint remote, ITransportHeaders requestHeaders, Stream requestStream)
        {
            // parse request uri
            var url = requestHeaders[CommonTransportKeys.RequestUri].ToString();
            string objectUri;
            UdpChannelHelper.Parse(url, out objectUri);
            objectUri = objectUri ?? url;
            requestHeaders[CommonTransportKeys.RequestUri] = objectUri;

            IMessage responseMsg;
            ITransportHeaders responseHeaders;
            Stream responseStream;

            // process message
            var stack = new ServerChannelSinkStack();
            stack.Push(this, null);
            var operation = NextChannelSink.ProcessMessage(stack, null, requestHeaders, requestStream,
                out responseMsg, out responseHeaders, out responseStream);

            switch (operation)
            {
                case ServerProcessing.Complete:
                    stack.Pop(this);
                    var transport = new UdpTransport(new UdpClient());
                    transport.Write(responseHeaders, responseStream, remote);
                    break;

                case ServerProcessing.Async:
                    stack.StoreAndDispatch(NextChannelSink, null);
                    break;

                case ServerProcessing.OneWay:
                    break;
            }
        }
        internal void ServiceRequest(Object state) 
        {
            IpcServerHandler ipcServerHandler = (IpcServerHandler)state; 
 
            // Read the headers from the stream, using the header size in the message
            ITransportHeaders headers = ipcServerHandler.ReadHeaders(); 

            // Get the request Stream
            Stream requestStream = ipcServerHandler.GetRequestStream();
            // customErrors should be disabled, since we are on the same machine 
            headers["__CustomErrorsEnabled"] = false;
 
            // process request 
            ServerChannelSinkStack sinkStack = new ServerChannelSinkStack();
            sinkStack.Push(this, ipcServerHandler); 

            IMessage responseMessage = null;
            ITransportHeaders responseHeaders = null;
            Stream responseStream = null; 
            WindowsIdentity identity = null;
            IPrincipal oldPrincipal = null; 
            bool impersonated = false; 
            bool principalChanged = false;
            ServerProcessing processing = ServerProcessing.Complete; 

            try{
                if (_secure)
                { 
                    IpcPort port = ipcServerHandler.Port;
                    port.ImpersonateClient(); 
                    oldPrincipal = Thread.CurrentPrincipal; 
                    principalChanged = true;
                    impersonated = true; 
                    identity = WindowsIdentity.GetCurrent();
                    // If the authentication mode is to identify callers only revert the impersonation immediately
                    if (!_impersonate)
                    { 
                        NativePipe.RevertToSelf();
                        Thread.CurrentPrincipal = new GenericPrincipal(identity, null); 
                        impersonated = false; 
                    }
                    else 
                    {
                        if (identity.ImpersonationLevel == TokenImpersonationLevel.Impersonation ||
                            identity.ImpersonationLevel == TokenImpersonationLevel.Delegation)
                        { 
                            // Set the current principal
                            Thread.CurrentPrincipal = new WindowsPrincipal(identity); 
                        } 
                        else
                            throw new RemotingException(CoreChannel.GetResourceString( 
                                                            "Remoting_Ipc_TokenImpersonationFailure"));
                    }
                }
 
                processing =
                        _nextSink.ProcessMessage(sinkStack, null, headers, requestStream, 
                                                 out responseMessage, 
                                                 out responseHeaders, out responseStream);
            } 
            catch( Exception e) {
                ipcServerHandler.CloseOnFatalError(e);
            }
            finally{ 
                // Revert the principal if we had changed the principal
                if (principalChanged) 
                { 
                    Thread.CurrentPrincipal = oldPrincipal;
                } 
                // Revert the impersonation if we had impersonated
                if (impersonated)
                {
                    NativePipe.RevertToSelf(); 
                    impersonated = false;
                } 
            } 

            // handle response 
            switch (processing)
            {

            case ServerProcessing.Complete: 
            {
                // Send the response. Call completed synchronously. 
                sinkStack.Pop(this); 
                // Send the response back to the client
                ipcServerHandler.SendResponse(responseHeaders, responseStream); 
                break;
            } // case ServerProcessing.Complete

            case ServerProcessing.OneWay: 
            {
                // No response needed, but the following method will make sure that 
                //   we send at least a skeleton reply if the incoming request was 
                //   not marked OneWayRequest (client/server metadata could be out of
                //   [....]). 
                ipcServerHandler.SendResponse(responseHeaders, responseStream);
                break;
            } // case ServerProcessing.OneWay
 
            case ServerProcessing.Async:
            { 
                sinkStack.StoreAndDispatch(this, ipcServerHandler); 
                break;
            }// case ServerProcessing.Async 

            } // switch (processing)

            // Start waiting for the next request 
            if (processing != ServerProcessing.Async)
            { 
                ipcServerHandler.BeginReadMessage(); 
            }
        } // ServiceRequest 
Exemple #4
0
        void ProcessClient(object state) 
        {
            try 
            {
                NamedPipeSocket socket = (NamedPipeSocket) state;

                ITransportHeaders requestHeaders;
                Stream requestStream;

                IpcTransport t = new IpcTransport(socket);
                t.Read(out requestHeaders, out requestStream);

                // parse the RequestUri
                string objectUri;
                string uri = (string) requestHeaders[CommonTransportKeys.RequestUri];
                IpcChannelHelper.Parse(uri, out objectUri);
                if (objectUri == null) objectUri = uri;
                requestHeaders[CommonTransportKeys.RequestUri] = objectUri;

                ServerChannelSinkStack stack = new ServerChannelSinkStack();
                stack.Push(this, null);

                IMessage responseMsg;
                ITransportHeaders responseHeaders;
                Stream responseStream;

                requestHeaders["__CustomErrorsEnabled"] = false;

                if (impersonate) 
                {
                    // TODO: Impersonate might throw exceptions. What to do with them?
                    socket.Impersonate();
                }

                ServerProcessing op = nextSink.ProcessMessage(
                    stack,
                    null,
                    requestHeaders,
                    requestStream,
                    out responseMsg,
                    out responseHeaders,
                    out responseStream
                    );

                if (impersonate) 
                {
                    NamedPipeSocket.RevertToSelf();
                }

                switch (op) 
                {
                    case ServerProcessing.Complete:
                        stack.Pop(this);
                        // send the response headers and the response data to the client
                        t.Write(responseHeaders, responseStream);
                        break;

                    case ServerProcessing.Async:
                        stack.StoreAndDispatch(nextSink, null);
                        break;

                    case ServerProcessing.OneWay:
                        break;
                }
            }
            catch (Exception)
            {
                // Console.WriteLine(ex);
            }
        }
        internal void ServiceRequest(object state)
        {
            IpcServerHandler handler = (IpcServerHandler) state;
            ITransportHeaders requestHeaders = handler.ReadHeaders();
            Stream requestStream = handler.GetRequestStream();
            requestHeaders["__CustomErrorsEnabled"] = false;
            ServerChannelSinkStack sinkStack = new ServerChannelSinkStack();
            sinkStack.Push(this, handler);
            IMessage responseMsg = null;
            ITransportHeaders responseHeaders = null;
            Stream responseStream = null;
            WindowsIdentity current = null;
            IPrincipal currentPrincipal = null;
            bool flag = false;
            bool flag2 = false;
            ServerProcessing complete = ServerProcessing.Complete;
            try
            {
                if (this._secure)
                {
                    handler.Port.ImpersonateClient();
                    currentPrincipal = Thread.CurrentPrincipal;
                    flag2 = true;
                    flag = true;
                    current = WindowsIdentity.GetCurrent();
                    if (!this._impersonate)
                    {
                        NativePipe.RevertToSelf();
                        Thread.CurrentPrincipal = new GenericPrincipal(current, null);
                        flag = false;
                    }
                    else
                    {
                        if ((current.ImpersonationLevel != TokenImpersonationLevel.Impersonation) && (current.ImpersonationLevel != TokenImpersonationLevel.Delegation))
                        {
                            throw new RemotingException(CoreChannel.GetResourceString("Remoting_Ipc_TokenImpersonationFailure"));
                        }
                        Thread.CurrentPrincipal = new WindowsPrincipal(current);
                    }
                }
                complete = this._nextSink.ProcessMessage(sinkStack, null, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream);
            }
            catch (Exception exception)
            {
                handler.CloseOnFatalError(exception);
            }
            finally
            {
                if (flag2)
                {
                    Thread.CurrentPrincipal = currentPrincipal;
                }
                if (flag)
                {
                    NativePipe.RevertToSelf();
                    flag = false;
                }
            }
            switch (complete)
            {
                case ServerProcessing.Complete:
                    sinkStack.Pop(this);
                    handler.SendResponse(responseHeaders, responseStream);
                    break;

                case ServerProcessing.OneWay:
                    handler.SendResponse(responseHeaders, responseStream);
                    break;

                case ServerProcessing.Async:
                    sinkStack.StoreAndDispatch(this, handler);
                    break;
            }
            if (complete != ServerProcessing.Async)
            {
                handler.BeginReadMessage();
            }
        }
Exemple #6
0
        } // TcpServerTransportSink
        
    
        internal void ServiceRequest(Object state)
        {
            TcpServerSocketHandler streamManager = (TcpServerSocketHandler)state;

            ITransportHeaders headers = streamManager.ReadHeaders();
            Stream requestStream = streamManager.GetRequestStream();
            RemotingServices.LogRemotingStage(CoreChannel.SERVER_MSG_RECEIVE);

            // process request
            ServerChannelSinkStack sinkStack = new ServerChannelSinkStack();
            sinkStack.Push(this, streamManager);

            IMessage responseMessage;
            ITransportHeaders responseHeaders;
            Stream responseStream;

            ServerProcessing processing = 
                _nextSink.ProcessMessage(sinkStack, null, headers, requestStream, 
                                         out responseMessage,
                                         out responseHeaders, out responseStream);

            // handle response
            switch (processing)
            {                    

            case ServerProcessing.Complete:
            {
                // Send the response. Call completed synchronously.
                sinkStack.Pop(this);
                RemotingServices.LogRemotingStage(CoreChannel.SERVER_RET_END);
                streamManager.SendResponse(responseHeaders, responseStream);
                break;
            } // case ServerProcessing.Complete
            
            case ServerProcessing.OneWay:
            {                       
                // No response needed, but the following method will make sure that
                //   we send at least a skeleton reply if the incoming request was
                //   not marked OneWayRequest (client/server metadata could be out of
                //   sync).
                streamManager.SendResponse(responseHeaders, responseStream);
                break;
            } // case ServerProcessing.OneWay

            case ServerProcessing.Async:
            {
                sinkStack.StoreAndDispatch(this, streamManager);
                break;
            }// case ServerProcessing.Async

            } // switch (processing) 
                   

            // async processing will take care if handling this later
            if (processing != ServerProcessing.Async)
            {
                if (streamManager.CanServiceAnotherRequest())
                    streamManager.BeginReadMessage();
                else
                    streamManager.Close();
            }
            
        } // ServiceRequest               
        } // IServerChannelSink
        
    
        internal void ServiceRequest(Object state)
        {        
            HttpServerSocketHandler streamManager = (HttpServerSocketHandler)state;

            ITransportHeaders headers = streamManager.ReadHeaders();
            Stream requestStream = streamManager.GetRequestStream();
            headers["__CustomErrorsEnabled"] = streamManager.CustomErrorsEnabled();

            // process request
            ServerChannelSinkStack sinkStack = new ServerChannelSinkStack();
            sinkStack.Push(this, streamManager);

            IMessage responseMessage;
            ITransportHeaders responseHeaders;
            Stream responseStream;

            ServerProcessing processing = 
                _nextSink.ProcessMessage(sinkStack, null, headers, requestStream, 
                                         out responseMessage,
                                         out responseHeaders, out responseStream);

            // handle response
            switch (processing)
            {                    

            case ServerProcessing.Complete:
            {
                // Send the response. Call completed synchronously.
                sinkStack.Pop(this);
                streamManager.SendResponse(responseStream, "200", "OK", responseHeaders);
                break;
            } // case ServerProcessing.Complete
            
            case ServerProcessing.OneWay:
            {
                // Just send back a 200 OK
                streamManager.SendResponse(null, "202", "Accepted", responseHeaders);
                break;
            } // case ServerProcessing.OneWay

            case ServerProcessing.Async:
            {
                sinkStack.StoreAndDispatch(this, streamManager);
                break;
            }// case ServerProcessing.Async

            } // switch (processing)


            // async processing will take care if handling this later
            if (processing != ServerProcessing.Async)
            {
                if (streamManager.CanServiceAnotherRequest())
                    streamManager.BeginReadMessage();
                else
                    streamManager.Close();
            }
            
        } // ServiceRequest
Exemple #8
0
        private void ProcessMessage(object waitCallbackState)
        {
            var requestMessage = (NullMessages.RequestMessage)waitCallbackState;

            // replace full url with object url
            var url = requestMessage.RequestHeaders[CommonTransportKeys.RequestUri].ToString();
            string objectUri;
            NullChannel.ParseUrl(url, out objectUri);
            objectUri = objectUri ?? url;
            requestMessage.RequestHeaders[CommonTransportKeys.RequestUri] = objectUri;
            requestMessage.Message.Properties["__Uri"] = objectUri;

            // add client address property for compatibility
            var callContext = requestMessage.Message.Properties["__CallContext"] as LogicalCallContext;
            callContext.SetData(ClientAddressSink.CallContextSlotName, IPAddress.Loopback);

            IMessage responseMsg;
            ITransportHeaders responseHeaders;
            Stream responseStream;

            // create sink stack to process request message
            var stack = new ServerChannelSinkStack();
            stack.Push(this, null);

            // process request message
            ServerProcessing serverProcessing;
            if (NextChannelSink != null)
            {
                // full processing mode, with deserialization
                serverProcessing = NextChannelSink.ProcessMessage(stack, null,
                    requestMessage.RequestHeaders, requestMessage.RequestStream,
                    out responseMsg, out responseHeaders, out responseStream);
            }
            else
            {
                // fast processing mode, bypassing deserialization
                serverProcessing = ChannelServices.DispatchMessage(stack, requestMessage.Message, out responseMsg);
                responseHeaders = null;
                responseStream = null;
            }

            // send back the reply
            switch (serverProcessing)
            {
                case ServerProcessing.Complete:
                    stack.Pop(this);
                    NullMessages.AddResponse(requestMessage, new NullMessages.ResponseMessage
                    {
                        Message = responseMsg,
                        ResponseHeaders = responseHeaders,
                        ResponseStream = responseStream
                    });
                    break;

                case ServerProcessing.Async:
                    stack.StoreAndDispatch(NextChannelSink, null);
                    break;

                case ServerProcessing.OneWay:
                    stack.Pop(this);
                    break;
            }
        }
		public void ProcessRequest(IConnection connection)
		{
			// parameters validation
			if (connection == null)
				throw new ArgumentNullException("connection");

			// receive request
			ITransportHeaders requestHeaders;
			Stream requestStream;
			connection.ReceiveRequest(out requestHeaders, out requestStream);

			// create sink stack for request processing
			ServerChannelSinkStack sinkStack = new ServerChannelSinkStack();
			sinkStack.Push(this, connection);	// save connection as state

			// process request
			ServerProcessing processing;
			IMethodReturnMessage methodReturn = null;
			ITransportHeaders responseHeaders = null;
			Stream responseStream = null;

			try
			{
				// call next sink to dispatch method call
				IMessage responseMsg;
				processing = _nextSink.ProcessMessage(sinkStack,
					null, requestHeaders, requestStream,
					out responseMsg, out responseHeaders, out responseStream);

				if (processing == ServerProcessing.Complete)
				{
					// response headers and stream can not be null at this point!
					if (responseHeaders == null)
						throw new ArgumentNullException("responseHeaders");
					if (responseStream == null)
						throw new ArgumentNullException("responseStream");

					// check response
					methodReturn = responseMsg as IMethodReturnMessage;
					if (methodReturn == null)
						throw new NotSupportedException();
				}
			}
			catch (Exception ex)
			{
				processing = ServerProcessing.Complete;
				methodReturn = new ReturnMessage(ex, null);
			}

			// handle response
			switch (processing)
			{
				case ServerProcessing.Complete:
				{
					// call completed synchronously - send response
					sinkStack.Pop(this);
					connection.SendResponse(methodReturn, responseHeaders, responseStream);
					break;
				}
				case ServerProcessing.OneWay:
				{
					// no response needed
					sinkStack.Pop(this);
					break;
				}
				case ServerProcessing.Async:
				{
					// call proceeded asynchronously
					sinkStack.StoreAndDispatch(this, connection);
					break;
				}
				default:
					throw new NotSupportedException();
			}
		}
        } // TcpServerTransportSink 
 

 
        internal void ServiceRequest(Object state)
        {
            TcpServerSocketHandler streamManager = (TcpServerSocketHandler)state;
 
            ITransportHeaders headers = streamManager.ReadHeaders();
            Stream requestStream = streamManager.GetRequestStream(); 
            headers["__CustomErrorsEnabled"] = streamManager.CustomErrorsEnabled(); 

            // process request 
            ServerChannelSinkStack sinkStack = new ServerChannelSinkStack();
            sinkStack.Push(this, streamManager);

            IMessage responseMessage; 
            ITransportHeaders responseHeaders;
            Stream responseStream; 
 
#if !FEATURE_PAL
            // If Impersonation was requested impersonate the client identity 
            WindowsIdentity identity = streamManager.ImpersonationIdentity;
            WindowsImpersonationContext context = null;
            IPrincipal oldPrincipal = null;
            bool principalChanged = false; 
            if(identity != null)
            { 
                oldPrincipal = Thread.CurrentPrincipal; 
                principalChanged = true;
                if (_impersonate) 
                {
                    Thread.CurrentPrincipal = new WindowsPrincipal(identity);
                    context = identity.Impersonate();
                } 
                else
                { 
                    Thread.CurrentPrincipal = new GenericPrincipal(identity, null); 
                }
            } 
#endif // !FEATURE_PAL
            ServerProcessing processing;
            // wrap Undo in an outer try block
            try{ 
                try{
                    processing = 
                        _nextSink.ProcessMessage(sinkStack, null, headers, requestStream, 
                                                 out responseMessage,
                                                 out responseHeaders, out responseStream); 
                }
                finally{
    #if !FEATURE_PAL
                    // Revert the principal if we had changed the principal 
                    if (principalChanged)
                    { 
                        Thread.CurrentPrincipal = oldPrincipal; 
                    }
                    // Revert the impersonation if we had impersonated 
                    if (_impersonate)
                    {
                        context.Undo();
                    } 
    #endif // !FEATURE_PAL
                } 
            } 
            catch { throw; }
 
            // handle response
            switch (processing)
            {
 
            case ServerProcessing.Complete:
            { 
                // Send the response. Call completed synchronously. 
                sinkStack.Pop(this);
                streamManager.SendResponse(responseHeaders, responseStream); 
                break;
            } // case ServerProcessing.Complete

            case ServerProcessing.OneWay: 
            {
                // No response needed, but the following method will make sure that 
                //   we send at least a skeleton reply if the incoming request was 
                //   not marked OneWayRequest (client/server metadata could be out of
                //   [....]). 
                streamManager.SendResponse(responseHeaders, responseStream);
                break;
            } // case ServerProcessing.OneWay
 
            case ServerProcessing.Async:
            { 
                sinkStack.StoreAndDispatch(this, streamManager); 
                break;
            }// case ServerProcessing.Async 

            } // switch (processing)

 
            // async processing will take care if handling this later
            if (processing != ServerProcessing.Async) 
            { 
                if (streamManager.CanServiceAnotherRequest())
                    streamManager.BeginReadMessage(); 
                else
                    streamManager.Close();
            }
 
        } // ServiceRequest
        private void ServerMain()
        {
            PipeConnection pipe = _pipe;
            _pipe = null;

            // Signal the guy to start waiting again... (w/ new event and endpoint)
            _event.Set();

            try
            {
                //TODO close the connection on a timeout
                //TODO if no activity for Nnnn milliseconds
                while (true)
                {
                    pipe.BeginReadMessage();
                    ITransportHeaders headers = pipe.ReadHeaders();
                    headers["__CustomErrorsEnabled"] = false;

                    Stream request = pipe.ReadStream();
                    pipe.EndReadMessage();

                    ServerChannelSinkStack stack = new ServerChannelSinkStack();
                    stack.Push(_transportSink, null);

                    IMessage responseMsg;
                    ITransportHeaders responseHeaders;
                    Stream responseStream;

                    ServerProcessing processing = _transportSink.NextChannelSink.ProcessMessage(stack,
                                                                    null,
                                                                    headers,
                                                                    request,
                                                                    out responseMsg,
                                                                    out responseHeaders,
                                                                    out responseStream);

                    // handle response
                    switch (processing)
                    {
                        case ServerProcessing.Complete:
                            // Send the response. Call completed synchronously.
                            stack.Pop(_transportSink);
                            WriteClientResponse(pipe, responseHeaders, responseStream);
                            break;

                        case ServerProcessing.OneWay:
                            break;

                        case ServerProcessing.Async:
                            stack.StoreAndDispatch(_transportSink, null);
                            break;
                    }
                }
            }
            catch (Exception e)
            {
                DBG.Info(null, "Terminating client connection: " + e.Message);
                WriteExceptionResponse(pipe, e.ToString());
            }
            finally
            {
                if (pipe != null)
                {
                    pipe.Dispose();
                }
               }
        }
        internal void ServiceRequest(object state)
        {
            ITransportHeaders headers2;
            Stream stream2;
            ServerProcessing processing;
            TcpServerSocketHandler handler = (TcpServerSocketHandler) state;
            ITransportHeaders requestHeaders = handler.ReadHeaders();
            Stream requestStream = handler.GetRequestStream();
            requestHeaders["__CustomErrorsEnabled"] = handler.CustomErrorsEnabled();
            ServerChannelSinkStack sinkStack = new ServerChannelSinkStack();
            sinkStack.Push(this, handler);
            WindowsIdentity impersonationIdentity = handler.ImpersonationIdentity;
            WindowsImpersonationContext context = null;
            IPrincipal currentPrincipal = null;
            bool flag = false;
            if (impersonationIdentity != null)
            {
                currentPrincipal = Thread.CurrentPrincipal;
                flag = true;
                if (this._impersonate)
                {
                    Thread.CurrentPrincipal = new WindowsPrincipal(impersonationIdentity);
                    context = impersonationIdentity.Impersonate();
                }
                else
                {
                    Thread.CurrentPrincipal = new GenericPrincipal(impersonationIdentity, null);
                }
            }
            try
            {
                try
                {
                    IMessage message;
                    processing = this._nextSink.ProcessMessage(sinkStack, null, requestHeaders, requestStream, out message, out headers2, out stream2);
                }
                finally
                {
                    if (flag)
                    {
                        Thread.CurrentPrincipal = currentPrincipal;
                    }
                    if (this._impersonate)
                    {
                        context.Undo();
                    }
                }
            }
            catch
            {
                throw;
            }
            switch (processing)
            {
                case ServerProcessing.Complete:
                    sinkStack.Pop(this);
                    handler.SendResponse(headers2, stream2);
                    break;

                case ServerProcessing.OneWay:
                    handler.SendResponse(headers2, stream2);
                    break;

                case ServerProcessing.Async:
                    sinkStack.StoreAndDispatch(this, handler);
                    break;
            }
            if (processing != ServerProcessing.Async)
            {
                if (handler.CanServiceAnotherRequest())
                {
                    handler.BeginReadMessage();
                }
                else
                {
                    handler.Close();
                }
            }
        }
        private void ProcessRequestInternal(Stream requestStream, GiopServerConnection serverCon) {
#if DEBUG
            OutputHelper.LogStream(requestStream);
#endif
            requestStream.Seek(0, SeekOrigin.Begin); // assure stream is read from beginning in formatter
            // the out params returned form later sinks
            IMessage responseMsg;
            ITransportHeaders responseHeaders;
            Stream responseStream;
            
            // create the sink stack for async processing of message
            ServerChannelSinkStack sinkStack = new ServerChannelSinkStack();
            sinkStack.Push(this, serverCon);
            // empty transport headers for this protocol
            ITransportHeaders requestHeaders = new TransportHeaders();
            requestHeaders[GiopServerConnection.SERVER_TR_HEADER_KEY] = serverCon;
            requestHeaders[CommonTransportKeys.IPAddress] = serverCon.TransportHandler.GetPeerAddress();
            
            // next sink will process the request-message
            ServerProcessing result = 
                NextChannelSink.ProcessMessage(sinkStack, null, /* no RequestMessage in transport handler */
                                               requestHeaders, requestStream, 
                                               out responseMsg, out responseHeaders,
                                               out responseStream);
            switch (result) {
                case ServerProcessing.Complete :
                    try { 
                        sinkStack.Pop(this); 
                    } catch (Exception) { }                    
#if DEBUG
                    Debug.WriteLine("Send response sync");
                    OutputHelper.LogStream(responseStream);
#endif                    
                    serverCon.TransportHandler.SendResponse(responseStream);
                    break;                    
                case ServerProcessing.Async : 
                    sinkStack.StoreAndDispatch(this, serverCon); // this sink wants to handle response
                    // no reply, async
                    break;
                case ServerProcessing.OneWay :
                    try { 
                        sinkStack.Pop(this); 
                    } catch (Exception) { }
                    // no message to send
                    break;
                default:
                    // should not arrive here
                    Trace.WriteLine("internal problem, invalid processing state: " + result);
                    throw new omg.org.CORBA.INTERNAL(568, omg.org.CORBA.CompletionStatus.Completed_MayBe);
            }            
        }