Refactor HttpOptions in client (#1942)
- Rename HttpOptions to HttpConfigurationOptions - Remove HttpConfigurationOptions from SignalR client project - Updated client HttpConnection ctors
This commit is contained in:
parent
b30c2fecbf
commit
12b69a0fdb
|
|
@ -33,10 +33,8 @@ namespace ClientSample
|
||||||
{
|
{
|
||||||
baseUrl = string.IsNullOrEmpty(baseUrl) ? "http://localhost:5000/chat" : baseUrl;
|
baseUrl = string.IsNullOrEmpty(baseUrl) ? "http://localhost:5000/chat" : baseUrl;
|
||||||
|
|
||||||
var loggerFactory = new LoggerFactory();
|
|
||||||
|
|
||||||
Console.WriteLine($"Connecting to {baseUrl}...");
|
Console.WriteLine($"Connecting to {baseUrl}...");
|
||||||
var connection = new HttpConnection(new Uri(baseUrl), loggerFactory);
|
var connection = new HttpConnection(new Uri(baseUrl));
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await connection.StartAsync(TransferFormat.Text);
|
await connection.StartAsync(TransferFormat.Text);
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,12 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
|
||||||
public class DefaultTransportFactory : ITransportFactory
|
public class DefaultTransportFactory : ITransportFactory
|
||||||
{
|
{
|
||||||
private readonly HttpClient _httpClient;
|
private readonly HttpClient _httpClient;
|
||||||
private readonly HttpOptions _httpOptions;
|
private readonly HttpConnectionOptions _httpConnectionOptions;
|
||||||
private readonly HttpTransportType _requestedTransportType;
|
private readonly HttpTransportType _requestedTransportType;
|
||||||
private readonly ILoggerFactory _loggerFactory;
|
private readonly ILoggerFactory _loggerFactory;
|
||||||
private static volatile bool _websocketsSupported = true;
|
private static volatile bool _websocketsSupported = true;
|
||||||
|
|
||||||
public DefaultTransportFactory(HttpTransportType requestedTransportType, ILoggerFactory loggerFactory, HttpClient httpClient, HttpOptions httpOptions)
|
public DefaultTransportFactory(HttpTransportType requestedTransportType, ILoggerFactory loggerFactory, HttpClient httpClient, HttpConnectionOptions httpConnectionOptions)
|
||||||
{
|
{
|
||||||
if (httpClient == null && requestedTransportType != HttpTransportType.WebSockets)
|
if (httpClient == null && requestedTransportType != HttpTransportType.WebSockets)
|
||||||
{
|
{
|
||||||
|
|
@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
|
||||||
_requestedTransportType = requestedTransportType;
|
_requestedTransportType = requestedTransportType;
|
||||||
_loggerFactory = loggerFactory;
|
_loggerFactory = loggerFactory;
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_httpOptions = httpOptions;
|
_httpConnectionOptions = httpConnectionOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ITransport CreateTransport(HttpTransportType availableServerTransports)
|
public ITransport CreateTransport(HttpTransportType availableServerTransports)
|
||||||
|
|
@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return new WebSocketsTransport(_httpOptions, _loggerFactory);
|
return new WebSocketsTransport(_httpConnectionOptions, _loggerFactory);
|
||||||
}
|
}
|
||||||
catch (PlatformNotSupportedException)
|
catch (PlatformNotSupportedException)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -34,17 +34,14 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
|
|
||||||
private readonly HttpClient _httpClient;
|
private readonly HttpClient _httpClient;
|
||||||
private readonly HttpOptions _httpOptions;
|
private readonly HttpConnectionOptions _httpConnectionOptions;
|
||||||
private ITransport _transport;
|
private ITransport _transport;
|
||||||
private readonly ITransportFactory _transportFactory;
|
private readonly ITransportFactory _transportFactory;
|
||||||
private string _connectionId;
|
private string _connectionId;
|
||||||
private readonly HttpTransportType _requestedTransports;
|
|
||||||
private readonly ConnectionLogScope _logScope;
|
private readonly ConnectionLogScope _logScope;
|
||||||
private readonly IDisposable _scopeDisposable;
|
private readonly IDisposable _scopeDisposable;
|
||||||
private readonly ILoggerFactory _loggerFactory;
|
private readonly ILoggerFactory _loggerFactory;
|
||||||
|
|
||||||
public Uri Url { get; }
|
|
||||||
|
|
||||||
public override IDuplexPipe Transport
|
public override IDuplexPipe Transport
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
@ -72,48 +69,49 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpConnection(Uri url, ILoggerFactory loggerFactory)
|
|
||||||
: this(url, HttpTransports.All, loggerFactory, httpOptions: null)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpConnection(Uri url, HttpTransportType transports, ILoggerFactory loggerFactory)
|
public HttpConnection(Uri url, HttpTransportType transports, ILoggerFactory loggerFactory)
|
||||||
: this(url, transports, loggerFactory, httpOptions: null)
|
: this(CreateHttpOptions(url, transports), loggerFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpConnection(Uri url, HttpTransportType transports, ILoggerFactory loggerFactory, HttpOptions httpOptions)
|
private static HttpConnectionOptions CreateHttpOptions(Uri url, HttpTransportType transports)
|
||||||
{
|
{
|
||||||
Url = url ?? throw new ArgumentNullException(nameof(url));
|
if (url == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(url));
|
||||||
|
}
|
||||||
|
return new HttpConnectionOptions { Url = url, Transports = transports };
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpConnection(HttpConnectionOptions httpConnectionOptions, ILoggerFactory loggerFactory)
|
||||||
|
{
|
||||||
|
if (httpConnectionOptions.Url == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Options does not have a URL specified.", nameof(httpConnectionOptions));
|
||||||
|
}
|
||||||
|
|
||||||
_loggerFactory = loggerFactory ?? NullLoggerFactory.Instance;
|
_loggerFactory = loggerFactory ?? NullLoggerFactory.Instance;
|
||||||
|
|
||||||
_logger = _loggerFactory.CreateLogger<HttpConnection>();
|
_logger = _loggerFactory.CreateLogger<HttpConnection>();
|
||||||
_httpOptions = httpOptions;
|
_httpConnectionOptions = httpConnectionOptions;
|
||||||
|
|
||||||
_requestedTransports = transports;
|
if (httpConnectionOptions.Transports != HttpTransportType.WebSockets)
|
||||||
if (_requestedTransports != HttpTransportType.WebSockets)
|
|
||||||
{
|
{
|
||||||
_httpClient = CreateHttpClient();
|
_httpClient = CreateHttpClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
_transportFactory = new DefaultTransportFactory(transports, _loggerFactory, _httpClient, httpOptions);
|
_transportFactory = new DefaultTransportFactory(httpConnectionOptions.Transports, _loggerFactory, _httpClient, httpConnectionOptions);
|
||||||
_logScope = new ConnectionLogScope();
|
_logScope = new ConnectionLogScope();
|
||||||
_scopeDisposable = _logger.BeginScope(_logScope);
|
_scopeDisposable = _logger.BeginScope(_logScope);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpConnection(Uri url, ITransportFactory transportFactory, ILoggerFactory loggerFactory, HttpOptions httpOptions)
|
// Used by unit tests
|
||||||
|
internal HttpConnection(HttpConnectionOptions httpConnectionOptions, ILoggerFactory loggerFactory, ITransportFactory transportFactory)
|
||||||
|
: this(httpConnectionOptions, loggerFactory)
|
||||||
{
|
{
|
||||||
Url = url ?? throw new ArgumentNullException(nameof(url));
|
_transportFactory = transportFactory;
|
||||||
_loggerFactory = loggerFactory ?? NullLoggerFactory.Instance;
|
|
||||||
_logger = _loggerFactory.CreateLogger<HttpConnection>();
|
|
||||||
_httpOptions = httpOptions;
|
|
||||||
_httpClient = CreateHttpClient();
|
|
||||||
_requestedTransports = HttpTransports.All;
|
|
||||||
_transportFactory = transportFactory ?? throw new ArgumentNullException(nameof(transportFactory));
|
|
||||||
_logScope = new ConnectionLogScope();
|
|
||||||
_scopeDisposable = _logger.BeginScope(_logScope);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StartAsync(TransferFormat transferFormat)
|
public async Task StartAsync(TransferFormat transferFormat)
|
||||||
{
|
{
|
||||||
await StartAsyncCore(transferFormat).ForceAsync();
|
await StartAsyncCore(transferFormat).ForceAsync();
|
||||||
|
|
@ -204,17 +202,17 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
|
||||||
|
|
||||||
private async Task SelectAndStartTransport(TransferFormat transferFormat)
|
private async Task SelectAndStartTransport(TransferFormat transferFormat)
|
||||||
{
|
{
|
||||||
if (_requestedTransports == HttpTransportType.WebSockets)
|
if (_httpConnectionOptions.Transports == HttpTransportType.WebSockets)
|
||||||
{
|
{
|
||||||
Log.StartingTransport(_logger, _requestedTransports, Url);
|
Log.StartingTransport(_logger, _httpConnectionOptions.Transports, _httpConnectionOptions.Url);
|
||||||
await StartTransport(Url, _requestedTransports, transferFormat);
|
await StartTransport(_httpConnectionOptions.Url, _httpConnectionOptions.Transports, transferFormat);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var negotiationResponse = await GetNegotiationResponse();
|
var negotiationResponse = await GetNegotiationResponse();
|
||||||
|
|
||||||
// This should only need to happen once
|
// This should only need to happen once
|
||||||
var connectUrl = CreateConnectUrl(Url, negotiationResponse.ConnectionId);
|
var connectUrl = CreateConnectUrl(_httpConnectionOptions.Url, negotiationResponse.ConnectionId);
|
||||||
|
|
||||||
// We're going to search for the transfer format as a string because we don't want to parse
|
// We're going to search for the transfer format as a string because we don't want to parse
|
||||||
// all the transfer formats in the negotiation response, and we want to allow transfer formats
|
// all the transfer formats in the negotiation response, and we want to allow transfer formats
|
||||||
|
|
@ -237,7 +235,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if ((transportType & _requestedTransports) == 0)
|
if ((transportType & _httpConnectionOptions.Transports) == 0)
|
||||||
{
|
{
|
||||||
Log.TransportDisabledByClient(_logger, transportType);
|
Log.TransportDisabledByClient(_logger, transportType);
|
||||||
}
|
}
|
||||||
|
|
@ -251,7 +249,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
|
||||||
if (negotiationResponse == null)
|
if (negotiationResponse == null)
|
||||||
{
|
{
|
||||||
negotiationResponse = await GetNegotiationResponse();
|
negotiationResponse = await GetNegotiationResponse();
|
||||||
connectUrl = CreateConnectUrl(Url, negotiationResponse.ConnectionId);
|
connectUrl = CreateConnectUrl(_httpConnectionOptions.Url, negotiationResponse.ConnectionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.StartingTransport(_logger, transportType, connectUrl);
|
Log.StartingTransport(_logger, transportType, connectUrl);
|
||||||
|
|
@ -362,33 +360,33 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
|
||||||
var httpClientHandler = new HttpClientHandler();
|
var httpClientHandler = new HttpClientHandler();
|
||||||
HttpMessageHandler httpMessageHandler = httpClientHandler;
|
HttpMessageHandler httpMessageHandler = httpClientHandler;
|
||||||
|
|
||||||
if (_httpOptions != null)
|
if (_httpConnectionOptions != null)
|
||||||
{
|
{
|
||||||
if (_httpOptions.Proxy != null)
|
if (_httpConnectionOptions.Proxy != null)
|
||||||
{
|
{
|
||||||
httpClientHandler.Proxy = _httpOptions.Proxy;
|
httpClientHandler.Proxy = _httpConnectionOptions.Proxy;
|
||||||
}
|
}
|
||||||
if (_httpOptions.Cookies != null)
|
if (_httpConnectionOptions.Cookies != null)
|
||||||
{
|
{
|
||||||
httpClientHandler.CookieContainer = _httpOptions.Cookies;
|
httpClientHandler.CookieContainer = _httpConnectionOptions.Cookies;
|
||||||
}
|
}
|
||||||
if (_httpOptions.ClientCertificates != null)
|
if (_httpConnectionOptions.ClientCertificates != null)
|
||||||
{
|
{
|
||||||
httpClientHandler.ClientCertificates.AddRange(_httpOptions.ClientCertificates);
|
httpClientHandler.ClientCertificates.AddRange(_httpConnectionOptions.ClientCertificates);
|
||||||
}
|
}
|
||||||
if (_httpOptions.UseDefaultCredentials != null)
|
if (_httpConnectionOptions.UseDefaultCredentials != null)
|
||||||
{
|
{
|
||||||
httpClientHandler.UseDefaultCredentials = _httpOptions.UseDefaultCredentials.Value;
|
httpClientHandler.UseDefaultCredentials = _httpConnectionOptions.UseDefaultCredentials.Value;
|
||||||
}
|
}
|
||||||
if (_httpOptions.Credentials != null)
|
if (_httpConnectionOptions.Credentials != null)
|
||||||
{
|
{
|
||||||
httpClientHandler.Credentials = _httpOptions.Credentials;
|
httpClientHandler.Credentials = _httpConnectionOptions.Credentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
httpMessageHandler = httpClientHandler;
|
httpMessageHandler = httpClientHandler;
|
||||||
if (_httpOptions.HttpMessageHandlerFactory != null)
|
if (_httpConnectionOptions.HttpMessageHandlerFactory != null)
|
||||||
{
|
{
|
||||||
httpMessageHandler = _httpOptions.HttpMessageHandlerFactory(httpClientHandler);
|
httpMessageHandler = _httpConnectionOptions.HttpMessageHandlerFactory(httpClientHandler);
|
||||||
if (httpMessageHandler == null)
|
if (httpMessageHandler == null)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Configured HttpMessageHandlerFactory did not return a value.");
|
throw new InvalidOperationException("Configured HttpMessageHandlerFactory did not return a value.");
|
||||||
|
|
@ -396,9 +394,9 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the authorization header in a handler instead of a default header because it can change with each request
|
// Apply the authorization header in a handler instead of a default header because it can change with each request
|
||||||
if (_httpOptions.AccessTokenFactory != null)
|
if (_httpConnectionOptions.AccessTokenFactory != null)
|
||||||
{
|
{
|
||||||
httpMessageHandler = new AccessTokenHttpMessageHandler(httpMessageHandler, _httpOptions.AccessTokenFactory);
|
httpMessageHandler = new AccessTokenHttpMessageHandler(httpMessageHandler, _httpConnectionOptions.AccessTokenFactory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -411,10 +409,10 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
|
||||||
// Start with the user agent header
|
// Start with the user agent header
|
||||||
httpClient.DefaultRequestHeaders.UserAgent.Add(Constants.UserAgentHeader);
|
httpClient.DefaultRequestHeaders.UserAgent.Add(Constants.UserAgentHeader);
|
||||||
|
|
||||||
// Apply any headers configured on the HttpOptions
|
// Apply any headers configured on the HttpConnectionOptions
|
||||||
if (_httpOptions?.Headers != null)
|
if (_httpConnectionOptions?.Headers != null)
|
||||||
{
|
{
|
||||||
foreach (var header in _httpOptions.Headers)
|
foreach (var header in _httpConnectionOptions.Headers)
|
||||||
{
|
{
|
||||||
httpClient.DefaultRequestHeaders.Add(header.Key, header.Value);
|
httpClient.DefaultRequestHeaders.Add(header.Key, header.Value);
|
||||||
}
|
}
|
||||||
|
|
@ -457,7 +455,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
|
||||||
|
|
||||||
private async Task<NegotiationResponse> GetNegotiationResponse()
|
private async Task<NegotiationResponse> GetNegotiationResponse()
|
||||||
{
|
{
|
||||||
var negotiationResponse = await Negotiate(Url, _httpClient, _logger);
|
var negotiationResponse = await Negotiate(_httpConnectionOptions.Url, _httpClient, _logger);
|
||||||
_connectionId = negotiationResponse.ConnectionId;
|
_connectionId = negotiationResponse.ConnectionId;
|
||||||
_logScope.ConnectionId = _connectionId;
|
_logScope.ConnectionId = _connectionId;
|
||||||
return negotiationResponse;
|
return negotiationResponse;
|
||||||
|
|
|
||||||
|
|
@ -8,23 +8,54 @@ using System.Net.Http;
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Http.Connections.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Http.Connections.Client
|
namespace Microsoft.AspNetCore.Http.Connections.Client
|
||||||
{
|
{
|
||||||
public class HttpOptions
|
public class HttpConnectionOptions
|
||||||
{
|
{
|
||||||
|
private IDictionary<string, string> _headers;
|
||||||
|
private X509CertificateCollection _clientCertificates;
|
||||||
|
private CookieContainer _cookies;
|
||||||
|
|
||||||
|
public HttpConnectionOptions()
|
||||||
|
{
|
||||||
|
_headers = new Dictionary<string, string>();
|
||||||
|
_clientCertificates = new X509CertificateCollection();
|
||||||
|
_cookies = new CookieContainer();
|
||||||
|
|
||||||
|
Transports = HttpTransports.All;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a delegate for wrapping or replacing the <see cref="HttpMessageHandlerFactory"/>
|
/// Gets or sets a delegate for wrapping or replacing the <see cref="HttpMessageHandlerFactory"/>
|
||||||
/// that will make HTTP requests the server.
|
/// that will make HTTP requests the server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Func<HttpMessageHandler, HttpMessageHandler> HttpMessageHandlerFactory { get; set; }
|
public Func<HttpMessageHandler, HttpMessageHandler> HttpMessageHandlerFactory { get; set; }
|
||||||
|
|
||||||
public IReadOnlyCollection<KeyValuePair<string, string>> Headers { get; set; }
|
public IDictionary<string, string> Headers
|
||||||
|
{
|
||||||
|
get => _headers;
|
||||||
|
set => _headers = value ?? throw new ArgumentNullException(nameof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public X509CertificateCollection ClientCertificates
|
||||||
|
{
|
||||||
|
get => _clientCertificates;
|
||||||
|
set => _clientCertificates = value ?? throw new ArgumentNullException(nameof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public CookieContainer Cookies
|
||||||
|
{
|
||||||
|
get => _cookies;
|
||||||
|
set => _cookies = value ?? throw new ArgumentNullException(nameof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uri Url { get; set; }
|
||||||
|
public HttpTransportType Transports { get; set; }
|
||||||
public Func<Task<string>> AccessTokenFactory { get; set; }
|
public Func<Task<string>> AccessTokenFactory { get; set; }
|
||||||
public TimeSpan CloseTimeout { get; set; } = TimeSpan.FromSeconds(5);
|
public TimeSpan CloseTimeout { get; set; } = TimeSpan.FromSeconds(5);
|
||||||
public ICredentials Credentials { get; set; }
|
public ICredentials Credentials { get; set; }
|
||||||
public X509CertificateCollection ClientCertificates { get; set; } = new X509CertificateCollection();
|
|
||||||
public CookieContainer Cookies { get; set; } = new CookieContainer();
|
|
||||||
public IWebProxy Proxy { get; set; }
|
public IWebProxy Proxy { get; set; }
|
||||||
public bool? UseDefaultCredentials { get; set; }
|
public bool? UseDefaultCredentials { get; set; }
|
||||||
|
|
||||||
|
|
@ -37,56 +37,56 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public WebSocketsTransport(HttpOptions httpOptions, ILoggerFactory loggerFactory)
|
public WebSocketsTransport(HttpConnectionOptions httpConnectionOptions, ILoggerFactory loggerFactory)
|
||||||
{
|
{
|
||||||
_webSocket = new ClientWebSocket();
|
_webSocket = new ClientWebSocket();
|
||||||
|
|
||||||
// Issue in ClientWebSocket prevents user-agent being set - https://github.com/dotnet/corefx/issues/26627
|
// Issue in ClientWebSocket prevents user-agent being set - https://github.com/dotnet/corefx/issues/26627
|
||||||
//_webSocket.Options.SetRequestHeader("User-Agent", Constants.UserAgentHeader.ToString());
|
//_webSocket.Options.SetRequestHeader("User-Agent", Constants.UserAgentHeader.ToString());
|
||||||
|
|
||||||
if (httpOptions != null)
|
if (httpConnectionOptions != null)
|
||||||
{
|
{
|
||||||
if (httpOptions.Headers != null)
|
if (httpConnectionOptions.Headers != null)
|
||||||
{
|
{
|
||||||
foreach (var header in httpOptions.Headers)
|
foreach (var header in httpConnectionOptions.Headers)
|
||||||
{
|
{
|
||||||
_webSocket.Options.SetRequestHeader(header.Key, header.Value);
|
_webSocket.Options.SetRequestHeader(header.Key, header.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (httpOptions.Cookies != null)
|
if (httpConnectionOptions.Cookies != null)
|
||||||
{
|
{
|
||||||
_webSocket.Options.Cookies = httpOptions.Cookies;
|
_webSocket.Options.Cookies = httpConnectionOptions.Cookies;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (httpOptions.ClientCertificates != null)
|
if (httpConnectionOptions.ClientCertificates != null)
|
||||||
{
|
{
|
||||||
_webSocket.Options.ClientCertificates.AddRange(httpOptions.ClientCertificates);
|
_webSocket.Options.ClientCertificates.AddRange(httpConnectionOptions.ClientCertificates);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (httpOptions.Credentials != null)
|
if (httpConnectionOptions.Credentials != null)
|
||||||
{
|
{
|
||||||
_webSocket.Options.Credentials = httpOptions.Credentials;
|
_webSocket.Options.Credentials = httpConnectionOptions.Credentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (httpOptions.Proxy != null)
|
if (httpConnectionOptions.Proxy != null)
|
||||||
{
|
{
|
||||||
_webSocket.Options.Proxy = httpOptions.Proxy;
|
_webSocket.Options.Proxy = httpConnectionOptions.Proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (httpOptions.UseDefaultCredentials != null)
|
if (httpConnectionOptions.UseDefaultCredentials != null)
|
||||||
{
|
{
|
||||||
_webSocket.Options.UseDefaultCredentials = httpOptions.UseDefaultCredentials.Value;
|
_webSocket.Options.UseDefaultCredentials = httpConnectionOptions.UseDefaultCredentials.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (httpOptions.AccessTokenFactory != null)
|
if (httpConnectionOptions.AccessTokenFactory != null)
|
||||||
{
|
{
|
||||||
_accessTokenFactory = httpOptions.AccessTokenFactory;
|
_accessTokenFactory = httpConnectionOptions.AccessTokenFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
httpOptions.WebSocketOptions?.Invoke(_webSocket.Options);
|
httpConnectionOptions.WebSocketOptions?.Invoke(_webSocket.Options);
|
||||||
|
|
||||||
_closeTimeout = httpOptions.CloseTimeout;
|
_closeTimeout = httpConnectionOptions.CloseTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set this header so the server auth middleware will set an Unauthorized instead of Redirect status code
|
// Set this header so the server auth middleware will set an Unauthorized instead of Redirect status code
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,6 @@
|
||||||
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.SignalR.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||||
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.SignalR.Client.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.SignalR.Client.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||||
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.SignalR.Microbenchmarks, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.SignalR.Microbenchmarks, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Connections;
|
using Microsoft.AspNetCore.Connections;
|
||||||
using Microsoft.AspNetCore.Http.Connections.Client;
|
using Microsoft.AspNetCore.Http.Connections.Client;
|
||||||
|
|
@ -13,7 +12,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
|
||||||
{
|
{
|
||||||
public class HttpConnectionFactory : IConnectionFactory
|
public class HttpConnectionFactory : IConnectionFactory
|
||||||
{
|
{
|
||||||
private readonly HttpConnectionOptions _options;
|
private readonly HttpConnectionOptions _httpConnectionOptions;
|
||||||
private readonly ILoggerFactory _loggerFactory;
|
private readonly ILoggerFactory _loggerFactory;
|
||||||
|
|
||||||
public HttpConnectionFactory(IOptions<HttpConnectionOptions> options, ILoggerFactory loggerFactory)
|
public HttpConnectionFactory(IOptions<HttpConnectionOptions> options, ILoggerFactory loggerFactory)
|
||||||
|
|
@ -28,28 +27,15 @@ namespace Microsoft.AspNetCore.SignalR.Client
|
||||||
throw new ArgumentNullException(nameof(loggerFactory));
|
throw new ArgumentNullException(nameof(loggerFactory));
|
||||||
}
|
}
|
||||||
|
|
||||||
_options = options.Value;
|
_httpConnectionOptions = options.Value;
|
||||||
_loggerFactory = loggerFactory;
|
_loggerFactory = loggerFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ConnectionContext> ConnectAsync(TransferFormat transferFormat)
|
public async Task<ConnectionContext> ConnectAsync(TransferFormat transferFormat)
|
||||||
{
|
{
|
||||||
var httpOptions = new HttpOptions
|
var connection = new HttpConnection(_httpConnectionOptions, _loggerFactory);
|
||||||
{
|
|
||||||
HttpMessageHandlerFactory = _options.MessageHandlerFactory,
|
|
||||||
Headers = _options._headers != null ? new ReadOnlyDictionary<string, string>(_options._headers) : null,
|
|
||||||
AccessTokenFactory = _options.AccessTokenFactory,
|
|
||||||
WebSocketOptions = _options.WebSocketOptions,
|
|
||||||
Cookies = _options._cookies,
|
|
||||||
Proxy = _options.Proxy,
|
|
||||||
UseDefaultCredentials = _options.UseDefaultCredentials,
|
|
||||||
ClientCertificates = _options._clientCertificates,
|
|
||||||
Credentials = _options.Credentials,
|
|
||||||
};
|
|
||||||
|
|
||||||
var connection = new HttpConnection(_options.Url, _options.Transports, _loggerFactory, httpOptions);
|
|
||||||
await connection.StartAsync(transferFormat);
|
await connection.StartAsync(transferFormat);
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
|
||||||
// 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.Net;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.WebSockets;
|
|
||||||
using System.Security.Cryptography.X509Certificates;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Http.Connections;
|
|
||||||
using Microsoft.AspNetCore.Http.Connections.Internal;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.SignalR.Client
|
|
||||||
{
|
|
||||||
public class HttpConnectionOptions
|
|
||||||
{
|
|
||||||
internal X509CertificateCollection _clientCertificates;
|
|
||||||
internal IDictionary<string, string> _headers;
|
|
||||||
internal CookieContainer _cookies;
|
|
||||||
|
|
||||||
public HttpConnectionOptions()
|
|
||||||
{
|
|
||||||
Transports = HttpTransports.All;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Uri Url { get; set; }
|
|
||||||
public HttpTransportType Transports { get; set; }
|
|
||||||
public Func<HttpMessageHandler, HttpMessageHandler> MessageHandlerFactory { get; set; }
|
|
||||||
public bool? UseDefaultCredentials { get; set; }
|
|
||||||
public ICredentials Credentials { get; set; }
|
|
||||||
public IWebProxy Proxy { get; set; }
|
|
||||||
public Func<Task<string>> AccessTokenFactory { get; set; }
|
|
||||||
public Action<ClientWebSocketOptions> WebSocketOptions { get; set; }
|
|
||||||
|
|
||||||
public X509CertificateCollection ClientCertificates
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_clientCertificates == null)
|
|
||||||
{
|
|
||||||
_clientCertificates = new X509CertificateCollection();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _clientCertificates;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public CookieContainer Cookies
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_cookies == null)
|
|
||||||
{
|
|
||||||
_cookies = new CookieContainer();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _cookies;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IDictionary<string, string> Headers
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_headers == null)
|
|
||||||
{
|
|
||||||
_headers = new Dictionary<string, string>(StringComparer.Ordinal);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _headers;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.AspNetCore.Http.Connections;
|
using Microsoft.AspNetCore.Http.Connections;
|
||||||
|
using Microsoft.AspNetCore.Http.Connections.Client;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.SignalR.Client
|
namespace Microsoft.AspNetCore.SignalR.Client
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Connections;
|
using Microsoft.AspNetCore.Connections;
|
||||||
using Microsoft.AspNetCore.Http.Connections.Client;
|
using Microsoft.AspNetCore.Http.Connections.Client;
|
||||||
using Microsoft.AspNetCore.Http.Connections.Client.Internal;
|
using Microsoft.AspNetCore.Http.Connections.Client.Internal;
|
||||||
|
using Microsoft.AspNetCore.Http.Connections.Internal;
|
||||||
using Microsoft.AspNetCore.SignalR.Tests;
|
using Microsoft.AspNetCore.SignalR.Tests;
|
||||||
using Microsoft.Extensions.Logging.Testing;
|
using Microsoft.Extensions.Logging.Testing;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -115,6 +116,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
|
||||||
await WithConnectionAsync(
|
await WithConnectionAsync(
|
||||||
CreateConnection(
|
CreateConnection(
|
||||||
loggerFactory: loggerFactory,
|
loggerFactory: loggerFactory,
|
||||||
|
transportType: HttpTransports.All,
|
||||||
transport: new TestTransport(onTransportStart: OnTransportStart)),
|
transport: new TestTransport(onTransportStart: OnTransportStart)),
|
||||||
async (connection) =>
|
async (connection) =>
|
||||||
{
|
{
|
||||||
|
|
@ -142,6 +144,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
|
||||||
await WithConnectionAsync(
|
await WithConnectionAsync(
|
||||||
CreateConnection(
|
CreateConnection(
|
||||||
loggerFactory: loggerFactory,
|
loggerFactory: loggerFactory,
|
||||||
|
transportType: HttpTransports.All,
|
||||||
transport: new TestTransport(onTransportStart: OnTransportStart)),
|
transport: new TestTransport(onTransportStart: OnTransportStart)),
|
||||||
async (connection) =>
|
async (connection) =>
|
||||||
{
|
{
|
||||||
|
|
@ -318,7 +321,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
|
||||||
var sse = new ServerSentEventsTransport(new HttpClient(httpHandler));
|
var sse = new ServerSentEventsTransport(new HttpClient(httpHandler));
|
||||||
|
|
||||||
await WithConnectionAsync(
|
await WithConnectionAsync(
|
||||||
CreateConnection(httpHandler, loggerFactory: loggerFactory, url: null, transport: sse),
|
CreateConnection(httpHandler, loggerFactory: loggerFactory, transport: sse),
|
||||||
async (connection) =>
|
async (connection) =>
|
||||||
{
|
{
|
||||||
await Assert.ThrowsAsync<InvalidOperationException>(
|
await Assert.ThrowsAsync<InvalidOperationException>(
|
||||||
|
|
@ -344,7 +347,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
|
||||||
var sse = new ServerSentEventsTransport(new HttpClient(httpHandler));
|
var sse = new ServerSentEventsTransport(new HttpClient(httpHandler));
|
||||||
|
|
||||||
await WithConnectionAsync(
|
await WithConnectionAsync(
|
||||||
CreateConnection(httpHandler, loggerFactory: loggerFactory, url: null, transport: sse),
|
CreateConnection(httpHandler, loggerFactory: loggerFactory, transport: sse),
|
||||||
async (connection) =>
|
async (connection) =>
|
||||||
{
|
{
|
||||||
var startTask = connection.StartAsync(TransferFormat.Text).OrTimeout();
|
var startTask = connection.StartAsync(TransferFormat.Text).OrTimeout();
|
||||||
|
|
|
||||||
|
|
@ -20,34 +20,39 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
|
||||||
string url = null,
|
string url = null,
|
||||||
ITransport transport = null,
|
ITransport transport = null,
|
||||||
ITransportFactory transportFactory = null,
|
ITransportFactory transportFactory = null,
|
||||||
HttpTransportType transportType = HttpTransportType.LongPolling,
|
HttpTransportType? transportType = null,
|
||||||
Func<Task<string>> accessTokenFactory = null)
|
Func<Task<string>> accessTokenFactory = null)
|
||||||
{
|
{
|
||||||
var httpOptions = new HttpOptions
|
var httpOptions = new HttpConnectionOptions
|
||||||
{
|
{
|
||||||
|
Transports = transportType ?? HttpTransportType.LongPolling,
|
||||||
HttpMessageHandlerFactory = (httpMessageHandler) => httpHandler ?? TestHttpMessageHandler.CreateDefault(),
|
HttpMessageHandlerFactory = (httpMessageHandler) => httpHandler ?? TestHttpMessageHandler.CreateDefault(),
|
||||||
AccessTokenFactory = accessTokenFactory,
|
AccessTokenFactory = accessTokenFactory,
|
||||||
};
|
};
|
||||||
|
if (url != null)
|
||||||
|
{
|
||||||
|
httpOptions.Url = new Uri(url);
|
||||||
|
}
|
||||||
|
|
||||||
return CreateConnection(httpOptions, loggerFactory, url, transport, transportFactory, transportType);
|
return CreateConnection(httpOptions, loggerFactory, transport, transportFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static HttpConnection CreateConnection(HttpOptions httpOptions, ILoggerFactory loggerFactory = null, string url = null, ITransport transport = null, ITransportFactory transportFactory = null, HttpTransportType transportType = HttpTransportType.LongPolling)
|
private static HttpConnection CreateConnection(HttpConnectionOptions httpConnectionOptions, ILoggerFactory loggerFactory = null, ITransport transport = null, ITransportFactory transportFactory = null)
|
||||||
{
|
{
|
||||||
loggerFactory = loggerFactory ?? NullLoggerFactory.Instance;
|
loggerFactory = loggerFactory ?? NullLoggerFactory.Instance;
|
||||||
var uri = new Uri(url ?? "http://fakeuri.org/");
|
httpConnectionOptions.Url = httpConnectionOptions.Url ?? new Uri("http://fakeuri.org/");
|
||||||
|
|
||||||
if (transportFactory != null)
|
if (transportFactory != null)
|
||||||
{
|
{
|
||||||
return new HttpConnection(uri, transportFactory, loggerFactory, httpOptions);
|
return new HttpConnection(httpConnectionOptions, loggerFactory, transportFactory);
|
||||||
}
|
}
|
||||||
else if (transport != null)
|
else if (transport != null)
|
||||||
{
|
{
|
||||||
return new HttpConnection(uri, new TestTransportFactory(transport), loggerFactory, httpOptions);
|
return new HttpConnection(httpConnectionOptions, loggerFactory, new TestTransportFactory(transport));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new HttpConnection(uri, transportType, loggerFactory, httpOptions);
|
return new HttpConnection(httpConnectionOptions, loggerFactory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,10 +32,10 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ConnectionReturnsUrlUsedToStartTheConnection()
|
public void CannotCreateConnectionWithNullUrlOnOptions()
|
||||||
{
|
{
|
||||||
var connectionUrl = new Uri("http://fakeuri.org/");
|
var exception = Assert.Throws<ArgumentException>(() => new HttpConnection(new HttpConnectionOptions(), NullLoggerFactory.Instance));
|
||||||
Assert.Equal(connectionUrl, new HttpConnection(connectionUrl).Url);
|
Assert.Equal("httpConnectionOptions", exception.ParamName);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -53,7 +53,8 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
|
||||||
|
|
||||||
HttpClientHandler httpClientHandler = null;
|
HttpClientHandler httpClientHandler = null;
|
||||||
|
|
||||||
var httpOptions = new HttpOptions();
|
var httpOptions = new HttpConnectionOptions();
|
||||||
|
httpOptions.Url = new Uri("http://fakeuri.org/");
|
||||||
httpOptions.HttpMessageHandlerFactory = inner =>
|
httpOptions.HttpMessageHandlerFactory = inner =>
|
||||||
{
|
{
|
||||||
httpClientHandler = (HttpClientHandler)inner;
|
httpClientHandler = (HttpClientHandler)inner;
|
||||||
|
|
@ -65,9 +66,10 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
|
||||||
httpOptions.UseDefaultCredentials = false;
|
httpOptions.UseDefaultCredentials = false;
|
||||||
httpOptions.Credentials = Mock.Of<ICredentials>();
|
httpOptions.Credentials = Mock.Of<ICredentials>();
|
||||||
httpOptions.Proxy = Mock.Of<IWebProxy>();
|
httpOptions.Proxy = Mock.Of<IWebProxy>();
|
||||||
|
httpOptions.Transports = HttpTransportType.LongPolling;
|
||||||
|
|
||||||
await WithConnectionAsync(
|
await WithConnectionAsync(
|
||||||
CreateConnection(httpOptions, url: "http://fakeuri.org/"),
|
CreateConnection(httpOptions),
|
||||||
async (connection) =>
|
async (connection) =>
|
||||||
{
|
{
|
||||||
await connection.StartAsync(TransferFormat.Text).OrTimeout();
|
await connection.StartAsync(TransferFormat.Text).OrTimeout();
|
||||||
|
|
@ -89,7 +91,8 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
|
||||||
|
|
||||||
testHttpHandler.OnNegotiate((request, cancellationToken) => ResponseUtils.CreateResponse(HttpStatusCode.BadGateway));
|
testHttpHandler.OnNegotiate((request, cancellationToken) => ResponseUtils.CreateResponse(HttpStatusCode.BadGateway));
|
||||||
|
|
||||||
var httpOptions = new HttpOptions();
|
var httpOptions = new HttpConnectionOptions();
|
||||||
|
httpOptions.Url = new Uri("http://fakeuri.org/");
|
||||||
httpOptions.HttpMessageHandlerFactory = inner => testHttpHandler;
|
httpOptions.HttpMessageHandlerFactory = inner => testHttpHandler;
|
||||||
|
|
||||||
const string loggerName = "Microsoft.AspNetCore.Http.Connections.Client.Internal.LoggingHttpMessageHandler";
|
const string loggerName = "Microsoft.AspNetCore.Http.Connections.Client.Internal.LoggingHttpMessageHandler";
|
||||||
|
|
@ -104,7 +107,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await WithConnectionAsync(
|
await WithConnectionAsync(
|
||||||
CreateConnection(httpOptions, loggerFactory: mockLoggerFactory.Object, url: "http://fakeuri.org/"),
|
CreateConnection(httpOptions, loggerFactory: mockLoggerFactory.Object),
|
||||||
async (connection) =>
|
async (connection) =>
|
||||||
{
|
{
|
||||||
await connection.StartAsync(TransferFormat.Text).OrTimeout();
|
await connection.StartAsync(TransferFormat.Text).OrTimeout();
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Microsoft.AspNetCore.Http.Connections;
|
using Microsoft.AspNetCore.Http.Connections;
|
||||||
|
using Microsoft.AspNetCore.Http.Connections.Client;
|
||||||
using Microsoft.AspNetCore.SignalR.Internal.Protocol;
|
using Microsoft.AspNetCore.SignalR.Internal.Protocol;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
[InlineData((HttpTransportType)int.MaxValue)]
|
[InlineData((HttpTransportType)int.MaxValue)]
|
||||||
public void DefaultTransportFactoryCanBeCreatedWithNoOrUnknownTransportTypeFlags(HttpTransportType transportType)
|
public void DefaultTransportFactoryCanBeCreatedWithNoOrUnknownTransportTypeFlags(HttpTransportType transportType)
|
||||||
{
|
{
|
||||||
Assert.NotNull(new DefaultTransportFactory(transportType, new LoggerFactory(), new HttpClient(), httpOptions: null));
|
Assert.NotNull(new DefaultTransportFactory(transportType, new LoggerFactory(), new HttpClient(), httpConnectionOptions: null));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
public void DefaultTransportFactoryCannotBeCreatedWithoutHttpClient(HttpTransportType transportType)
|
public void DefaultTransportFactoryCannotBeCreatedWithoutHttpClient(HttpTransportType transportType)
|
||||||
{
|
{
|
||||||
var exception = Assert.Throws<ArgumentNullException>(
|
var exception = Assert.Throws<ArgumentNullException>(
|
||||||
() => new DefaultTransportFactory(transportType, new LoggerFactory(), httpClient: null, httpOptions: null));
|
() => new DefaultTransportFactory(transportType, new LoggerFactory(), httpClient: null, httpConnectionOptions: null));
|
||||||
|
|
||||||
Assert.Equal("httpClient", exception.ParamName);
|
Assert.Equal("httpClient", exception.ParamName);
|
||||||
}
|
}
|
||||||
|
|
@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
[Fact]
|
[Fact]
|
||||||
public void DefaultTransportFactoryCanBeCreatedWithoutHttpClientIfWebSocketsTransportRequestedExplicitly()
|
public void DefaultTransportFactoryCanBeCreatedWithoutHttpClientIfWebSocketsTransportRequestedExplicitly()
|
||||||
{
|
{
|
||||||
new DefaultTransportFactory(HttpTransportType.WebSockets, new LoggerFactory(), httpClient: null, httpOptions: null);
|
new DefaultTransportFactory(HttpTransportType.WebSockets, new LoggerFactory(), httpClient: null, httpConnectionOptions: null);
|
||||||
}
|
}
|
||||||
|
|
||||||
[ConditionalTheory]
|
[ConditionalTheory]
|
||||||
|
|
@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
[WebSocketsSupportedCondition]
|
[WebSocketsSupportedCondition]
|
||||||
public void DefaultTransportFactoryCreatesRequestedTransportIfAvailable(HttpTransportType requestedTransport, Type expectedTransportType)
|
public void DefaultTransportFactoryCreatesRequestedTransportIfAvailable(HttpTransportType requestedTransport, Type expectedTransportType)
|
||||||
{
|
{
|
||||||
var transportFactory = new DefaultTransportFactory(requestedTransport, loggerFactory: null, httpClient: new HttpClient(), httpOptions: null);
|
var transportFactory = new DefaultTransportFactory(requestedTransport, loggerFactory: null, httpClient: new HttpClient(), httpConnectionOptions: null);
|
||||||
Assert.IsType(expectedTransportType,
|
Assert.IsType(expectedTransportType,
|
||||||
transportFactory.CreateTransport(AllTransportTypes));
|
transportFactory.CreateTransport(AllTransportTypes));
|
||||||
}
|
}
|
||||||
|
|
@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
public void DefaultTransportFactoryThrowsIfItCannotCreateRequestedTransport(HttpTransportType requestedTransport)
|
public void DefaultTransportFactoryThrowsIfItCannotCreateRequestedTransport(HttpTransportType requestedTransport)
|
||||||
{
|
{
|
||||||
var transportFactory =
|
var transportFactory =
|
||||||
new DefaultTransportFactory(requestedTransport, loggerFactory: null, httpClient: new HttpClient(), httpOptions: null);
|
new DefaultTransportFactory(requestedTransport, loggerFactory: null, httpClient: new HttpClient(), httpConnectionOptions: null);
|
||||||
var ex = Assert.Throws<InvalidOperationException>(
|
var ex = Assert.Throws<InvalidOperationException>(
|
||||||
() => transportFactory.CreateTransport(~requestedTransport));
|
() => transportFactory.CreateTransport(~requestedTransport));
|
||||||
|
|
||||||
|
|
@ -76,7 +76,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
public void DefaultTransportFactoryCreatesWebSocketsTransportIfAvailable()
|
public void DefaultTransportFactoryCreatesWebSocketsTransportIfAvailable()
|
||||||
{
|
{
|
||||||
Assert.IsType<WebSocketsTransport>(
|
Assert.IsType<WebSocketsTransport>(
|
||||||
new DefaultTransportFactory(AllTransportTypes, loggerFactory: null, httpClient: new HttpClient(), httpOptions: null)
|
new DefaultTransportFactory(AllTransportTypes, loggerFactory: null, httpClient: new HttpClient(), httpConnectionOptions: null)
|
||||||
.CreateTransport(AllTransportTypes));
|
.CreateTransport(AllTransportTypes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,7 +88,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
{
|
{
|
||||||
if (!TestHelpers.IsWebSocketsSupported())
|
if (!TestHelpers.IsWebSocketsSupported())
|
||||||
{
|
{
|
||||||
var transportFactory = new DefaultTransportFactory(requestedTransport, loggerFactory: null, httpClient: new HttpClient(), httpOptions: null);
|
var transportFactory = new DefaultTransportFactory(requestedTransport, loggerFactory: null, httpClient: new HttpClient(), httpConnectionOptions: null);
|
||||||
Assert.IsType(expectedTransportType,
|
Assert.IsType(expectedTransportType,
|
||||||
transportFactory.CreateTransport(AllTransportTypes));
|
transportFactory.CreateTransport(AllTransportTypes));
|
||||||
}
|
}
|
||||||
|
|
@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
if (!TestHelpers.IsWebSocketsSupported())
|
if (!TestHelpers.IsWebSocketsSupported())
|
||||||
{
|
{
|
||||||
var transportFactory =
|
var transportFactory =
|
||||||
new DefaultTransportFactory(requestedTransport, loggerFactory: null, httpClient: new HttpClient(), httpOptions: null);
|
new DefaultTransportFactory(requestedTransport, loggerFactory: null, httpClient: new HttpClient(), httpConnectionOptions: null);
|
||||||
var ex = Assert.Throws<InvalidOperationException>(
|
var ex = Assert.Throws<InvalidOperationException>(
|
||||||
() => transportFactory.CreateTransport(AllTransportTypes));
|
() => transportFactory.CreateTransport(AllTransportTypes));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ using Moq;
|
||||||
using Moq.Protected;
|
using Moq.Protected;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Xunit.Abstractions;
|
using Xunit.Abstractions;
|
||||||
|
using HttpConnectionOptions = Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.SignalR.Tests
|
namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
{
|
{
|
||||||
|
|
@ -66,7 +67,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
// On Windows 7/2008R2 it should use ServerSentEvents transport to connect to the server.
|
// On Windows 7/2008R2 it should use ServerSentEvents transport to connect to the server.
|
||||||
|
|
||||||
// The test logic lives in the TestTransportFactory and FakeTransport.
|
// The test logic lives in the TestTransportFactory and FakeTransport.
|
||||||
var connection = new HttpConnection(new Uri(url), new TestTransportFactory(), null, null);
|
var connection = new HttpConnection(new HttpConnectionOptions { Url = new Uri(url) }, null, new TestTransportFactory());
|
||||||
await connection.StartAsync(TransferFormat.Text).OrTimeout();
|
await connection.StartAsync(TransferFormat.Text).OrTimeout();
|
||||||
await connection.DisposeAsync().OrTimeout();
|
await connection.DisposeAsync().OrTimeout();
|
||||||
}
|
}
|
||||||
|
|
@ -171,7 +172,14 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
.Returns<HttpRequestMessage, CancellationToken>(
|
.Returns<HttpRequestMessage, CancellationToken>(
|
||||||
(request, cancellationToken) => Task.FromException<HttpResponseMessage>(new InvalidOperationException("HTTP requests should not be sent.")));
|
(request, cancellationToken) => Task.FromException<HttpResponseMessage>(new InvalidOperationException("HTTP requests should not be sent.")));
|
||||||
|
|
||||||
var connection = new HttpConnection(new Uri(url), HttpTransportType.WebSockets, loggerFactory, new HttpOptions { HttpMessageHandlerFactory = (httpMessageHandler) => mockHttpHandler.Object });
|
var httpOptions = new HttpConnectionOptions
|
||||||
|
{
|
||||||
|
Url = new Uri(url),
|
||||||
|
Transports = HttpTransportType.WebSockets,
|
||||||
|
HttpMessageHandlerFactory = (httpMessageHandler) => mockHttpHandler.Object
|
||||||
|
};
|
||||||
|
|
||||||
|
var connection = new HttpConnection(httpOptions, loggerFactory);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,6 @@
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Include="..\..\src\Common\DuplexPipe.cs" Link="DuplexPipe.cs" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.SignalR\Microsoft.AspNetCore.SignalR.csproj" />
|
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.SignalR\Microsoft.AspNetCore.SignalR.csproj" />
|
||||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.SignalR.Client\Microsoft.AspNetCore.SignalR.Client.csproj" />
|
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.SignalR.Client\Microsoft.AspNetCore.SignalR.Client.csproj" />
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
{
|
{
|
||||||
ClientWebSocketOptions webSocketsOptions = null;
|
ClientWebSocketOptions webSocketsOptions = null;
|
||||||
|
|
||||||
var httpOptions = new HttpOptions();
|
var httpOptions = new HttpConnectionOptions();
|
||||||
httpOptions.Cookies.Add(new Cookie("Name", "Value", string.Empty, "fakeuri.org"));
|
httpOptions.Cookies.Add(new Cookie("Name", "Value", string.Empty, "fakeuri.org"));
|
||||||
var clientCertificate = new X509Certificate();
|
var clientCertificate = new X509Certificate();
|
||||||
httpOptions.ClientCertificates.Add(clientCertificate);
|
httpOptions.ClientCertificates.Add(clientCertificate);
|
||||||
|
|
@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
httpOptions.Proxy = Mock.Of<IWebProxy>();
|
httpOptions.Proxy = Mock.Of<IWebProxy>();
|
||||||
httpOptions.WebSocketOptions = options => webSocketsOptions = options;
|
httpOptions.WebSocketOptions = options => webSocketsOptions = options;
|
||||||
|
|
||||||
var webSocketsTransport = new WebSocketsTransport(httpOptions: httpOptions, loggerFactory: null);
|
var webSocketsTransport = new WebSocketsTransport(httpConnectionOptions: httpOptions, loggerFactory: null);
|
||||||
Assert.NotNull(webSocketsTransport);
|
Assert.NotNull(webSocketsTransport);
|
||||||
|
|
||||||
Assert.NotNull(webSocketsOptions);
|
Assert.NotNull(webSocketsOptions);
|
||||||
|
|
@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var webSocketsTransport = new WebSocketsTransport(httpOptions: null, loggerFactory: loggerFactory);
|
var webSocketsTransport = new WebSocketsTransport(httpConnectionOptions: null, loggerFactory: loggerFactory);
|
||||||
await webSocketsTransport.StartAsync(new Uri(_serverFixture.WebSocketsUrl + "/echo"),
|
await webSocketsTransport.StartAsync(new Uri(_serverFixture.WebSocketsUrl + "/echo"),
|
||||||
TransferFormat.Binary).OrTimeout();
|
TransferFormat.Binary).OrTimeout();
|
||||||
await webSocketsTransport.StopAsync().OrTimeout();
|
await webSocketsTransport.StopAsync().OrTimeout();
|
||||||
|
|
@ -83,7 +83,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var webSocketsTransport = new WebSocketsTransport(httpOptions: null, loggerFactory: loggerFactory);
|
var webSocketsTransport = new WebSocketsTransport(httpConnectionOptions: null, loggerFactory: loggerFactory);
|
||||||
await webSocketsTransport.StartAsync(new Uri(_serverFixture.WebSocketsUrl + "/httpheader"),
|
await webSocketsTransport.StartAsync(new Uri(_serverFixture.WebSocketsUrl + "/httpheader"),
|
||||||
TransferFormat.Binary).OrTimeout();
|
TransferFormat.Binary).OrTimeout();
|
||||||
|
|
||||||
|
|
@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var webSocketsTransport = new WebSocketsTransport(httpOptions: null, loggerFactory: loggerFactory);
|
var webSocketsTransport = new WebSocketsTransport(httpConnectionOptions: null, loggerFactory: loggerFactory);
|
||||||
await webSocketsTransport.StartAsync(new Uri(_serverFixture.WebSocketsUrl + "/httpheader"),
|
await webSocketsTransport.StartAsync(new Uri(_serverFixture.WebSocketsUrl + "/httpheader"),
|
||||||
TransferFormat.Binary).OrTimeout();
|
TransferFormat.Binary).OrTimeout();
|
||||||
|
|
||||||
|
|
@ -134,7 +134,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var webSocketsTransport = new WebSocketsTransport(httpOptions: null, loggerFactory: loggerFactory);
|
var webSocketsTransport = new WebSocketsTransport(httpConnectionOptions: null, loggerFactory: loggerFactory);
|
||||||
await webSocketsTransport.StartAsync(new Uri(_serverFixture.WebSocketsUrl + "/echo"),
|
await webSocketsTransport.StartAsync(new Uri(_serverFixture.WebSocketsUrl + "/echo"),
|
||||||
TransferFormat.Binary);
|
TransferFormat.Binary);
|
||||||
webSocketsTransport.Output.Complete();
|
webSocketsTransport.Output.Complete();
|
||||||
|
|
@ -150,7 +150,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var webSocketsTransport = new WebSocketsTransport(httpOptions: null, loggerFactory: loggerFactory);
|
var webSocketsTransport = new WebSocketsTransport(httpConnectionOptions: null, loggerFactory: loggerFactory);
|
||||||
await webSocketsTransport.StartAsync(new Uri(_serverFixture.WebSocketsUrl + "/echoAndClose"), transferFormat);
|
await webSocketsTransport.StartAsync(new Uri(_serverFixture.WebSocketsUrl + "/echoAndClose"), transferFormat);
|
||||||
|
|
||||||
await webSocketsTransport.Output.WriteAsync(new byte[] { 0x42 });
|
await webSocketsTransport.Output.WriteAsync(new byte[] { 0x42 });
|
||||||
|
|
@ -172,7 +172,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var webSocketsTransport = new WebSocketsTransport(httpOptions: null, loggerFactory: loggerFactory);
|
var webSocketsTransport = new WebSocketsTransport(httpConnectionOptions: null, loggerFactory: loggerFactory);
|
||||||
|
|
||||||
await webSocketsTransport.StartAsync(new Uri(_serverFixture.WebSocketsUrl + "/echo"),
|
await webSocketsTransport.StartAsync(new Uri(_serverFixture.WebSocketsUrl + "/echo"),
|
||||||
transferFormat).OrTimeout();
|
transferFormat).OrTimeout();
|
||||||
|
|
@ -190,7 +190,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
{
|
{
|
||||||
using (StartLog(out var loggerFactory))
|
using (StartLog(out var loggerFactory))
|
||||||
{
|
{
|
||||||
var webSocketsTransport = new WebSocketsTransport(httpOptions: null, loggerFactory: loggerFactory);
|
var webSocketsTransport = new WebSocketsTransport(httpConnectionOptions: null, loggerFactory: loggerFactory);
|
||||||
var exception = await Assert.ThrowsAsync<ArgumentException>(() =>
|
var exception = await Assert.ThrowsAsync<ArgumentException>(() =>
|
||||||
webSocketsTransport.StartAsync(new Uri("http://fakeuri.org"), transferFormat));
|
webSocketsTransport.StartAsync(new Uri("http://fakeuri.org"), transferFormat));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue