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());
            }
예제 #2
0
        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());
                    });
                }
            }
예제 #8
0
 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);
                    });
                }
            }
예제 #16
0
 public Task ConnectionCannotBeStartedIfNoCommonTransportsBetweenClientAndServer(TransportType serverTransports)
 {
     return(RunInvalidNegotiateResponseTest <InvalidOperationException>(ResponseUtils.CreateNegotiationContent(transportTypes: serverTransports), "No requested transports available on the server."));
 }
예제 #17
0
        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."));
 }
예제 #19
0
        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());
                    }
                });
            }
        }
예제 #20
0
        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());
                    }
                });
            }
        }