示例#1
0
        async Task CompleteAcceptAsync(RelayedHttpListenerContext listenerContext, Uri rendezvousUri, bool shouldAccept)
        {
            try
            {
                if (shouldAccept)
                {
                    var webSocketStream = await listenerContext.AcceptAsync(rendezvousUri).ConfigureAwait(false);

                    lock (this.ThisLock)
                    {
                        if (this.closeCalled)
                        {
                            RelayEventSource.Log.RelayListenerRendezvousFailed(this, listenerContext.TrackingContext.TrackingId, SR.ObjectClosedOrAborted);
                            return;
                        }

                        this.connectionInputQueue.EnqueueAndDispatch(webSocketStream, null, canDispatchOnThisThread: false);
                    }
                }
                else
                {
                    RelayEventSource.Log.RelayListenerRendezvousRejected(
                        listenerContext.TrackingContext, listenerContext.Response.StatusCode, listenerContext.Response.StatusDescription);
                    await listenerContext.RejectAsync(rendezvousUri).ConfigureAwait(false);
                }
            }
            catch (Exception exception) when(!Fx.IsFatal(exception))
            {
                RelayEventSource.Log.RelayListenerRendezvousFailed(this, listenerContext.TrackingContext.TrackingId, exception);
            }
            finally
            {
                RelayEventSource.Log.RelayListenerRendezvousStop();
            }
        }
 public ResponseStream(HybridHttpConnection connection, RelayedHttpListenerContext context)
 {
     this.connection   = connection;
     this.context      = context;
     this.WriteTimeout = TimeoutHelper.ToMilliseconds(this.connection.OperationTimeout);
     this.asyncLock    = new AsyncLock();
 }
 internal RelayedHttpListenerResponse(RelayedHttpListenerContext context)
 {
     this.Context      = context;
     this.statusCode   = HttpStatusCode.Continue;
     this.Headers      = new ResponseWebHeaderCollection(this);
     this.OutputStream = Stream.Null;
 }
 public void RelayListenerRendezvousStart(RelayedHttpListenerContext listenerContext, string rendezvousAddress)
 {
     if (this.IsEnabled())
     {
         this.RelayListenerRendezvousStart(
             CreateSourceString(listenerContext.Listener), listenerContext.TrackingContext.TrackingId, rendezvousAddress);
     }
 }
 public void RelayListenerRendezvousFailed(RelayedHttpListenerContext listenerContext, string exception)
 {
     if (this.IsEnabled())
     {
         this.RelayListenerRendezvousFailed(
             CreateSourceString(listenerContext.Listener), listenerContext.TrackingContext.TrackingId, exception);
     }
 }
        async Task OnAcceptClientCommand(ListenerCommand.AcceptCommand acceptCommand)
        {
            var listenerContext = new RelayedHttpListenerContext(this, acceptCommand);

            RelayEventSource.Log.RelayListenerRendezvousStart(listenerContext, acceptCommand.Address);
            try
            {
                bool shouldAccept       = true;
                var  acceptHandlerValue = this.AcceptHandler;
                if (acceptHandlerValue != null)
                {
                    // Invoke and await the user's AcceptHandler method
                    try
                    {
                        shouldAccept = await acceptHandlerValue(listenerContext).ConfigureAwait(false);
                    }
                    catch (Exception userException) when(!Fx.IsFatal(userException))
                    {
                        string description = SR.GetString(SR.AcceptHandlerException, listenerContext.TrackingContext.TrackingId);

                        RelayEventSource.Log.RelayListenerRendezvousFailed(listenerContext, description + " " + userException);
                        listenerContext.Response.StatusCode        = HttpStatusCode.BadGateway;
                        listenerContext.Response.StatusDescription = description;
                        shouldAccept = false;
                    }
                }

                if (shouldAccept)
                {
                    var webSocketStream = await listenerContext.AcceptAsync().ConfigureAwait(false);

                    lock (this.ThisLock)
                    {
                        if (this.closeCalled)
                        {
                            RelayEventSource.Log.RelayListenerRendezvousFailed(listenerContext, SR.ObjectClosedOrAborted);
                            return;
                        }

                        this.connectionInputQueue.EnqueueAndDispatch(webSocketStream, null, canDispatchOnThisThread: false);
                    }
                }
                else
                {
                    RelayEventSource.Log.RelayListenerRendezvousRejected(listenerContext);
                    await listenerContext.RejectAsync().ConfigureAwait(false);
                }
            }
            catch (Exception exception) when(!Fx.IsFatal(exception))
            {
                RelayEventSource.Log.RelayListenerRendezvousFailed(listenerContext, exception.ToString());
            }
            finally
            {
                RelayEventSource.Log.RelayListenerRendezvousStop();
            }
        }
 public void RelayListenerRendezvousRejected(RelayedHttpListenerContext listenerContext)
 {
     if (this.IsEnabled())
     {
         var response = listenerContext.Response;
         this.RelayListenerRendezvousRejected(
             listenerContext.TrackingContext.TrackingId, (int)response.StatusCode, response.StatusDescription);
     }
 }
        void InvokeRequestHandler(RequestCommandAndStream requestAndStream)
        {
            ListenerCommand.RequestCommand requestCommand = requestAndStream.RequestCommand;
            Uri requestUri      = new Uri(this.listener.Address, requestCommand.RequestTarget);
            var listenerContext = new RelayedHttpListenerContext(
                this.listener,
                requestUri,
                requestCommand.Id,
                requestCommand.Method,
                requestCommand.RequestHeaders);

            listenerContext.Request.SetRemoteAddress(requestCommand.RemoteEndpoint);
            listenerContext.Response.StatusCode   = HttpStatusCode.OK;
            listenerContext.Response.OutputStream = new ResponseStream(this, listenerContext);

            RelayEventSource.Log.HybridHttpRequestReceived(listenerContext.TrackingContext, requestCommand.Method);

            Stream requestStream = requestAndStream.Stream;

            if (requestStream != null)
            {
                listenerContext.Request.HasEntityBody = true;
                listenerContext.Request.InputStream   = requestStream;
            }

            var requestHandler = this.listener.RequestHandler;

            if (requestHandler != null)
            {
                try
                {
                    RelayEventSource.Log.HybridHttpInvokingUserRequestHandler();
                    requestHandler(listenerContext);
                }
                catch (Exception userException) when(!Fx.IsFatal(userException))
                {
                    RelayEventSource.Log.HandledExceptionAsWarning(this, userException);
                    listenerContext.Response.StatusCode        = HttpStatusCode.InternalServerError;
                    listenerContext.Response.StatusDescription = this.TrackingContext.EnsureTrackableMessage(SR.RequestHandlerException);
                    listenerContext.Response.CloseAsync().Fork(this);
                    return;
                }
            }
            else
            {
                RelayEventSource.Log.HybridHttpConnectionMissingRequestHandler();
                listenerContext.Response.StatusCode        = HttpStatusCode.NotImplemented;
                listenerContext.Response.StatusDescription = this.TrackingContext.EnsureTrackableMessage(SR.RequestHandlerMissing);
                listenerContext.Response.CloseAsync().Fork(this);
            }
        }
        static ListenerCommand.ResponseCommand CreateResponseCommand(RelayedHttpListenerContext listenerContext)
        {
            var responseCommand = new ListenerCommand.ResponseCommand();

            responseCommand.StatusCode        = (int)listenerContext.Response.StatusCode;
            responseCommand.StatusDescription = listenerContext.Response.StatusDescription;
            responseCommand.RequestId         = listenerContext.TrackingContext.TrackingId;
            foreach (string headerName in listenerContext.Response.Headers.AllKeys)
            {
                responseCommand.ResponseHeaders[headerName] = listenerContext.Response.Headers[headerName];
            }

            return(responseCommand);
        }
        void InvokeRequestHandler(RequestCommandAndStream requestAndStream)
        {
            ListenerCommand.RequestCommand requestCommand = requestAndStream.RequestCommand;
            Uri requestUri      = new Uri(this.listener.Address, requestCommand.RequestTarget);
            var listenerContext = new RelayedHttpListenerContext(
                this.listener,
                requestUri,
                requestCommand.Id,
                requestCommand.Method,
                requestCommand.RequestHeaders);

            listenerContext.Request.SetRemoteAddress(requestCommand.RemoteEndpoint);
            listenerContext.Response.StatusCode   = HttpStatusCode.OK;
            listenerContext.Response.OutputStream = new ResponseStream(this, listenerContext);

            RelayEventSource.Log.HybridHttpRequestReceived(listenerContext.TrackingContext, requestCommand.Method);

            Stream requestStream = requestAndStream.Stream;

            if (requestStream != null)
            {
                listenerContext.Request.HasEntityBody = true;
                listenerContext.Request.InputStream   = requestStream;
            }

            var requestHandler = this.listener.RequestHandler;

            if (requestHandler != null)
            {
                try
                {
                    RelayEventSource.Log.HybridHttpInvokingUserRequestHandler();
                    requestHandler(listenerContext);
                }
                catch (Exception userException) when(!Fx.IsFatal(userException))
                {
                    RelayEventSource.Log.Warning(
                        listenerContext,
                        $"The Relayed Listener's custom RequestHandler threw an exception. {listenerContext.TrackingContext}, Exception: {userException}");
                    return;
                }
            }
            else
            {
                RelayEventSource.Log.HandledExceptionAsWarning(this, new InvalidOperationException("RequestHandler is not set."));
            }
        }
        async Task OnAcceptCommandAsync(ListenerCommand.AcceptCommand acceptCommand)
        {
            Uri rendezvousUri = new Uri(acceptCommand.Address);
            Uri requestUri    = this.GenerateAcceptRequestUri(rendezvousUri);

            var listenerContext = new RelayedHttpListenerContext(
                this, requestUri, acceptCommand.Id, "GET", acceptCommand.ConnectHeaders);

            listenerContext.Request.SetRemoteAddress(acceptCommand.RemoteEndpoint);

            RelayEventSource.Log.RelayListenerRendezvousStart(listenerContext.Listener, listenerContext.TrackingContext.TrackingId, acceptCommand.Address);
            try
            {
                var  acceptHandler = this.AcceptHandler;
                bool shouldAccept  = acceptHandler == null;
                if (acceptHandler != null)
                {
                    // Invoke and await the user's AcceptHandler method
                    try
                    {
                        shouldAccept = await acceptHandler(listenerContext).ConfigureAwait(false);
                    }
                    catch (Exception userException) when(!Fx.IsFatal(userException))
                    {
                        string description = SR.GetString(SR.AcceptHandlerException, listenerContext.TrackingContext.TrackingId);

                        RelayEventSource.Log.RelayListenerRendezvousFailed(this, listenerContext.TrackingContext.TrackingId, description + " " + userException);
                        listenerContext.Response.StatusCode        = HttpStatusCode.BadGateway;
                        listenerContext.Response.StatusDescription = description;
                    }
                }

                // Don't block the pump waiting for the rendezvous
                this.CompleteAcceptAsync(listenerContext, rendezvousUri, shouldAccept).Fork(this);
            }
            catch (Exception exception) when(!Fx.IsFatal(exception))
            {
                RelayEventSource.Log.RelayListenerRendezvousFailed(this, listenerContext.TrackingContext.TrackingId, exception);
                RelayEventSource.Log.RelayListenerRendezvousStop();
            }
        }
示例#12
0
 internal RelayedHttpListenerResponse(RelayedHttpListenerContext context)
 {
     this.Context    = context;
     this.statusCode = HttpStatusCode.Continue;
     this.Headers    = new WebHeaderCollection();
 }