Skip to content

Commit c2694e4

Browse files
authored
HTTP/3: Make logging IDs consistent with other protocols (#34745)
1 parent 39912f8 commit c2694e4

File tree

8 files changed

+70
-25
lines changed

8 files changed

+70
-25
lines changed

src/Servers/Kestrel/Core/src/Internal/Http3/Http3Connection.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ public async Task ProcessRequestsAsync<TContext>(IHttpApplication<TContext> appl
287287
else
288288
{
289289
stream = (Http3Stream<TContext>)s!;
290-
stream.InitializeWithExistingContext(streamContext.Transport, streamContext.ConnectionId);
290+
stream.InitializeWithExistingContext(streamContext.Transport);
291291
}
292292

293293
_streamLifetimeHandler.OnStreamCreated(stream);
@@ -377,9 +377,9 @@ public async Task ProcessRequestsAsync<TContext>(IHttpApplication<TContext> appl
377377
private Http3StreamContext CreateHttpStreamContext(ConnectionContext streamContext)
378378
{
379379
var httpConnectionContext = new Http3StreamContext(
380-
streamContext.ConnectionId,
381-
protocols: default,
382-
connectionContext: null!, // TODO connection context is null here. Should we set it to anything?
380+
_multiplexedContext.ConnectionId,
381+
HttpProtocols.Http3,
382+
_multiplexedContext,
383383
_context.ServiceContext,
384384
streamContext.Features,
385385
_context.MemoryPool,
@@ -459,9 +459,9 @@ private async ValueTask<Http3ControlStream> CreateNewUnidirectionalStreamAsync<T
459459
features.Set<IStreamDirectionFeature>(new DefaultStreamDirectionFeature(canRead: false, canWrite: true));
460460
var streamContext = await _multiplexedContext.ConnectAsync(features);
461461
var httpConnectionContext = new Http3StreamContext(
462-
connectionId: streamContext.ConnectionId,
462+
_multiplexedContext.ConnectionId,
463463
HttpProtocols.Http3,
464-
connectionContext: null!, // TODO connection context is null here. Should we set it to anything?
464+
_multiplexedContext,
465465
_context.ServiceContext,
466466
streamContext.Features,
467467
_context.MemoryPool,

src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,8 @@ public void Initialize(Http3StreamContext context)
128128
_frameWriter.Reset(context.Transport.Output, context.ConnectionId);
129129
}
130130

131-
public void InitializeWithExistingContext(IDuplexPipe transport, string connectionId)
131+
public void InitializeWithExistingContext(IDuplexPipe transport)
132132
{
133-
_context.ConnectionId = connectionId;
134133
_context.Transport = transport;
135134
Initialize(_context);
136135
}
@@ -677,14 +676,12 @@ private void ApplicationAbort(ConnectionAbortedException abortReason, Http3Error
677676

678677
protected override string CreateRequestId()
679678
{
680-
// TODO include stream id.
681-
return ConnectionId;
679+
return _context.StreamContext.ConnectionId;
682680
}
683681

684682
protected override MessageBody CreateMessageBody()
685683
=> Http3MessageBody.For(this);
686684

687-
688685
protected override bool TryParseRequest(ReadResult result, out bool endConnection)
689686
{
690687
endConnection = !TryValidatePseudoHeaders();

src/Servers/Kestrel/Core/src/Internal/Http3StreamContext.cs renamed to src/Servers/Kestrel/Core/src/Internal/Http3/Http3StreamContext.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,15 @@
66
using System.Net;
77
using Microsoft.AspNetCore.Connections;
88
using Microsoft.AspNetCore.Http.Features;
9-
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3;
109

11-
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
10+
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3
1211
{
1312
internal class Http3StreamContext : HttpConnectionContext
1413
{
1514
public Http3StreamContext(
1615
string connectionId,
1716
HttpProtocols protocols,
18-
ConnectionContext connectionContext,
17+
BaseConnectionContext connectionContext,
1918
ServiceContext serviceContext,
2019
IFeatureCollection connectionFeatures,
2120
MemoryPool<byte> memoryPool,

src/Servers/Kestrel/Core/src/Internal/HttpConnectionContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ internal class HttpConnectionContext : BaseHttpConnectionContext
1414
public HttpConnectionContext(
1515
string connectionId,
1616
HttpProtocols protocols,
17-
ConnectionContext connectionContext,
17+
BaseConnectionContext connectionContext,
1818
ServiceContext serviceContext,
1919
IFeatureCollection connectionFeatures,
2020
MemoryPool<byte> memoryPool,

src/Servers/Kestrel/Transport.Quic/src/Internal/QuicStreamContext.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using Microsoft.AspNetCore.Connections;
1313
using Microsoft.AspNetCore.Connections.Features;
1414
using Microsoft.AspNetCore.Http.Features;
15+
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
1516
using Microsoft.Extensions.Logging;
1617

1718
namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Quic.Internal
@@ -129,7 +130,7 @@ public void Initialize(QuicStream stream)
129130

130131
public override string ConnectionId
131132
{
132-
get => _connectionId ??= $"{_connection.ConnectionId}:{StreamId}";
133+
get => _connectionId ??= StringUtilities.ConcatAsHexSuffix(_connection.ConnectionId, ':', (uint)StreamId);
133134
set => _connectionId = value;
134135
}
135136

src/Servers/Kestrel/Transport.Quic/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Quic.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<Compile Include="$(KestrelSharedSourceRoot)\CompletionPipeWriter.cs" Link="Internal\CompletionPipeWriter.cs" />
2020
<Compile Include="$(KestrelSharedSourceRoot)\CorrelationIdGenerator.cs" Link="Internal\CorrelationIdGenerator.cs" />
2121
<Compile Include="$(SharedSourceRoot)ServerInfrastructure\DuplexPipe.cs" Link="Internal\DuplexPipe.cs" />
22+
<Compile Include="$(SharedSourceRoot)ServerInfrastructure\StringUtilities.cs" Link="Internal\StringUtilities.cs" />
2223
<Compile Include="$(KestrelSharedSourceRoot)\TransportConnection.cs" Link="Internal\TransportConnection.cs" />
2324
<Compile Include="$(KestrelSharedSourceRoot)\TransportConnection.Generated.cs" Link="Internal\TransportConnection.Generated.cs" />
2425
<Compile Include="$(KestrelSharedSourceRoot)\TransportConnection.FeatureCollection.cs" Link="Internal\TransportConnection.FeatureCollection.cs" />

src/Servers/Kestrel/shared/test/TestContextFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ public static Http2StreamContext CreateHttp2StreamContext(
165165

166166
public static Http3StreamContext CreateHttp3StreamContext(
167167
string connectionId = null,
168-
ConnectionContext connectionContext = null,
168+
BaseConnectionContext connectionContext = null,
169169
ServiceContext serviceContext = null,
170170
IFeatureCollection connectionFeatures = null,
171171
MemoryPool<byte> memoryPool = null,

src/Servers/Kestrel/test/Interop.FunctionalTests/Http3/Http3RequestTests.cs

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,8 @@ public async Task POST_ClientCancellationUpload_RequestAbortRaised(HttpProtocols
159159
readAsyncTask.SetResult(body.ReadAsync(buffer).AsTask());
160160
}, protocol: protocol);
161161

162-
var httpClientHandler = new HttpClientHandler();
163-
httpClientHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
164-
165162
using (var host = builder.Build())
166-
using (var client = new HttpClient(httpClientHandler))
163+
using (var client = CreateClient())
167164
{
168165
await host.StartAsync().DefaultTimeout();
169166

@@ -231,11 +228,8 @@ public async Task GET_ServerAbort_ClientReceivesAbort(HttpProtocols protocol)
231228
writeAsyncTask.SetResult(context.Response.Body.WriteAsync(TestData).AsTask());
232229
}, protocol: protocol);
233230

234-
var httpClientHandler = new HttpClientHandler();
235-
httpClientHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
236-
237231
using (var host = builder.Build())
238-
using (var client = new HttpClient(httpClientHandler))
232+
using (var client = CreateClient())
239233
{
240234
await host.StartAsync().DefaultTimeout();
241235

@@ -338,6 +332,59 @@ public async Task GET_MultipleRequestsInSequence_ReusedState()
338332
}
339333
}
340334

335+
[ConditionalFact]
336+
[MsQuicSupported]
337+
public async Task GET_MultipleRequests_ConnectionAndTraceIdsUpdated()
338+
{
339+
// Arrange
340+
string connectionId = null;
341+
string traceId = null;
342+
343+
var builder = CreateHostBuilder(context =>
344+
{
345+
connectionId = context.Connection.Id;
346+
traceId = context.TraceIdentifier;
347+
348+
return Task.CompletedTask;
349+
});
350+
351+
using (var host = builder.Build())
352+
using (var client = CreateClient())
353+
{
354+
await host.StartAsync();
355+
356+
// Act
357+
var request1 = new HttpRequestMessage(HttpMethod.Get, $"https://127.0.0.1:{host.GetPort()}/");
358+
request1.Version = HttpVersion.Version30;
359+
request1.VersionPolicy = HttpVersionPolicy.RequestVersionExact;
360+
361+
var response1 = await client.SendAsync(request1);
362+
response1.EnsureSuccessStatusCode();
363+
364+
var connectionId1 = connectionId;
365+
var traceId1 = traceId;
366+
367+
var request2 = new HttpRequestMessage(HttpMethod.Get, $"https://127.0.0.1:{host.GetPort()}/");
368+
request2.Version = HttpVersion.Version30;
369+
request2.VersionPolicy = HttpVersionPolicy.RequestVersionExact;
370+
371+
var response2 = await client.SendAsync(request2);
372+
response2.EnsureSuccessStatusCode();
373+
374+
var connectionId2 = connectionId;
375+
var traceId2 = traceId;
376+
377+
// Assert
378+
Assert.True(!string.IsNullOrEmpty(connectionId1), "ConnectionId should have a value.");
379+
Assert.Equal(connectionId1, connectionId2); // ConnectionId unchanged
380+
381+
Assert.Equal($"{connectionId1}:00000000", traceId1);
382+
Assert.Equal($"{connectionId2}:00000004", traceId2);
383+
384+
await host.StopAsync();
385+
}
386+
}
387+
341388
[ConditionalFact]
342389
[MsQuicSupported]
343390
public async Task GET_MultipleRequestsInSequence_ReusedRequestHeaderStrings()

0 commit comments

Comments
 (0)