Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2361,47 +2361,80 @@ public async Task CanBlockOnAsyncOperationsWithOneAtATimeSynchronizationContext(
}

[ConditionalFact]
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/50180")]
public async Task LongPollingUsesHttp2ByDefault()
{
await using (var server = await StartServer<Startup>(configureKestrelServerOptions: o =>
var logsSeen = false;
var logsTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

Action<WriteContext> handler = null;
handler = context =>
{
o.ConfigureEndpointDefaults(o2 =>
if (logsSeen)
{
o2.Protocols = Server.Kestrel.Core.HttpProtocols.Http1AndHttp2;
o2.UseHttps();
});
o.ConfigureHttpsDefaults(httpsOptions =>
return;
}

var message = context.Message;
if ((message.Contains("Request starting HTTP/2 POST") && message.Contains("/negotiate?")) ||
(message.Contains("Request starting HTTP/2 POST") && message.Contains("?id=")) ||
(message.Contains("Request finished HTTP/2 GET") && message.Contains("?id=")) ||
(message.Contains("Request finished HTTP/2 DELETE") && message.Contains("?id=")))
{
httpsOptions.ServerCertificate = TestCertificateHelper.GetTestCert();
});
}))
logsSeen = true;
logsTcs.TrySetResult();
}
};

TestSink.MessageLogged += handler;

try
{
var hubConnection = new HubConnectionBuilder()
.WithLoggerFactory(LoggerFactory)
.WithUrl(server.Url + "/default", HttpTransportType.LongPolling, o => o.HttpMessageHandlerFactory = h =>
await using (var server = await StartServer<Startup>(configureKestrelServerOptions: o =>
{
o.ConfigureEndpointDefaults(o2 =>
{
((HttpClientHandler)h).ServerCertificateCustomValidationCallback = (_, _, _, _) => true;
return h;
})
.Build();
try
o2.Protocols = Server.Kestrel.Core.HttpProtocols.Http1AndHttp2;
o2.UseHttps();
});
o.ConfigureHttpsDefaults(httpsOptions =>
{
httpsOptions.ServerCertificate = TestCertificateHelper.GetTestCert();
});
}))
{
await hubConnection.StartAsync().DefaultTimeout();
var httpProtocol = await hubConnection.InvokeAsync<string>(nameof(TestHub.GetHttpProtocol)).DefaultTimeout();
var hubConnection = new HubConnectionBuilder()
.WithLoggerFactory(LoggerFactory)
.WithUrl(server.Url + "/default", HttpTransportType.LongPolling, o => o.HttpMessageHandlerFactory = h =>
{
((HttpClientHandler)h).ServerCertificateCustomValidationCallback = (_, _, _, _) => true;
return h;
})
.Build();
try
{
await hubConnection.StartAsync().DefaultTimeout();
var httpProtocol = await hubConnection.InvokeAsync<string>(nameof(TestHub.GetHttpProtocol)).DefaultTimeout();

Assert.Equal("HTTP/2", httpProtocol);
}
catch (Exception ex)
{
LoggerFactory.CreateLogger<HubConnectionTests>().LogError(ex, "{ExceptionType} from test", ex.GetType().FullName);
throw;
}
finally
{
await hubConnection.DisposeAsync().DefaultTimeout();
Assert.Equal("HTTP/2", httpProtocol);

// Wait for HTTP/2 logs to flush before server disposal
await logsTcs.Task.DefaultTimeout();
}
catch (Exception ex)
{
LoggerFactory.CreateLogger<HubConnectionTests>().LogError(ex, "{ExceptionType} from test", ex.GetType().FullName);
throw;
}
finally
{
await hubConnection.DisposeAsync().DefaultTimeout();
}
}
}
finally
{
TestSink.MessageLogged -= handler;
}

// negotiate is HTTP2
Assert.Contains(TestSink.Writes, context => context.Message.Contains("Request starting HTTP/2 POST") && context.Message.Contains("/negotiate?"));
Expand Down
Loading