diff --git a/build/dependencies.props b/build/dependencies.props
index f96f84e714..6f5e1830a5 100644
--- a/build/dependencies.props
+++ b/build/dependencies.props
@@ -9,6 +9,7 @@
2.1.0-preview1-15549
2.1.0-preview1-27579
2.1.0-preview1-27579
+ 2.1.0-preview1-27475
2.1.0-preview1-27579
2.1.0-preview1-27579
2.1.0-preview1-27579
diff --git a/samples/ClientSample/HubSample.cs b/samples/ClientSample/HubSample.cs
index 397cb8f433..ebd805f5b0 100644
--- a/samples/ClientSample/HubSample.cs
+++ b/samples/ClientSample/HubSample.cs
@@ -6,7 +6,6 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR.Client;
-using Microsoft.AspNetCore.Sockets.Client;
using Microsoft.Extensions.CommandLineUtils;
using Microsoft.Extensions.Logging;
diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionBuilder.cs b/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionBuilder.cs
index d40232dac0..9be6b2993b 100644
--- a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionBuilder.cs
+++ b/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionBuilder.cs
@@ -42,9 +42,11 @@ public HubConnection Build()
throw new InvalidOperationException("Cannot create IConnection instance. The connection factory was not configured.");
}
+ IHubConnectionBuilder builder = this;
var connection = _connectionFactoryDelegate();
- var loggerFactory = ((IHubConnectionBuilder)this).GetLoggerFactory();
- var hubProtocol = ((IHubConnectionBuilder)this).GetHubProtocol();
+
+ var loggerFactory = builder.GetLoggerFactory();
+ var hubProtocol = builder.GetHubProtocol();
return new HubConnection(connection, hubProtocol ?? new JsonHubProtocol(), loggerFactory);
}
diff --git a/src/Microsoft.AspNetCore.SignalR.Client/HubConnectionBuilderHttpExtensions.cs b/src/Microsoft.AspNetCore.SignalR.Client/HubConnectionBuilderHttpExtensions.cs
index 5ba00304ec..cdab76ef41 100644
--- a/src/Microsoft.AspNetCore.SignalR.Client/HubConnectionBuilderHttpExtensions.cs
+++ b/src/Microsoft.AspNetCore.SignalR.Client/HubConnectionBuilderHttpExtensions.cs
@@ -2,9 +2,12 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Net.Http;
using Microsoft.AspNetCore.Sockets;
using Microsoft.AspNetCore.Sockets.Client;
+using Microsoft.AspNetCore.Sockets.Client.Http;
namespace Microsoft.AspNetCore.SignalR.Client
{
@@ -12,6 +15,8 @@ public static class HubConnectionBuilderHttpExtensions
{
public static readonly string TransportTypeKey = "TransportType";
public static readonly string HttpMessageHandlerKey = "HttpMessageHandler";
+ public static readonly string HeadersKey = "Headers";
+ public static readonly string JwtBearerTokenFactoryKey = "JwtBearerTokenFactory";
public static IHubConnectionBuilder WithUrl(this IHubConnectionBuilder hubConnectionBuilder, string url)
{
@@ -32,10 +37,18 @@ public static IHubConnectionBuilder WithUrl(this IHubConnectionBuilder hubConnec
hubConnectionBuilder.ConfigureConnectionFactory(() =>
{
+ var headers = hubConnectionBuilder.GetHeaders();
+ var httpOptions = new HttpOptions
+ {
+ HttpMessageHandler = hubConnectionBuilder.GetMessageHandler(),
+ Headers = headers != null ? new ReadOnlyDictionary(headers) : null,
+ JwtBearerTokenFactory = hubConnectionBuilder.GetJwtBearerTokenFactory()
+ };
+
return new HttpConnection(url,
hubConnectionBuilder.GetTransport(),
hubConnectionBuilder.GetLoggerFactory(),
- hubConnectionBuilder.GetMessageHandler());
+ httpOptions);
});
return hubConnectionBuilder;
}
@@ -52,6 +65,37 @@ public static IHubConnectionBuilder WithMessageHandler(this IHubConnectionBuilde
return hubConnectionBuilder;
}
+ public static IHubConnectionBuilder WithHeader(this IHubConnectionBuilder hubConnectionBuilder, string name, string value)
+ {
+ if (string.IsNullOrEmpty(name))
+ {
+ throw new ArgumentException("Header name cannot be null or empty string.", nameof(name));
+ }
+
+ var headers = hubConnectionBuilder.GetHeaders();
+ if (headers == null)
+ {
+ headers = new Dictionary();
+ hubConnectionBuilder.AddSetting(HeadersKey, headers);
+ }
+
+ headers.Add(name, value);
+
+ return hubConnectionBuilder;
+ }
+
+ public static IHubConnectionBuilder WithJwtBearer(this IHubConnectionBuilder hubConnectionBuilder, Func jwtBearerTokenFactory)
+ {
+ if (jwtBearerTokenFactory == null)
+ {
+ throw new ArgumentNullException(nameof(jwtBearerTokenFactory));
+ }
+
+ hubConnectionBuilder.AddSetting(JwtBearerTokenFactoryKey, jwtBearerTokenFactory);
+
+ return hubConnectionBuilder;
+ }
+
public static TransportType GetTransport(this IHubConnectionBuilder hubConnectionBuilder)
{
if (hubConnectionBuilder.TryGetSetting(TransportTypeKey, out var transportType))
@@ -67,5 +111,25 @@ public static HttpMessageHandler GetMessageHandler(this IHubConnectionBuilder hu
hubConnectionBuilder.TryGetSetting(HttpMessageHandlerKey, out var messageHandler);
return messageHandler;
}
+
+ public static IDictionary GetHeaders(this IHubConnectionBuilder hubConnectionBuilder)
+ {
+ if (hubConnectionBuilder.TryGetSetting>(HeadersKey, out var headers))
+ {
+ return headers;
+ }
+
+ return null;
+ }
+
+ public static Func GetJwtBearerTokenFactory(this IHubConnectionBuilder hubConnectionBuilder)
+ {
+ if (hubConnectionBuilder.TryGetSetting>(JwtBearerTokenFactoryKey, out var factory))
+ {
+ return factory;
+ }
+
+ return null;
+ }
}
}
diff --git a/src/Microsoft.AspNetCore.Sockets.Client.Http/DefaultTransportFactory.cs b/src/Microsoft.AspNetCore.Sockets.Client.Http/DefaultTransportFactory.cs
index 155348e692..2f1f93c8da 100644
--- a/src/Microsoft.AspNetCore.Sockets.Client.Http/DefaultTransportFactory.cs
+++ b/src/Microsoft.AspNetCore.Sockets.Client.Http/DefaultTransportFactory.cs
@@ -3,6 +3,7 @@
using System;
using System.Net.Http;
+using Microsoft.AspNetCore.Sockets.Client.Http;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Sockets.Client
@@ -10,11 +11,12 @@ namespace Microsoft.AspNetCore.Sockets.Client
public class DefaultTransportFactory : ITransportFactory
{
private readonly HttpClient _httpClient;
+ private readonly HttpOptions _httpOptions;
private readonly TransportType _requestedTransportType;
private readonly ILoggerFactory _loggerFactory;
private static volatile bool _websocketsSupported = true;
- public DefaultTransportFactory(TransportType requestedTransportType, ILoggerFactory loggerFactory, HttpClient httpClient)
+ public DefaultTransportFactory(TransportType requestedTransportType, ILoggerFactory loggerFactory, HttpClient httpClient, HttpOptions httpOptions)
{
if (requestedTransportType <= 0 || requestedTransportType > TransportType.All)
{
@@ -29,6 +31,7 @@ public DefaultTransportFactory(TransportType requestedTransportType, ILoggerFact
_requestedTransportType = requestedTransportType;
_loggerFactory = loggerFactory;
_httpClient = httpClient;
+ _httpOptions = httpOptions;
}
public ITransport CreateTransport(TransportType availableServerTransports)
@@ -37,7 +40,7 @@ public ITransport CreateTransport(TransportType availableServerTransports)
{
try
{
- return new WebSocketsTransport(_loggerFactory);
+ return new WebSocketsTransport(_httpOptions, _loggerFactory);
}
catch (PlatformNotSupportedException)
{
@@ -47,12 +50,12 @@ public ITransport CreateTransport(TransportType availableServerTransports)
if ((availableServerTransports & TransportType.ServerSentEvents & _requestedTransportType) == TransportType.ServerSentEvents)
{
- return new ServerSentEventsTransport(_httpClient, _loggerFactory);
+ return new ServerSentEventsTransport(_httpClient, _httpOptions, _loggerFactory);
}
if ((availableServerTransports & TransportType.LongPolling & _requestedTransportType) == TransportType.LongPolling)
{
- return new LongPollingTransport(_httpClient, _loggerFactory);
+ return new LongPollingTransport(_httpClient, _httpOptions, _loggerFactory);
}
throw new InvalidOperationException("No requested transports available on the server.");
diff --git a/src/Microsoft.AspNetCore.Sockets.Client.Http/HttpConnection.cs b/src/Microsoft.AspNetCore.Sockets.Client.Http/HttpConnection.cs
index 7187db3a57..e312bad199 100644
--- a/src/Microsoft.AspNetCore.Sockets.Client.Http/HttpConnection.cs
+++ b/src/Microsoft.AspNetCore.Sockets.Client.Http/HttpConnection.cs
@@ -31,6 +31,7 @@ public class HttpConnection : IConnection
private volatile int _connectionState = ConnectionState.Initial;
private volatile ChannelConnection _transportChannel;
private readonly HttpClient _httpClient;
+ private readonly HttpOptions _httpOptions;
private volatile ITransport _transport;
private volatile Task _receiveLoopTask;
private TaskCompletionSource