public static TestHttpMessageHandler CreateDefault()
        {
            var testHttpMessageHandler = new TestHttpMessageHandler();

            var deleteCts = new CancellationTokenSource();

            testHttpMessageHandler.OnSocketSend((_, __) => ResponseUtils.CreateResponse(HttpStatusCode.Accepted));
            testHttpMessageHandler.OnLongPoll(async cancellationToken =>
            {
                var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, deleteCts.Token);

                // Just block until canceled
                var tcs = new TaskCompletionSource <object>();
                using (cts.Token.Register(() => tcs.TrySetResult(null)))
                {
                    await tcs.Task;
                }
                return(ResponseUtils.CreateResponse(HttpStatusCode.NoContent));
            });
            testHttpMessageHandler.OnRequest((request, next, cancellationToken) =>
            {
                if (request.Method.Equals(HttpMethod.Delete) && request.RequestUri.PathAndQuery.Contains("&id="))
                {
                    deleteCts.Cancel();
                    return(Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.Accepted)));
                }

                return(next());
            });

            return(testHttpMessageHandler);
        }
            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 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 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 ConnectionIsDisposedIfItFailsToStartAsync()
        {
            var testHandler = new TestHttpMessageHandler(autoNegotiate: false, handleFirstPoll: false);

            testHandler.OnRequest((req, next, ct) => Task.FromException <HttpResponseMessage>(new Exception("BOOM")));

            var factory = new HttpConnectionFactory(Options.Create(new HttpConnectionOptions()
            {
                Url = new Uri("http://example.com"),
                HttpMessageHandlerFactory = _ => testHandler
            }), NullLoggerFactory.Instance);

            // We don't care about the specific exception
            await Assert.ThrowsAnyAsync <Exception>(() => factory.ConnectAsync(TransferFormat.Text));

            // We care that the handler (and by extension the client) was disposed
            Assert.True(testHandler.Disposed);
        }
            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);
                    });
                }
            }