Skip to content

Commit debe91c

Browse files
authored
Merge branch 'release/6.0' into merge/release/6.0-rc1-to-release/6.0
2 parents 49eae20 + 057ed19 commit debe91c

File tree

9 files changed

+396
-241
lines changed

9 files changed

+396
-241
lines changed

eng/SourceBuild.props

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,19 @@
7272
</PropertyGroup>
7373
</Target>
7474

75+
<Target Name="GetAspnetcoreCategorizedIntermediateNupkgContents"
76+
BeforeTargets="GetCategorizedIntermediateNupkgContents">
77+
<PropertyGroup>
78+
<InstallersArtifactsDir>$(CurrentRepoSourceBuildArtifactsDir)\installers\$(Configuration)\</InstallersArtifactsDir>
79+
</PropertyGroup>
80+
81+
<ItemGroup>
82+
<!--
83+
Add the internal installers artifacts required by dotnet/installer.
84+
-->
85+
<IntermediateNupkgArtifactFile Include="$(InstallersArtifactsDir)aspnetcore-runtime-internal-*.tar.gz" />
86+
<IntermediateNupkgArtifactFile Include="$(InstallersArtifactsDir)aspnetcore_base_runtime.version" />
87+
</ItemGroup>
88+
</Target>
89+
7590
</Project>

eng/Version.Details.xml

Lines changed: 140 additions & 140 deletions
Large diffs are not rendered by default.

eng/Versions.props

Lines changed: 71 additions & 71 deletions
Large diffs are not rendered by default.

src/Servers/HttpSys/src/RequestProcessing/RequestContext.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ public void Abort()
181181
}
182182
_requestAbortSource.Dispose();
183183
}
184+
else
185+
{
186+
_disconnectToken = new CancellationToken(canceled: true);
187+
}
184188
ForceCancelRequest();
185189
Request.Dispose();
186190
// Only Abort, Response.Dispose() tries a graceful flush

src/Servers/HttpSys/test/FunctionalTests/RequestTests.cs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,101 @@ public async Task Request_EscapedControlCharacters_400()
468468
}
469469
}
470470

