async Task CreateTransportAsync()

in src/Listener/ConnectionListener.cs [841:912]


            async Task<int> CreateTransportAsync(HttpListenerContext context, IHandler handler)
            {
                X509Certificate2 clientCertificate = null;

                if (this.Listener.sslSettings != null && this.Listener.sslSettings.ClientCertificateRequired)
                {
                    clientCertificate = await context.Request.GetClientCertificateAsync().ConfigureAwait(false);
                    if (clientCertificate == null)
                    {
                        return 40300;
                    }

                    if (this.Listener.sslSettings.RemoteCertificateValidationCallback != null)
                    {
                        SslPolicyErrors sslError = SslPolicyErrors.None;
                        X509Chain chain = new X509Chain();
                        chain.ChainPolicy.RevocationMode = this.Listener.sslSettings.CheckCertificateRevocation ?
                            X509RevocationMode.Online : X509RevocationMode.NoCheck;
                        chain.Build(clientCertificate);
                        if (chain.ChainStatus.Length > 0)
                        {
                            sslError = SslPolicyErrors.RemoteCertificateChainErrors;
                        }

                        bool success = this.Listener.sslSettings.RemoteCertificateValidationCallback(
                            this, clientCertificate, chain, sslError);
                        if (!success)
                        {
                            return 40301;
                        }
                    }
                    else if (context.Request.ClientCertificateError != 0)
                    {
                        return 40302;
                    }
                }

                IPrincipal principal = context.User;
                if (principal == null && clientCertificate != null)
                {
                    principal = new GenericPrincipal(new X509Identity(clientCertificate), new string[0]);
                }

                string subProtocol = null;
                string[] subProtocols = context.Request.Headers.GetValues("Sec-WebSocket-Protocol");
                for (int i = 0; i < subProtocols.Length; i++)
                {
                    if (subProtocols[i].Equals(WebSocketTransport.WebSocketSubProtocol) ||
                        subProtocols[i].Equals("AMQPWSB10")     // defined by the previous draft
                       )
                    {
                        subProtocol = subProtocols[i];
                        break;
                    }
                }

                if (subProtocol == null)
                {
                    return 40003;
                }

                var wsContext = await context.AcceptWebSocketAsync(subProtocol).ConfigureAwait(false);
                if (handler != null && handler.CanHandle(EventId.WebSocketAccept))
                {
                    handler.Handle(Event.Create(EventId.WebSocketAccept, null, context: wsContext));
                }

                var wsTransport = new ListenerWebSocketTransport(wsContext.WebSocket, principal);
                await this.Listener.HandleTransportAsync(wsTransport, handler, wsContext.WebSocket).ConfigureAwait(false);

                return 0;
            }