Task OnAcceptClientCommandAsync(ListenerCommand.AcceptCommand acceptCommand)
        {
            string id = acceptCommand.Id;
            var    trackingContext = TrackingContext.Create(id, this.Address);

#if DEBUG
            // TestHook: In DEBUG builds if the trackingId is Guid.Empty don't accept the rendezvous
            if (trackingContext.TrackingId.StartsWith(Guid.Empty.ToString(), StringComparison.Ordinal))
            {
                return(TaskEx.CompletedTask);
            }
#endif

            RelayEventSource.Log.RelayListenerRendezvousStart(this.ToString(), trackingContext.TrackingId, acceptCommand.Address);

            DataConnection clientConnection;
            lock (this.ThisLock)
            {
                if (this.closeCalled)
                {
                    RelayEventSource.Log.RelayListenerRendezvousFailed(this.ToString(), trackingContext.TrackingId, SR.ObjectClosedOrAborted);
                    return(TaskEx.CompletedTask);
                }
                else if (this.clientConnections.ContainsKey(id))
                {
                    RelayEventSource.Log.RelayListenerRendezvousFailed(this.ToString(), trackingContext.TrackingId, SR.DuplicateConnectionId);
                    return(TaskEx.CompletedTask);
                }

                clientConnection = new DataConnection(this, acceptCommand, trackingContext);
                this.clientConnections.Add(id, clientConnection);
            }

            return(clientConnection.AcceptConnectionAsync());
        }
        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 DataConnection(HybridConnectionListener listener, ListenerCommand.AcceptCommand acceptCommand, TrackingContext trackingContext)
 {
     this.listener          = listener;
     this.bufferSize        = listener.ConnectionBufferSize;
     this.Address           = listener.Address;
     this.tokenProvider     = listener.TokenProvider;
     this.Id                = acceptCommand.Id;
     this.rendezvousAddress = new Uri(acceptCommand.Address);
     this.TrackingContext   = trackingContext;
 }
Example #4
0
 internal RelayedHttpListenerRequest(Uri requestUri, ListenerCommand.AcceptCommand acceptCommand)
 {
     this.AcceptCommand = acceptCommand;
     this.Url           = requestUri;
     this.Headers       = new WebHeaderCollection();
     foreach (var headerPair in acceptCommand.ConnectHeaders)
     {
         this.Headers[headerPair.Key] = headerPair.Value;
     }
 }
Example #5
0
        internal RelayedHttpListenerContext(HybridConnectionListener listener, ListenerCommand.AcceptCommand acceptCommand)
        {
            this.Listener             = listener;
            this.wssRendezvousAddress = new Uri(acceptCommand.Address);
            Uri requestUri = this.GenerateRequestUri();

            this.TrackingContext = TrackingContext.Create(acceptCommand.Id, requestUri);
            this.Request         = new RelayedHttpListenerRequest(requestUri, acceptCommand);
            this.Response        = new RelayedHttpListenerResponse(this);

            this.FlowSubProtocol();
        }
        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();
            }
        }