Skip to content
Merged
Show file tree
Hide file tree
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 @@ -1721,6 +1721,34 @@ public async Task WebSocketOptionsAreApplied()
}
}

[ConditionalFact]
[WebSocketsSupportedCondition]
public async Task CookiesFromNegotiateAreAppliedToWebSockets()
{
await using (var server = await StartServer<Startup>())
{
var hubConnection = new HubConnectionBuilder()
.WithLoggerFactory(LoggerFactory)
.WithUrl(server.Url + "/default", HttpTransportType.WebSockets)
.Build();
try
{
await hubConnection.StartAsync().OrTimeout();
var cookieValue = await hubConnection.InvokeAsync<string>(nameof(TestHub.GetCookieValue), "fromNegotiate").OrTimeout();
Assert.Equal("a value", cookieValue);
}
catch (Exception ex)
{
LoggerFactory.CreateLogger<HubConnectionTests>().LogError(ex, "{ExceptionType} from test", ex.GetType().FullName);
throw;
}
finally
{
await hubConnection.DisposeAsync().OrTimeout();
}
}
}

[Fact]
public async Task CheckHttpConnectionFeatures()
{
Expand Down
12 changes: 12 additions & 0 deletions src/SignalR/clients/csharp/Client/test/FunctionalTests/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ public void Configure(IApplicationBuilder app)
app.UseAuthentication();
app.UseAuthorization();

app.Use(next =>
{
return context =>
{
if (context.Request.Path.Value.EndsWith("/negotiate"))
{
context.Response.Cookies.Append("fromNegotiate", "a value");
}
return next(context);
};
});

app.UseEndpoints(endpoints =>
{
endpoints.MapHub<TestHub>("/default");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ private static class Log
private static readonly Action<ILogger, Exception> _serverSentEventsNotSupportedByBrowser =
LoggerMessage.Define(LogLevel.Debug, new EventId(19, "ServerSentEventsNotSupportedByBrowser"), "Skipping ServerSentEvents because they are not supported by the browser.");

private static readonly Action<ILogger, Exception> _cookiesNotSupported =
LoggerMessage.Define(LogLevel.Trace, new EventId(20, "CookiesNotSupported"), "Cookies are not supported on this platform.");

public static void Starting(ILogger logger)
{
_starting(logger, null);
Expand Down Expand Up @@ -175,6 +178,11 @@ public static void ServerSentEventsNotSupportedByBrowser(ILogger logger)
{
_serverSentEventsNotSupportedByBrowser(logger, null);
}

public static void CookiesNotSupported(ILogger logger)
{
_cookiesNotSupported(logger, null);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ public HttpConnection(HttpConnectionOptions httpConnectionOptions, ILoggerFactor

_isRunningInBrowser = Utils.IsRunningInBrowser();


if (httpConnectionOptions.Transports == HttpTransportType.ServerSentEvents && _isRunningInBrowser)
{
throw new ArgumentException("ServerSentEvents can not be the only transport specified when running in the browser.", nameof(httpConnectionOptions));
Expand Down Expand Up @@ -534,13 +533,21 @@ private HttpClient CreateHttpClient()
httpClientHandler.Proxy = _httpConnectionOptions.Proxy;
}

// Only access HttpClientHandler.ClientCertificates and HttpClientHandler.CookieContainer
// if the user has configured those options
// Some variants of Mono do not support client certs or cookies and will throw NotImplementedException
if (_httpConnectionOptions.Cookies.Count > 0)
try
{
// On supported platforms, we need to pass the cookie container to the http client
// so that we can capture any cookies from the negotiate response and give them to WebSockets.
httpClientHandler.CookieContainer = _httpConnectionOptions.Cookies;
}
// Some variants of Mono do not support client certs or cookies and will throw NotImplementedException or NotSupportedException
// Also WASM doesn't support some settings in the browser
catch (Exception ex) when (ex is NotSupportedException || ex is NotImplementedException)
{
Log.CookiesNotSupported(_logger);
}

// Only access HttpClientHandler.ClientCertificates
// if the user has configured those options
// https://github.com/aspnet/SignalR/issues/2232
var clientCertificates = _httpConnectionOptions.ClientCertificates;
if (clientCertificates?.Count > 0)
Expand Down