Skip to content

Commit 1fcffb8

Browse files
committed
comments 1
1 parent 48e07f8 commit 1fcffb8

File tree

3 files changed

+41
-20
lines changed

3 files changed

+41
-20
lines changed

src/Servers/Kestrel/Core/src/ListenOptionsHttpsExtensions.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,15 @@ public static ListenOptions UseHttps(this ListenOptions listenOptions, TlsHandsh
270270
listenOptions.IsTls = true;
271271
listenOptions.HttpsCallbackOptions = callbackOptions;
272272

273+
if (listenOptions.HttpsOptions?.TlsClientHelloBytesCallback is not null)
274+
{
275+
listenOptions.Use(next =>
276+
{
277+
var middleware = new TlsListenerMiddleware(next, listenOptions.HttpsOptions.TlsClientHelloBytesCallback);
278+
return middleware.OnTlsClientHelloAsync;
279+
});
280+
}
281+
273282
listenOptions.Use(next =>
274283
{
275284
// Set the list of protocols from listen options.

src/Servers/Kestrel/Core/src/Middleware/TlsListenerMiddleware.cs

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,35 +30,46 @@ internal async Task OnTlsClientHelloAsync(ConnectionContext connection)
3030
var result = await input.ReadAsync();
3131
var buffer = result.Buffer;
3232

33-
// If the buffer length is less than 6 bytes (handshake + version + length + client-hello byte)
34-
// and no more data is coming, we can't block in a loop here because we will not get more data
35-
if (buffer.Length < 6 && result.IsCompleted)
33+
try
3634
{
37-
break;
35+
// If the buffer length is less than 6 bytes (handshake + version + length + client-hello byte)
36+
// and no more data is coming, we can't block in a loop here because we will not get more data
37+
if (buffer.Length < 6 && result.IsCompleted)
38+
{
39+
break;
40+
}
41+
42+
var parseState = TryParseClientHello(buffer, out var clientHelloBytes);
43+
44+
if (parseState == ClientHelloParseState.NotEnoughData)
45+
{
46+
continue;
47+
}
48+
49+
if (parseState == ClientHelloParseState.ValidTlsClientHello)
50+
{
51+
_tlsClientHelloBytesCallback(connection, clientHelloBytes);
52+
}
53+
54+
Debug.Assert(parseState is ClientHelloParseState.ValidTlsClientHello or ClientHelloParseState.NotTlsClientHello);
55+
break; // We can continue with the middleware pipeline
3856
}
39-
40-
var parseState = TryParseClientHello(buffer, out var clientHelloBytes);
41-
42-
// no data is consumed, it will be processed by the follow-up middlewares
43-
input.AdvanceTo(buffer.Start);
44-
45-
if (parseState == ClientHelloParseState.NotEnoughData)
57+
finally
4658
{
47-
continue;
59+
input.AdvanceTo(buffer.Start);
4860
}
49-
50-
if (parseState == ClientHelloParseState.ValidTlsClientHello)
51-
{
52-
_tlsClientHelloBytesCallback(connection, clientHelloBytes);
53-
}
54-
55-
Debug.Assert(parseState is ClientHelloParseState.ValidTlsClientHello or ClientHelloParseState.NotTlsClientHello);
56-
break; // We can continue with the middleware pipeline
5761
}
5862

5963
await _next(connection);
6064
}
6165

66+
/// <summary>
67+
/// RFCs
68+
/// ----
69+
/// TLS 1.1: https://datatracker.ietf.org/doc/html/rfc4346#section-6.2
70+
/// TLS 1.2: https://datatracker.ietf.org/doc/html/rfc5246#section-6.2
71+
/// TLS 1.3: https://datatracker.ietf.org/doc/html/rfc8446#section-5.1
72+
/// </summary>
6273
private static ClientHelloParseState TryParseClientHello(ReadOnlySequence<byte> buffer, out ReadOnlySequence<byte> clientHelloBytes)
6374
{
6475
clientHelloBytes = default;

src/Servers/Kestrel/test/InMemory.FunctionalTests/TlsListenerMiddlewareTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ await sslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions
5757

5858
var request = Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nHost:\r\n\r\n");
5959
await sslStream.WriteAsync(request, 0, request.Length);
60+
await sslStream.ReadAsync(new Memory<byte>(new byte[1024]));
6061
}
6162
}
6263
}

0 commit comments

Comments
 (0)