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;
}