public async Task CorrectlyHandlesQueryStringWhenAppendingNegotiateToUrl(string requestedUrl, string expectedNegotiate) { var testHttpHandler = new TestHttpMessageHandler(autoNegotiate: false); var negotiateUrlTcs = new TaskCompletionSource <string>(); testHttpHandler.OnLongPoll(cancellationToken => ResponseUtils.CreateResponse(HttpStatusCode.NoContent)); testHttpHandler.OnLongPollDelete(cancellationToken => ResponseUtils.CreateResponse(HttpStatusCode.NoContent)); testHttpHandler.OnNegotiate((request, cancellationToken) => { negotiateUrlTcs.TrySetResult(request.RequestUri.ToString()); return(ResponseUtils.CreateResponse(HttpStatusCode.OK, ResponseUtils.CreateNegotiationContent())); }); using (var noErrorScope = new VerifyNoErrorsScope()) { await WithConnectionAsync( CreateConnection(testHttpHandler, url : requestedUrl, loggerFactory : noErrorScope.LoggerFactory), async (connection) => { await connection.StartAsync().DefaultTimeout(); }); } Assert.Equal(expectedNegotiate, await negotiateUrlTcs.Task.DefaultTimeout()); }
public async Task HttpOptionsSetOntoHttpClientHandler() { var testHttpHandler = TestHttpMessageHandler.CreateDefault(); var negotiateUrlTcs = new TaskCompletionSource <string>(); testHttpHandler.OnNegotiate((request, cancellationToken) => { negotiateUrlTcs.TrySetResult(request.RequestUri.ToString()); return(ResponseUtils.CreateResponse(HttpStatusCode.OK, ResponseUtils.CreateNegotiationContent())); }); HttpClientHandler httpClientHandler = null; var httpOptions = new HttpConnectionOptions(); httpOptions.Url = new Uri("http://fakeuri.org/"); httpOptions.HttpMessageHandlerFactory = inner => { httpClientHandler = (HttpClientHandler)inner; return(testHttpHandler); }; httpOptions.Cookies.Add(new Cookie("Name", "Value", string.Empty, "fakeuri.org")); var clientCertificate = new X509Certificate(Array.Empty <byte>()); httpOptions.ClientCertificates.Add(clientCertificate); httpOptions.UseDefaultCredentials = false; httpOptions.Credentials = Mock.Of <ICredentials>(); httpOptions.Proxy = Mock.Of <IWebProxy>(); httpOptions.Transports = HttpTransportType.LongPolling; await WithConnectionAsync( CreateConnection(httpOptions), async (connection) => { await connection.StartAsync().DefaultTimeout(); }); Assert.NotNull(httpClientHandler); Assert.Equal(1, httpClientHandler.CookieContainer.Count); Assert.Single(httpClientHandler.ClientCertificates); Assert.Same(clientCertificate, httpClientHandler.ClientCertificates[0]); Assert.False(httpClientHandler.UseDefaultCredentials); Assert.Same(httpOptions.Proxy, httpClientHandler.Proxy); Assert.Same(httpOptions.Credentials, httpClientHandler.Credentials); }
public async Task HttpConnectionSetsUserAgentOnAllRequests(HttpTransportType transportType) { var testHttpHandler = new TestHttpMessageHandler(autoNegotiate: false); var requestsExecuted = false; testHttpHandler.OnNegotiate((_, cancellationToken) => { return(ResponseUtils.CreateResponse(HttpStatusCode.OK, ResponseUtils.CreateNegotiationContent())); }); testHttpHandler.OnRequest(async(request, next, token) => { var userAgentHeader = request.Headers.UserAgent.ToString(); Assert.NotNull(userAgentHeader); Assert.StartsWith("Microsoft SignalR/", userAgentHeader); // user agent version should come from version embedded in assembly metadata var assemblyVersion = typeof(Constants) .Assembly .GetCustomAttribute <AssemblyInformationalVersionAttribute>(); Assert.Contains(assemblyVersion.InformationalVersion, userAgentHeader); requestsExecuted = true; return(await next()); }); testHttpHandler.OnRequest((request, next, token) => { return(Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.NoContent))); }); await WithConnectionAsync( CreateConnection(testHttpHandler, transportType : transportType), async (connection) => { await connection.StartAsync().DefaultTimeout(); await connection.Transport.Output.WriteAsync(Encoding.UTF8.GetBytes("Hello World")); }); // Fail safe in case the code is modified and some requests don't execute as a result Assert.True(requestsExecuted); }
public async Task HttpConnectionSetsAccessTokenOnAllRequests(HttpTransportType transportType) { var testHttpHandler = new TestHttpMessageHandler(autoNegotiate: false); var requestsExecuted = false; var callCount = 0; testHttpHandler.OnNegotiate((_, cancellationToken) => { return(ResponseUtils.CreateResponse(HttpStatusCode.OK, ResponseUtils.CreateNegotiationContent())); }); testHttpHandler.OnRequest(async(request, next, token) => { Assert.Equal("Bearer", request.Headers.Authorization.Scheme); // Call count increments with each call and is used as the access token Assert.Equal(callCount.ToString(CultureInfo.InvariantCulture), request.Headers.Authorization.Parameter); requestsExecuted = true; return(await next()); }); testHttpHandler.OnRequest((request, next, token) => { return(Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.NoContent))); }); Task <string> AccessTokenProvider() { callCount++; return(Task.FromResult(callCount.ToString(CultureInfo.InvariantCulture))); } await WithConnectionAsync( CreateConnection(testHttpHandler, transportType : transportType, accessTokenProvider : AccessTokenProvider), async (connection) => { await connection.StartAsync().DefaultTimeout(); await connection.Transport.Output.WriteAsync(Encoding.UTF8.GetBytes("Hello world 1")); await connection.Transport.Output.WriteAsync(Encoding.UTF8.GetBytes("Hello world 2")); }); // Fail safe in case the code is modified and some requests don't execute as a result Assert.True(requestsExecuted); }
public async Task CorrectlyHandlesQueryStringWhenAppendingNegotiateToUrl(string requestedUrl, string expectedNegotiate) { var testHttpHandler = new TestHttpMessageHandler(autoNegotiate: false); var negotiateUrlTcs = new TaskCompletionSource <string>(); testHttpHandler.OnLongPoll(cancellationToken => ResponseUtils.CreateResponse(HttpStatusCode.NoContent)); testHttpHandler.OnNegotiate((request, cancellationToken) => { negotiateUrlTcs.TrySetResult(request.RequestUri.ToString()); return(ResponseUtils.CreateResponse(HttpStatusCode.OK, ResponseUtils.CreateNegotiationContent())); }); await WithConnectionAsync( CreateConnection(testHttpHandler, url : requestedUrl), async (connection, closed) => { await connection.StartAsync(TransferFormat.Text).OrTimeout(); }); Assert.Equal(expectedNegotiate, await negotiateUrlTcs.Task.OrTimeout()); }
public async Task HttpConnectionSetsRequestedWithOnAllRequests(HttpTransportType transportType) { var testHttpHandler = new TestHttpMessageHandler(autoNegotiate: false); var requestsExecuted = false; testHttpHandler.OnNegotiate((_, cancellationToken) => { return(ResponseUtils.CreateResponse(HttpStatusCode.OK, ResponseUtils.CreateNegotiationContent())); }); testHttpHandler.OnRequest(async(request, next, token) => { var requestedWithHeader = request.Headers.GetValues(HeaderNames.XRequestedWith); var requestedWithValue = Assert.Single(requestedWithHeader); Assert.Equal("XMLHttpRequest", requestedWithValue); requestsExecuted = true; return(await next()); }); testHttpHandler.OnRequest((request, next, token) => { return(Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.NoContent))); }); await WithConnectionAsync( CreateConnection(testHttpHandler, transportType : transportType), async (connection) => { await connection.StartAsync().DefaultTimeout(); await connection.Transport.Output.WriteAsync(Encoding.UTF8.GetBytes("Hello World")); }); // Fail safe in case the code is modified and some requests don't execute as a result Assert.True(requestsExecuted); }
public async Task LongPollingTransportCanBeCanceled() { using (StartVerifiableLog()) { var cts = new CancellationTokenSource(); var httpHandler = new TestHttpMessageHandler(autoNegotiate: false); httpHandler.OnNegotiate((request, cancellationToken) => { // Cancel token so that the first request poll will throw cts.Cancel(); return(ResponseUtils.CreateResponse(HttpStatusCode.OK, ResponseUtils.CreateNegotiationContent())); }); var lp = new LongPollingTransport(new HttpClient(httpHandler)); await WithConnectionAsync( CreateConnection(httpHandler, transport : lp, transportType : HttpTransportType.LongPolling), async (connection) => { var ex = await Assert.ThrowsAsync <AggregateException>(async() => await connection.StartAsync(cts.Token).OrTimeout()); }); } }
public Task StartThrowsFormatExceptionIfNegotiationResponseHasNoConnectionId() { return(RunInvalidNegotiateResponseTest <FormatException>(ResponseUtils.CreateNegotiationContent(connectionId: null), "Invalid connection id returned in negotiation response.")); }
public Task ConnectionCannotBeStartedIfNoTransportProvidedByServer() { return(RunInvalidNegotiateResponseTest <NoTransportSupportedException>(ResponseUtils.CreateNegotiationContent(transportTypes: HttpTransportType.None), "None of the transports supported by the client are supported by the server.")); }
public Task ConnectionCannotBeStartedIfNoCommonTransportsBetweenClientAndServer() { return(RunInvalidNegotiateResponseTest <AggregateException>(ResponseUtils.CreateNegotiationContent(transportTypes: HttpTransportType.ServerSentEvents), "Unable to connect to the server with any of the available transports. (ServerSentEvents failed: The transport is disabled by the client.)")); }
public Task NegotiateResponseWithNegotiateVersionRequiresConnectionToken() { return(RunInvalidNegotiateResponseTest <InvalidDataException>(ResponseUtils.CreateNegotiationContent(negotiateVersion: 1, connectionToken: null), "Invalid negotiation response received.")); }
public Task StartThrowsFormatExceptionIfNegotiationResponseHasNoConnectionId() { return(RunInvalidNegotiateResponseTest <FormatException>(ResponseUtils.CreateNegotiationContent(connectionId: string.Empty), "Invalid connection id.")); }
public Task ConnectionCannotBeStartedIfNoCommonTransportsBetweenClientAndServer(HttpTransportType serverTransports) { return(RunInvalidNegotiateResponseTest <InvalidOperationException>(ResponseUtils.CreateNegotiationContent(transportTypes: serverTransports), "Unable to connect to the server with any of the available transports.")); }
public Task StartThrowsFormatExceptionIfNegotiationResponseHasNoTransports() { return(RunInvalidNegotiateResponseTest <InvalidOperationException>(ResponseUtils.CreateNegotiationContent(transportTypes: 0), "Unable to connect to the server with any of the available transports.")); }
public async Task HttpConnectionSetsInherentKeepAliveFeature(HttpTransportType transportType, bool expectedValue) { using (StartVerifiableLog()) { var testHttpHandler = new TestHttpMessageHandler(autoNegotiate: false); testHttpHandler.OnNegotiate((_, cancellationToken) => ResponseUtils.CreateResponse(HttpStatusCode.OK, ResponseUtils.CreateNegotiationContent())); testHttpHandler.OnRequest((request, next, token) => Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.NoContent))); await WithConnectionAsync( CreateConnection(testHttpHandler, transportType : transportType, loggerFactory : LoggerFactory), async (connection) => { await connection.StartAsync().DefaultTimeout(); var feature = connection.Features.Get <IConnectionInherentKeepAliveFeature>(); Assert.NotNull(feature); Assert.Equal(expectedValue, feature.HasInherentKeepAlive); }); } }
public Task ConnectionCannotBeStartedIfNoCommonTransportsBetweenClientAndServer(TransportType serverTransports) { return(RunInvalidNegotiateResponseTest <InvalidOperationException>(ResponseUtils.CreateNegotiationContent(transportTypes: serverTransports), "No requested transports available on the server.")); }
public TestHttpMessageHandler(bool autoNegotiate = true) { _handler = (request, cancellationToken) => BaseHandler(request, cancellationToken); if (autoNegotiate) { OnNegotiate((_, cancellationToken) => ResponseUtils.CreateResponse(HttpStatusCode.OK, ResponseUtils.CreateNegotiationContent())); } }
public Task StartThrowsFormatExceptionIfNegotiationResponseHasNoTransports() { return(RunInvalidNegotiateResponseTest <FormatException>(ResponseUtils.CreateNegotiationContent(transportTypes: null), "No transports returned in negotiation response.")); }
public TestHttpMessageHandler(ILoggerFactory loggerFactory, bool autoNegotiate = true, bool handleFirstPoll = true) { _logger = loggerFactory?.CreateLogger <TestHttpMessageHandler>() ?? NullLoggerFactory.Instance.CreateLogger <TestHttpMessageHandler>(); if (autoNegotiate) { OnNegotiate((_, cancellationToken) => ResponseUtils.CreateResponse(HttpStatusCode.OK, ResponseUtils.CreateNegotiationContent())); } if (handleFirstPoll) { var firstPoll = true; OnRequest(async(request, next, cancellationToken) => { cancellationToken.ThrowIfCancellationRequested(); if (ResponseUtils.IsLongPollRequest(request) && firstPoll) { firstPoll = false; return(ResponseUtils.CreateResponse(HttpStatusCode.OK)); } else { return(await next()); } }); } }
public TestHttpMessageHandler(bool autoNegotiate = true, bool handleFirstPoll = true) { if (autoNegotiate) { OnNegotiate((_, cancellationToken) => ResponseUtils.CreateResponse(HttpStatusCode.OK, ResponseUtils.CreateNegotiationContent())); } if (handleFirstPoll) { var firstPoll = true; OnRequest(async(request, next, cancellationToken) => { if (ResponseUtils.IsLongPollRequest(request) && firstPoll) { firstPoll = false; return(ResponseUtils.CreateResponse(HttpStatusCode.OK)); } else { return(await next()); } }); } }