471+
[ConditionalFact]
472+
public async Task RequestAborted_AfterAccessingProperty_Notified()
473+
{
474+
var registered = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
475+
var result = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
476+
using var server = Utilities.CreateHttpServerReturnRoot("/", out var address, async httpContext =>
477+
{
478+
var ct = httpContext.RequestAborted;
479+
480+
if (!ct.CanBeCanceled || ct.IsCancellationRequested)
481+
{
482+
result.SetException(new Exception("The CT isn't valid."));
483+
return;
484+
}
485+
486+
ct.Register(() => result.SetResult());
487+
488+
registered.SetResult();
489+
490+
// Don't exit until it fires or else it could be disposed.
491+
await result.Task.DefaultTimeout();
492+
});
493+
494+
// Send a request and then abort.
495+
496+
var uri = new Uri(address);
497+
StringBuilder builder = new StringBuilder();
498+
builder.AppendLine("POST / HTTP/1.1");
499+
builder.AppendLine("Connection: close");
500+
builder.AppendLine("Content-Length: 10");
501+
builder.Append("HOST: ");
502+
builder.AppendLine(uri.Authority);
503+
builder.AppendLine();
504+
505+
byte[] request = Encoding.ASCII.GetBytes(builder.ToString());
506+
507+
using var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
508+
509+
await socket.ConnectAsync(uri.Host, uri.Port);
510+
socket.Send(request);
511+
512+
// Wait for the token to be setup before aborting.
513+
await registered.Task.DefaultTimeout();
514+
515+
socket.Close();
516+
517+
await result.Task.DefaultTimeout();
518+
}
519+
520+
[ConditionalFact]
521+
public async Task RequestAbortedDurringRead_BeforeAccessingProperty_TokenAlreadyCanceled()
522+
{
523+
var requestAborted = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
524+
var result = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
525+
using var server = Utilities.CreateHttpServerReturnRoot("/", out var address, async httpContext =>
526+
{
527+
await requestAborted.Task.DefaultTimeout();
528+
try
529+
{
530+
await httpContext.Request.Body.ReadAsync(new byte[10]).DefaultTimeout();
531+
result.SetException(new Exception("This should have aborted"));
532+
return;
533+
}
534+
catch (IOException)
535+
{
536+
}
537+
538+
result.SetResult(httpContext.RequestAborted.IsCancellationRequested);
539+
});
540+
541+
// Send a request and then abort.
542+
543+
var uri = new Uri(address);
544+
StringBuilder builder = new StringBuilder();
545+
builder.AppendLine("POST / HTTP/1.1");
546+
builder.AppendLine("Connection: close");
547+
builder.AppendLine("Content-Length: 10");
548+
builder.Append("HOST: ");
549+
builder.AppendLine(uri.Authority);
550+
builder.AppendLine();
551+
552+
byte[] request = Encoding.ASCII.GetBytes(builder.ToString());
553+
554+
using var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
555+
556+
await socket.ConnectAsync(uri.Host, uri.Port);
557+
socket.Send(request);
558+
socket.Close();
559+
560+
requestAborted.SetResult();
561+
562+
var wasCancelled = await result.Task;
563+
Assert.True(wasCancelled);
564+
}
565+
471566
private IServer CreateServer(out string root, RequestDelegate app)
472567
{
473568
// TODO: We're just doing this to get a dynamic port. This can be removed later when we add support for hot-adding prefixes.

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,10 @@ public static ListenOptions UseHttps(this ListenOptions listenOptions, ServerOpt
256256
/// <returns>The <see cref="ListenOptions"/>.</returns>
257257
public static ListenOptions UseHttps(this ListenOptions listenOptions, ServerOptionsSelectionCallback serverOptionsSelectionCallback, object state, TimeSpan handshakeTimeout)
258258
{
259+
if (listenOptions.Protocols.HasFlag(HttpProtocols.Http3))
260+
{
261+
throw new NotSupportedException($"{nameof(UseHttps)} with {nameof(ServerOptionsSelectionCallback)} is not supported with HTTP/3.");
262+
}
259263
return listenOptions.UseHttps(new TlsHandshakeCallbackOptions()
260264
{
261265
OnConnection = context => serverOptionsSelectionCallback(context.SslStream, context.ClientHelloInfo, context.State, context.CancellationToken),
@@ -283,6 +287,11 @@ public static ListenOptions UseHttps(this ListenOptions listenOptions, TlsHandsh
283287
throw new ArgumentException($"{nameof(TlsHandshakeCallbackOptions.OnConnection)} must not be null.");
284288
}
285289

290+
if (listenOptions.Protocols.HasFlag(HttpProtocols.Http3))
291+
{
292+
throw new NotSupportedException($"{nameof(UseHttps)} with {nameof(TlsHandshakeCallbackOptions)} is not supported with HTTP/3.");
293+
}
294+
286295
var loggerFactory = listenOptions.KestrelServerOptions?.ApplicationServices.GetRequiredService<ILoggerFactory>() ?? NullLoggerFactory.Instance;
287296

288297
listenOptions.IsTls = true;

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,11 @@ private static bool IsWindowsVersionIncompatibleWithHttp2()
510510

511511
internal static SslServerAuthenticationOptions CreateHttp3Options(HttpsConnectionAdapterOptions httpsOptions)
512512
{
513+
if (httpsOptions.OnAuthenticate != null)
514+
{
515+
throw new NotSupportedException($"The {nameof(HttpsConnectionAdapterOptions.OnAuthenticate)} callback is not supported with HTTP/3.");
516+
}
517+
513518
// TODO Set other relevant values on options
514519
var sslServerAuthenticationOptions = new SslServerAuthenticationOptions
515520
{

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

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -593,44 +593,44 @@ public async Task Http3_NoUseHttps_Throws()
593593
}
594594

595595
[Fact]
596-
public async Task Http3_UseHttp3Callback_NoSslServerOptions()
596+
public void Http3_ServerOptionsSelectionCallback_Throws()
597597
{
598598
var serverOptions = CreateServerOptions();
599599
serverOptions.DefaultCertificate = _x509Certificate2;
600600

601-
IFeatureCollection bindFeatures = null;
602-
var multiplexedConnectionListenerFactory = new MockMultiplexedConnectionListenerFactory();
603-
multiplexedConnectionListenerFactory.OnBindAsync = (ep, features) =>
601+
serverOptions.ListenLocalhost(5001, options =>
604602
{
605-
bindFeatures = features;
606-
};
607-
608-
var testContext = new TestServiceContext(LoggerFactory);
609-
testContext.ServerOptions = serverOptions;
610-
await using (var server = new TestServer(context => Task.CompletedTask,
611-
testContext,
612-
serverOptions =>
613-
{
614-
serverOptions.ListenLocalhost(5001, listenOptions =>
603+
options.Protocols = HttpProtocols.Http3;
604+
var exception = Assert.Throws<NotSupportedException>(() =>
605+
options.UseHttps((SslStream stream, SslClientHelloInfo clientHelloInfo, object state, CancellationToken cancellationToken) =>
615606
{
616-
listenOptions.Protocols = HttpProtocols.Http3;
617-
listenOptions.UseHttps((SslStream stream, SslClientHelloInfo clientHelloInfo, object state, CancellationToken cancellationToken) =>
618-
{
619-
return ValueTask.FromResult((new SslServerAuthenticationOptions()));
620-
}, state: null);
621-
});
622-
},
623-
services =>
624-
{
625-
services.AddSingleton<IMultiplexedConnectionListenerFactory>(multiplexedConnectionListenerFactory);
626-
}))
627-
{
628-
}
607+
return ValueTask.FromResult((new SslServerAuthenticationOptions()));
608+
}, state: null)
609+
);
610+
Assert.Equal("UseHttps with ServerOptionsSelectionCallback is not supported with HTTP/3.", exception.Message);
611+
});
612+
}
629613

630-
Assert.NotNull(bindFeatures);
614+
[Fact]
615+
public void Http3_TlsHandshakeCallbackOptions_Throws()
616+
{
617+
var serverOptions = CreateServerOptions();
618+
serverOptions.DefaultCertificate = _x509Certificate2;
631619

632-
var sslOptions = bindFeatures.Get<SslServerAuthenticationOptions>();
633-
Assert.Null(sslOptions);
620+
serverOptions.ListenLocalhost(5001, options =>
621+
{
622+
options.Protocols = HttpProtocols.Http3;
623+
var exception = Assert.Throws<NotSupportedException>(() =>
624+
options.UseHttps(new TlsHandshakeCallbackOptions()
625+
{
626+
OnConnection = context =>
627+
{
628+
return ValueTask.FromResult(new SslServerAuthenticationOptions());
629+
}
630+
})
631+
);
632+
Assert.Equal("UseHttps with TlsHandshakeCallbackOptions is not supported with HTTP/3.", exception.Message);
633+
});
634634
}
635635

636636
[Fact]

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,33 @@ public async Task ClientCertificate_Allow_NotAvailable_Optional()
227227
await host.StopAsync().DefaultTimeout();
228228
}
229229

230+
[ConditionalFact]
231+
[MsQuicSupported]
232+
public async Task OnAuthentice_Available_Throws()
233+
{
234+
var builder = CreateHostBuilder(async context =>
235+
{
236+
await context.Response.WriteAsync("Hello World");
237+
}, configureKestrel: kestrelOptions =>
238+
{
239+
kestrelOptions.ListenAnyIP(0, listenOptions =>
240+
{
241+
listenOptions.Protocols = HttpProtocols.Http3;
242+
listenOptions.UseHttps(httpsOptions =>
243+
{
244+
httpsOptions.OnAuthenticate = (_, _) => { };
245+
});
246+
});
247+
});
248+
249+
using var host = builder.Build();
250+
using var client = Http3Helpers.CreateClient();
251+
252+
var exception = await Assert.ThrowsAsync<NotSupportedException>(() =>
253+
host.StartAsync().DefaultTimeout());
254+
Assert.Equal("The OnAuthenticate callback is not supported with HTTP/3.", exception.Message);
255+
}
256+
230257
private IHostBuilder CreateHostBuilder(RequestDelegate requestDelegate, HttpProtocols? protocol = null, Action<KestrelServerOptions> configureKestrel = null)
231258
{
232259
return Http3Helpers.CreateHostBuilder(AddTestLogging, requestDelegate, protocol, configureKestrel);

0 commit comments

Comments
 (0)