Exemple #1
0
        public async Task LongPollingTransportShutsDownWhenChannelIsClosed()
        {
            var mockHttpHandler = new Mock <HttpMessageHandler>();

            mockHttpHandler.Protected()
            .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
            .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
            {
                await Task.Yield();
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
            });

            using (var httpClient = new HttpClient(mockHttpHandler.Object))
            {
                var longPollingTransport = new LongPollingTransport(httpClient);
                try
                {
                    await longPollingTransport.StartAsync(new Uri("http://fakeuri.org"), TransferFormat.Binary);

                    longPollingTransport.Output.Complete();

                    await longPollingTransport.Running.OrTimeout();

                    await longPollingTransport.Input.ReadAllAsync().OrTimeout();
                }
                finally
                {
                    await longPollingTransport.StopAsync();
                }
            }
        }
Exemple #2
0
        public async Task LongPollingTransportSetsTransferFormat(TransferFormat transferFormat)
        {
            var mockHttpHandler = new Mock <HttpMessageHandler>();

            mockHttpHandler.Protected()
            .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
            .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
            {
                await Task.Yield();
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
            });

            using (var httpClient = new HttpClient(mockHttpHandler.Object))
            {
                var longPollingTransport = new LongPollingTransport(httpClient);

                try
                {
                    var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);

                    await longPollingTransport.StartAsync(new Uri("http://fakeuri.org"), pair.Application, transferFormat, connection : new TestConnection());
                }
                finally
                {
                    await longPollingTransport.StopAsync();
                }
            }
        }
        public void SendSetsContentTypeAndWritesSerializedResponse()
        {
            var obj      = new { A = 1 };
            var context  = new Mock <HttpContextBase>();
            var request  = new Mock <HttpRequestBase>();
            var response = new Mock <HttpResponseBase>();

            request.Setup(m => m.Path).Returns("/foo/");
            var qs = new NameValueCollection();

            qs["connectionId"] = "1";
            request.Setup(m => m.QueryString).Returns(qs);
            context.Setup(m => m.Response).Returns(response.Object);
            context.Setup(m => m.Request).Returns(request.Object);
            var json = new Mock <IJsonSerializer>();

            json.Setup(m => m.Stringify(obj)).Returns("A=1");
            var heartBeat  = new Mock <ITransportHeartBeat>();
            var transport  = new LongPollingTransport(context.Object, json.Object, heartBeat.Object);
            var connection = new Mock <IConnection>();

            transport.Send(obj);

            response.VerifySet(m => m.ContentType = "application/json");
            response.Verify(m => m.Write("A=1"), Times.Once());
        }
    public async Task LongPollingTransportStopsWhenPollReceives204()
    {
        var mockHttpHandler = new Mock <HttpMessageHandler>();

        mockHttpHandler.Protected()
        .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
        .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
        {
            await Task.Yield();
            return(ResponseUtils.CreateResponse(HttpStatusCode.NoContent));
        });

        using (var httpClient = new HttpClient(mockHttpHandler.Object))
        {
            var longPollingTransport = new LongPollingTransport(httpClient);
            try
            {
                await longPollingTransport.StartAsync(TestUri, TransferFormat.Binary);

                await longPollingTransport.Running.DefaultTimeout();

                Assert.True(longPollingTransport.Input.TryRead(out var result));
                Assert.True(result.IsCompleted);
                longPollingTransport.Input.AdvanceTo(result.Buffer.End);
            }
            finally
            {
                await longPollingTransport.StopAsync();
            }
        }
    }
Exemple #5
0
        public async Task LongPollingTransportSetsTransferMode(TransferMode transferMode)
        {
            var mockHttpHandler = new Mock <HttpMessageHandler>();

            mockHttpHandler.Protected()
            .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
            .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
            {
                await Task.Yield();
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
            });

            using (var httpClient = new HttpClient(mockHttpHandler.Object))
            {
                var longPollingTransport = new LongPollingTransport(httpClient);

                try
                {
                    var connectionToTransport = Channel.CreateUnbounded <SendMessage>();
                    var transportToConnection = Channel.CreateUnbounded <byte[]>();
                    var channelConnection     = new ChannelConnection <SendMessage, byte[]>(connectionToTransport, transportToConnection);

                    Assert.Null(longPollingTransport.Mode);
                    await longPollingTransport.StartAsync(new Uri("http://fakeuri.org"), channelConnection, transferMode, connectionId : string.Empty, connection : new TestConnection());

                    Assert.Equal(transferMode, longPollingTransport.Mode);
                }
                finally
                {
                    await longPollingTransport.StopAsync();
                }
            }
        }
Exemple #6
0
        public async Task LongPollingTransportStopsWhenPollReceives204()
        {
            var mockHttpHandler = new Mock <HttpMessageHandler>();

            mockHttpHandler.Protected()
            .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
            .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
            {
                await Task.Yield();
                return(ResponseUtils.CreateResponse(HttpStatusCode.NoContent));
            });

            using (var httpClient = new HttpClient(mockHttpHandler.Object))
            {
                var longPollingTransport = new LongPollingTransport(httpClient);
                try
                {
                    var connectionToTransport = Channel.CreateUnbounded <SendMessage>();
                    var transportToConnection = Channel.CreateUnbounded <byte[]>();
                    var channelConnection     = ChannelConnection.Create(connectionToTransport, transportToConnection);
                    await longPollingTransport.StartAsync(new Uri("http://fakeuri.org"), channelConnection, TransferMode.Binary, connectionId : string.Empty, connection : new TestConnection());

                    await longPollingTransport.Running.OrTimeout();

                    Assert.True(transportToConnection.Reader.Completion.IsCompleted);
                }
                finally
                {
                    await longPollingTransport.StopAsync();
                }
            }
        }
    public async Task LongPollingTransportStopsPollAndSendLoopsWhenTransportStopped()
    {
        var mockHttpHandler = new Mock <HttpMessageHandler>();

        mockHttpHandler.Protected()
        .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
        .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
        {
            await Task.Yield();
            return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
        });

        Task transportActiveTask;

        using (var httpClient = new HttpClient(mockHttpHandler.Object))
        {
            var longPollingTransport = new LongPollingTransport(httpClient);

            try
            {
                await longPollingTransport.StartAsync(TestUri, TransferFormat.Binary);

                transportActiveTask = longPollingTransport.Running;

                Assert.False(transportActiveTask.IsCompleted);
            }
            finally
            {
                await longPollingTransport.StopAsync();
            }

            await transportActiveTask.DefaultTimeout();
        }
    }
        public void ConnectRequestRaisesConnectEvent()
        {
            var context = new Mock <HttpContextBase>();
            var request = new Mock <HttpRequestBase>();

            request.Setup(m => m.Path).Returns("/foo/connect");
            var qs = new NameValueCollection();

            qs["connectionId"] = "1";
            request.Setup(m => m.QueryString).Returns(qs);
            context.Setup(m => m.Request).Returns(request.Object);
            var  json        = new Mock <IJsonSerializer>();
            var  heartBeat   = new Mock <ITransportHeartBeat>();
            var  transport   = new LongPollingTransport(context.Object, json.Object, heartBeat.Object);
            var  connection  = new Mock <IConnection>();
            bool eventRaised = false;

            transport.Connected += () =>
            {
                eventRaised = true;
            };

            transport.ProcessRequest(connection.Object);
            Assert.True(eventRaised);
        }
    public async Task LongPollingTransportSetsTransferFormat(TransferFormat transferFormat)
    {
        var mockHttpHandler = new Mock <HttpMessageHandler>();

        mockHttpHandler.Protected()
        .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
        .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
        {
            await Task.Yield();
            return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
        });

        using (var httpClient = new HttpClient(mockHttpHandler.Object))
        {
            var longPollingTransport = new LongPollingTransport(httpClient);

            try
            {
                await longPollingTransport.StartAsync(TestUri, transferFormat);
            }
            finally
            {
                await longPollingTransport.StopAsync();
            }
        }
    }
        public async Task TransportIsStoppedWhenConnectionIsStopped()
        {
            var mockHttpHandler = new Mock <HttpMessageHandler>();

            mockHttpHandler.Protected()
            .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
            .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
            {
                await Task.Yield();

                return(request.Method == HttpMethod.Options
                        ? ResponseUtils.CreateResponse(HttpStatusCode.OK, ResponseUtils.CreateNegotiationResponse())
                        : ResponseUtils.CreateResponse(HttpStatusCode.OK));
            });

            using (var httpClient = new HttpClient(mockHttpHandler.Object))
            {
                var longPollingTransport = new LongPollingTransport(httpClient, new LoggerFactory());
                var connection           = new HttpConnection(new Uri("http://fakeuri.org/"), new TestTransportFactory(longPollingTransport), loggerFactory: null, httpMessageHandler: mockHttpHandler.Object);

                try
                {
                    await connection.StartAsync();

                    Assert.False(longPollingTransport.Running.IsCompleted);
                }
                finally
                {
                    await connection.DisposeAsync();
                }

                await longPollingTransport.Running.OrTimeout();
            }
        }
Exemple #11
0
        public async Task LongPollingTransportStopsWhenPollRequestFails()
        {
            var mockHttpHandler = new Mock <HttpMessageHandler>();

            mockHttpHandler.Protected()
            .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
            .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
            {
                await Task.Yield();
                return(ResponseUtils.CreateResponse(HttpStatusCode.InternalServerError));
            });

            using (var httpClient = new HttpClient(mockHttpHandler.Object))
            {
                var longPollingTransport = new LongPollingTransport(httpClient);
                try
                {
                    var connectionToTransport = Channel.CreateUnbounded <SendMessage>();
                    var transportToConnection = Channel.CreateUnbounded <byte[]>();
                    var channelConnection     = new ChannelConnection <SendMessage, byte[]>(connectionToTransport, transportToConnection);
                    await longPollingTransport.StartAsync(new Uri("http://fakeuri.org"), channelConnection, TransferMode.Binary, connectionId : string.Empty);

                    var exception =
                        await Assert.ThrowsAsync <HttpRequestException>(async() => await transportToConnection.Reader.Completion.OrTimeout());

                    Assert.Contains(" 500 ", exception.Message);
                }
                finally
                {
                    await longPollingTransport.StopAsync();
                }
            }
        }
    public async Task LongPollingTransportShutsDownImmediatelyEvenIfServerDoesntCompletePoll()
    {
        var mockHttpHandler = new Mock <HttpMessageHandler>();

        mockHttpHandler.Protected()
        .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
        .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
        {
            await Task.Yield();
            return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
        });

        using (var httpClient = new HttpClient(mockHttpHandler.Object))
        {
            var longPollingTransport = new LongPollingTransport(httpClient);

            try
            {
                await longPollingTransport.StartAsync(TestUri, TransferFormat.Binary);

                longPollingTransport.Output.Complete();

                await longPollingTransport.Running.DefaultTimeout();

                await longPollingTransport.Input.ReadAllAsync().DefaultTimeout();
            }
            finally
            {
                await longPollingTransport.StopAsync();
            }
        }
    }
        public async Task LongPollingTransportStopsPollAndSendLoopsWhenTransportStopped()
        {
            var mockHttpHandler = new Mock <HttpMessageHandler>();

            mockHttpHandler.Protected()
            .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
            .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
            {
                await Task.Yield();
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
            });

            Task transportActiveTask;

            using (var httpClient = new HttpClient(mockHttpHandler.Object))
            {
                var longPollingTransport = new LongPollingTransport(httpClient);

                try
                {
                    var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
                    await longPollingTransport.StartAsync(new Uri("http://fakeuri.org"), pair.Application, TransferMode.Binary, connection : new TestConnection());

                    transportActiveTask = longPollingTransport.Running;

                    Assert.False(transportActiveTask.IsCompleted);
                }
                finally
                {
                    await longPollingTransport.StopAsync();
                }

                await transportActiveTask.OrTimeout();
            }
        }
        public async Task LongPollingTransportStopsWhenPollReceives204()
        {
            var mockHttpHandler = new Mock <HttpMessageHandler>();

            mockHttpHandler.Protected()
            .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
            .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
            {
                await Task.Yield();
                return(ResponseUtils.CreateResponse(HttpStatusCode.NoContent));
            });

            using (var httpClient = new HttpClient(mockHttpHandler.Object))
            {
                var longPollingTransport = new LongPollingTransport(httpClient);
                try
                {
                    var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
                    await longPollingTransport.StartAsync(new Uri("http://fakeuri.org"), pair.Application, TransferMode.Binary, connection : new TestConnection());

                    await longPollingTransport.Running.OrTimeout();

                    Assert.True(pair.Transport.Input.TryRead(out var result));
                    Assert.True(result.IsCompleted);
                    pair.Transport.Input.AdvanceTo(result.Buffer.End);
                }
                finally
                {
                    await longPollingTransport.StopAsync();
                }
            }
        }
Exemple #15
0
        public async Task MultipleFramesSentAsSingleResponse()
        {
            var channel = Channel.CreateUnbounded <byte[]>();
            var context = new DefaultHttpContext();

            var poll = new LongPollingTransport(CancellationToken.None, channel, connectionId: string.Empty, loggerFactory: new LoggerFactory());
            var ms   = new MemoryStream();

            context.Response.Body = ms;

            await channel.Out.WriteAsync(Encoding.UTF8.GetBytes("Hello"));

            await channel.Out.WriteAsync(Encoding.UTF8.GetBytes(" "));

            await channel.Out.WriteAsync(Encoding.UTF8.GetBytes("World"));

            Assert.True(channel.Out.TryComplete());

            await poll.ProcessRequestAsync(context, context.RequestAborted);

            Assert.Equal(200, context.Response.StatusCode);

            var payload = ms.ToArray();

            Assert.Equal("Hello World", Encoding.UTF8.GetString(payload));
        }
Exemple #16
0
        public async Task PollingLoopNotRestartedIfStartFails()
        {
            var disconnectCts = new CancellationTokenSource();

            var mockConnection = new Mock <Client.IConnection>();

            mockConnection.SetupGet(c => c.JsonSerializer).Returns(JsonSerializer.CreateDefault());
            mockConnection.Setup(c => c.TotalTransportConnectTimeout).Returns(TimeSpan.FromSeconds(500));
            mockConnection.SetupProperty(c => c.MessageId);

            var mockHttpClient = CreateFakeHttpClient((url, request, postData, isLongRunning) =>
                                                      Task.FromException <IResponse>(new InvalidOperationException("Request rejected")));

            mockHttpClient.Setup(
                m => m.Get(It.IsAny <string>(), It.IsAny <Action <Client.Http.IRequest> >(), It.IsAny <bool>()))
            .Returns <string, Action <Client.Http.IRequest>, bool>(
                (url, request, isLongRunning) => Task.FromResult(CreateResponse("{ \"Response\" : \"started\"}")));

            var longPollingTransport = new LongPollingTransport(mockHttpClient.Object);

            await Assert.ThrowsAsync <InvalidOperationException>(() =>
                                                                 longPollingTransport.Start(mockConnection.Object, string.Empty, disconnectCts.Token))
            .OrTimeout(TimeSpan.FromSeconds(15));

            // give it some time to settle
            await Task.Delay(1000);

            mockHttpClient
            .Verify(c => c.Post(It.Is <string>(url => url.StartsWith("poll?")), It.IsAny <Action <Client.Http.IRequest> >(),
                                It.IsAny <IDictionary <string, string> >(), It.IsAny <bool>()), Times.Never());
        }
        public void SendRequestRaisesOnReceived()
        {
            var context = new Mock <HttpContextBase>();
            var request = new Mock <HttpRequestBase>();

            request.Setup(m => m.Path).Returns("/foo/send");
            var form = new NameValueCollection();

            form["data"] = "some data";
            request.Setup(m => m.Form).Returns(form);
            context.Setup(m => m.Request).Returns(request.Object);
            var  json        = new Mock <IJsonStringifier>();
            var  heartBeat   = new Mock <ITransportHeartBeat>();
            var  transport   = new LongPollingTransport(context.Object, json.Object, heartBeat.Object);
            var  connection  = new Mock <IConnection>();
            bool eventRaised = false;

            transport.Received += data =>
            {
                eventRaised = true;
                Assert.Equal(data, "some data");
            };

            transport.ProcessRequest(connection.Object);
            Assert.True(eventRaised);
        }
    public async Task LongPollingTransportStartAsyncFailsIfFirstRequestFails()
    {
        var mockHttpHandler = new Mock <HttpMessageHandler>();

        mockHttpHandler.Protected()
        .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
        .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
        {
            await Task.Yield();
            return(ResponseUtils.CreateResponse(HttpStatusCode.InternalServerError));
        });

        using (var httpClient = new HttpClient(mockHttpHandler.Object))
        {
            var longPollingTransport = new LongPollingTransport(httpClient);
            try
            {
                var exception = await Assert.ThrowsAsync <HttpRequestException>(() => longPollingTransport.StartAsync(TestUri, TransferFormat.Binary));

                Assert.Contains(" 500 ", exception.Message);
            }
            finally
            {
                await longPollingTransport.StopAsync();
            }
        }
    }
Exemple #19
0
        public async Task MultipleFramesSentAsSingleResponse()
        {
            var pair       = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
            var connection = new DefaultConnectionContext("foo", pair.Transport, pair.Application);
            var context    = new DefaultHttpContext();

            var poll = new LongPollingTransport(CancellationToken.None, connection.Application.Input, loggerFactory: new LoggerFactory());
            var ms   = new MemoryStream();

            context.Response.Body = ms;

            await connection.Transport.Output.WriteAsync(Encoding.UTF8.GetBytes("Hello"));

            await connection.Transport.Output.WriteAsync(Encoding.UTF8.GetBytes(" "));

            await connection.Transport.Output.WriteAsync(Encoding.UTF8.GetBytes("World"));

            connection.Transport.Output.Complete();

            await poll.ProcessRequestAsync(context, context.RequestAborted).OrTimeout();

            Assert.Equal(200, context.Response.StatusCode);

            var payload = ms.ToArray();

            Assert.Equal("Hello World", Encoding.UTF8.GetString(payload));
        }
    public async Task LongPollingTransportSendsDeleteAfterPollEnds()
    {
        var sentRequests = new List <byte[]>();
        var pollTcs      = new TaskCompletionSource <HttpResponseMessage>();
        var deleteTcs    = new TaskCompletionSource();
        var firstPoll    = true;

        var mockHttpHandler = new Mock <HttpMessageHandler>();

        mockHttpHandler.Protected()
        .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
        .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
        {
            await Task.Yield();
            if (request.Method == HttpMethod.Post)
            {
                // Build a new request object, but convert the entire payload to string
                sentRequests.Add(await request.Content.ReadAsByteArrayAsync());
            }
            else if (request.Method == HttpMethod.Get)
            {
                // First poll completes immediately
                if (firstPoll)
                {
                    firstPoll = false;
                    return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
                }

                cancellationToken.Register(() => pollTcs.TrySetCanceled(cancellationToken));
                // This is the poll task
                return(await pollTcs.Task);
            }
            else if (request.Method == HttpMethod.Delete)
            {
                // The poll task should have been completed
                Assert.True(pollTcs.Task.IsCompleted);

                deleteTcs.TrySetResult();

                return(ResponseUtils.CreateResponse(HttpStatusCode.Accepted));
            }
            return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
        });

        using (var httpClient = new HttpClient(mockHttpHandler.Object))
        {
            var longPollingTransport = new LongPollingTransport(httpClient);

            // Start the transport
            await longPollingTransport.StartAsync(TestUri, TransferFormat.Binary);

            var task = longPollingTransport.StopAsync();

            await deleteTcs.Task.DefaultTimeout();

            await task.DefaultTimeout();
        }
    }
        public async Task LongPollingTransportSendsAvailableMessagesWhenTheyArrive()
        {
            var sentRequests = new List <byte[]>();
            var tcs          = new TaskCompletionSource <HttpResponseMessage>();

            var mockHttpHandler = new Mock <HttpMessageHandler>();

            mockHttpHandler.Protected()
            .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
            .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
            {
                await Task.Yield();
                if (request.Method == HttpMethod.Post)
                {
                    // Build a new request object, but convert the entire payload to string
                    sentRequests.Add(await request.Content.ReadAsByteArrayAsync());
                }
                else if (request.Method == HttpMethod.Get)
                {
                    cancellationToken.Register(() => tcs.TrySetCanceled(cancellationToken));
                    // This is the poll task
                    return(await tcs.Task);
                }
                else if (request.Method == HttpMethod.Delete)
                {
                    return(ResponseUtils.CreateResponse(HttpStatusCode.Accepted));
                }
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
            });

            using (var httpClient = new HttpClient(mockHttpHandler.Object))
            {
                var longPollingTransport = new LongPollingTransport(httpClient);

                try
                {
                    // Start the transport
                    await longPollingTransport.StartAsync(TestUri, TransferFormat.Binary);

                    longPollingTransport.Output.Write(Encoding.UTF8.GetBytes("Hello"));
                    longPollingTransport.Output.Write(Encoding.UTF8.GetBytes("World"));
                    await longPollingTransport.Output.FlushAsync();

                    longPollingTransport.Output.Complete();

                    await longPollingTransport.Running.OrTimeout();

                    await longPollingTransport.Input.ReadAllAsync();

                    Assert.Single(sentRequests);
                    Assert.Equal(new[] { (byte)'H', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)'W', (byte)'o', (byte)'r', (byte)'l', (byte)'d' }, sentRequests[0]);
                }
                finally
                {
                    await longPollingTransport.StopAsync();
                }
            }
        }
Exemple #22
0
        public async Task LongPollingTransportResponseWithNoContentDoesNotStopPoll()
        {
            int requests        = 0;
            var mockHttpHandler = new Mock <HttpMessageHandler>();

            mockHttpHandler.Protected()
            .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
            .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
            {
                await Task.Yield();

                if (requests == 0)
                {
                    requests++;
                    return(ResponseUtils.CreateResponse(HttpStatusCode.OK, "Hello"));
                }
                else if (requests == 1)
                {
                    requests++;
                    // Time out
                    return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
                }
                else if (requests == 2)
                {
                    requests++;
                    return(ResponseUtils.CreateResponse(HttpStatusCode.OK, "World"));
                }

                // Done
                return(ResponseUtils.CreateResponse(HttpStatusCode.NoContent));
            });

            using (var httpClient = new HttpClient(mockHttpHandler.Object))
            {
                var longPollingTransport = new LongPollingTransport(httpClient);
                try
                {
                    var connectionToTransport = Channel.CreateUnbounded <SendMessage>();
                    var transportToConnection = Channel.CreateUnbounded <byte[]>();
                    var channelConnection     = new ChannelConnection <SendMessage, byte[]>(connectionToTransport, transportToConnection);
                    await longPollingTransport.StartAsync(new Uri("http://fakeuri.org"), channelConnection, TransferMode.Binary, connectionId : string.Empty, connection : new TestConnection());

                    var data = await transportToConnection.Reader.ReadAllAsync().OrTimeout();

                    await longPollingTransport.Running.OrTimeout();

                    Assert.True(transportToConnection.Reader.Completion.IsCompleted);
                    Assert.Equal(2, data.Count);
                    Assert.Equal(Encoding.UTF8.GetBytes("Hello"), data[0]);
                    Assert.Equal(Encoding.UTF8.GetBytes("World"), data[1]);
                }
                finally
                {
                    await longPollingTransport.StopAsync();
                }
            }
        }
    public async Task LongPollingTransportDispatchesMessagesReceivedFromPoll()
    {
        var message1Payload = new[] { (byte)'H', (byte)'e', (byte)'l', (byte)'l', (byte)'o' };

        var requests        = 0;
        var mockHttpHandler = new Mock <HttpMessageHandler>();
        var sentRequests    = new List <HttpRequestMessage>();

        mockHttpHandler.Protected()
        .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
        .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
        {
            sentRequests.Add(request);

            await Task.Yield();

            if (requests == 0)
            {
                requests++;
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
            }
            else if (requests == 1)
            {
                requests++;
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, message1Payload));
            }

            return(ResponseUtils.CreateResponse(HttpStatusCode.NoContent));
        });

        using (var httpClient = new HttpClient(mockHttpHandler.Object))
        {
            var longPollingTransport = new LongPollingTransport(httpClient);
            try
            {
                // Start the transport
                await longPollingTransport.StartAsync(TestUri, TransferFormat.Binary);

                // Wait for the transport to finish
                await longPollingTransport.Running.DefaultTimeout();

                // Pull Messages out of the channel
                var message = await longPollingTransport.Input.ReadAllAsync();

                // Check the provided request
                Assert.Equal(3, sentRequests.Count);

                // Check the messages received
                Assert.Equal(message1Payload, message);
            }
            finally
            {
                await longPollingTransport.StopAsync();
            }
        }
    }
    public async Task LongPollingTransportResponseWithNoContentDoesNotStopPoll()
    {
        var requests        = 0;
        var mockHttpHandler = new Mock <HttpMessageHandler>();

        mockHttpHandler.Protected()
        .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
        .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
        {
            await Task.Yield();

            if (requests == 0)
            {
                requests++;
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
            }
            else if (requests == 1)
            {
                requests++;
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, "Hello"));
            }
            else if (requests == 2)
            {
                requests++;
                // Time out
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
            }
            else if (requests == 3)
            {
                requests++;
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, "World"));
            }

            // Done
            return(ResponseUtils.CreateResponse(HttpStatusCode.NoContent));
        });

        using (var httpClient = new HttpClient(mockHttpHandler.Object))
        {
            var longPollingTransport = new LongPollingTransport(httpClient);
            try
            {
                await longPollingTransport.StartAsync(TestUri, TransferFormat.Binary);

                var data = await longPollingTransport.Input.ReadAllAsync().DefaultTimeout();

                await longPollingTransport.Running.DefaultTimeout();

                Assert.Equal(Encoding.UTF8.GetBytes("HelloWorld"), data);
            }
            finally
            {
                await longPollingTransport.StopAsync();
            }
        }
    }
Exemple #25
0
        static void Main(string[] args)
        {
            Thread.Sleep(3000);

            var baseUrl = "http://localhost:5000/hubs/testHub";

            var loggerFactory = new LoggerFactory();

            loggerFactory.AddConsole()
            .AddDebug();

            var logger = loggerFactory.CreateLogger <Program>();

            var cts = new CancellationTokenSource();

            Console.CancelKeyPress += (sender, a) =>
            {
                a.Cancel = true;
                logger.LogInformation("Stopping loops...");
                cts.Cancel();
            };

            using (var httpClient = new HttpClient(new LoggingMessageHandler(loggerFactory, new HttpClientHandler())))
            {
                var transport  = new LongPollingTransport(httpClient, loggerFactory);
                var connection = new HubConnection(new Uri(baseUrl), new JsonNetInvocationAdapter(), loggerFactory);

                try
                {
                    logger.LogInformation("Connecting to {0}", baseUrl);
                    connection.StartAsync(transport, httpClient).GetAwaiter();
                    logger.LogInformation("Connected to {0}", baseUrl);

                    connection.On("echo", new[] { typeof(string) }, a =>
                    {
                        var message = (string)a[0];
                        logger.LogInformation("RECEIVED: " + message);
                    });

                    var result = connection.Invoke <string>("echo").GetAwaiter();

                    while (!cts.Token.IsCancellationRequested)
                    {
                        //var line = Console.ReadLine();
                        //logger.LogInformation("Sending: {0}", line);
                        //
                        //connection.Invoke<object>("Send", line).GetAwaiter();
                    }
                }
                finally
                {
                    connection.DisposeAsync().GetAwaiter();
                }
            }
        }
Exemple #26
0
        public async Task LongPollingTransportSendsAvailableMessagesWhenTheyArrive()
        {
            var sentRequests = new List <byte[]>();

            var mockHttpHandler = new Mock <HttpMessageHandler>();

            mockHttpHandler.Protected()
            .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
            .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
            {
                await Task.Yield();
                if (request.Method == HttpMethod.Post)
                {
                    // Build a new request object, but convert the entire payload to string
                    sentRequests.Add(await request.Content.ReadAsByteArrayAsync());
                }
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
            });

            using (var httpClient = new HttpClient(mockHttpHandler.Object))
            {
                var longPollingTransport = new LongPollingTransport(httpClient);
                try
                {
                    var connectionToTransport = Channel.CreateUnbounded <SendMessage>();
                    var transportToConnection = Channel.CreateUnbounded <byte[]>();
                    var channelConnection     = new ChannelConnection <SendMessage, byte[]>(connectionToTransport, transportToConnection);

                    var tcs1 = new TaskCompletionSource <object>();
                    var tcs2 = new TaskCompletionSource <object>();

                    // Pre-queue some messages
                    await connectionToTransport.Writer.WriteAsync(new SendMessage(Encoding.UTF8.GetBytes("Hello"), tcs1)).OrTimeout();

                    await connectionToTransport.Writer.WriteAsync(new SendMessage(Encoding.UTF8.GetBytes("World"), tcs2)).OrTimeout();

                    // Start the transport
                    await longPollingTransport.StartAsync(new Uri("http://fakeuri.org"), channelConnection, TransferMode.Binary, connectionId : string.Empty, connection : new TestConnection());

                    connectionToTransport.Writer.Complete();

                    await longPollingTransport.Running.OrTimeout();

                    await connectionToTransport.Reader.Completion.OrTimeout();

                    Assert.Single(sentRequests);
                    Assert.Equal(new byte[] { (byte)'H', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)'W', (byte)'o', (byte)'r', (byte)'l', (byte)'d' }, sentRequests[0]);
                }
                finally
                {
                    await longPollingTransport.StopAsync();
                }
            }
        }
Exemple #27
0
        public async Task LongPollingTransportDispatchesMessagesReceivedFromPoll()
        {
            var message1Payload = new byte[] { (byte)'H', (byte)'e', (byte)'l', (byte)'l', (byte)'o' };

            var firstCall       = true;
            var mockHttpHandler = new Mock <HttpMessageHandler>();
            var sentRequests    = new List <HttpRequestMessage>();

            mockHttpHandler.Protected()
            .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
            .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
            {
                sentRequests.Add(request);

                await Task.Yield();

                if (firstCall)
                {
                    firstCall = false;
                    return(ResponseUtils.CreateResponse(HttpStatusCode.OK, message1Payload));
                }

                return(ResponseUtils.CreateResponse(HttpStatusCode.NoContent));
            });

            using (var httpClient = new HttpClient(mockHttpHandler.Object))
            {
                var longPollingTransport = new LongPollingTransport(httpClient);
                try
                {
                    var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);

                    // Start the transport
                    await longPollingTransport.StartAsync(new Uri("http://fakeuri.org"), pair.Application, TransferFormat.Binary, connection : new TestConnection());

                    // Wait for the transport to finish
                    await longPollingTransport.Running.OrTimeout();

                    // Pull Messages out of the channel
                    var message = await pair.Transport.Input.ReadAllAsync();

                    // Check the provided request
                    Assert.Equal(2, sentRequests.Count);

                    // Check the messages received
                    Assert.Equal(message1Payload, message);
                }
                finally
                {
                    await longPollingTransport.StopAsync();
                }
            }
        }
Exemple #28
0
        public async Task Set204StatusCodeWhenChannelComplete()
        {
            var channel = Channel.CreateUnbounded <byte[]>();
            var context = new DefaultHttpContext();
            var poll    = new LongPollingTransport(CancellationToken.None, channel, connectionId: string.Empty, loggerFactory: new LoggerFactory());

            Assert.True(channel.Out.TryComplete());

            await poll.ProcessRequestAsync(context, context.RequestAborted);

            Assert.Equal(204, context.Response.StatusCode);
        }
    public async Task LongPollingTransportStopsWhenSendRequestFails()
    {
        var stopped         = false;
        var mockHttpHandler = new Mock <HttpMessageHandler>();

        mockHttpHandler.Protected()
        .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
        .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
        {
            await Task.Yield();
            switch (request.Method.Method)
            {
            case "DELETE":
                stopped = true;
                return(ResponseUtils.CreateResponse(HttpStatusCode.Accepted));

            case "GET" when stopped:
                return(ResponseUtils.CreateResponse(HttpStatusCode.NoContent));

            case "GET":
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK));

            case "POST":
                return(ResponseUtils.CreateResponse(HttpStatusCode.InternalServerError));

            default:
                throw new InvalidOperationException("Unexpected request");
            }
        });

        using (var httpClient = new HttpClient(mockHttpHandler.Object))
        {
            var longPollingTransport = new LongPollingTransport(httpClient);
            try
            {
                await longPollingTransport.StartAsync(TestUri, TransferFormat.Binary);

                await longPollingTransport.Output.WriteAsync(Encoding.UTF8.GetBytes("Hello World"));

                await longPollingTransport.Running.DefaultTimeout();

                var exception = await Assert.ThrowsAsync <HttpRequestException>(async() => await longPollingTransport.Input.ReadAllAsync().DefaultTimeout());

                Assert.Contains(" 500 ", exception.Message);

                Assert.True(stopped);
            }
            finally
            {
                await longPollingTransport.StopAsync();
            }
        }
    }
Exemple #30
0
        public async Task LongPollingDoesNotPollAfterTransportIsBeingStoppedMidRequest()
        {
            var disconnectCts = new CancellationTokenSource();

            var mockConnection = new Mock <Client.IConnection>();

            mockConnection.SetupGet(c => c.JsonSerializer).Returns(JsonSerializer.CreateDefault());
            mockConnection.Setup(c => c.TotalTransportConnectTimeout).Returns(TimeSpan.FromSeconds(10));
            mockConnection.SetupProperty(c => c.MessageId);

            var pollingTcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

            var mockHttpClient = CreateFakeHttpClient(
                (url, request, postData, isLongRunning) =>
            {
                var responseMessage = string.Empty;
                if (url.Contains("connect?"))
                {
                    responseMessage = "{\"C\":\"d-C6243495-A,0|B,0|C,1|D,0\",\"S\":1,\"M\":[]}";
                }
                else if (url.Contains("poll?"))
                {
                    pollingTcs.TrySetResult(null);

                    // stop polling loop
                    disconnectCts.Cancel();
                }

                return(Task.FromResult(CreateResponse(responseMessage)));
            });

            var longPollingTransport = new LongPollingTransport(mockHttpClient.Object);

            try
            {
                await longPollingTransport.Start(mockConnection.Object, string.Empty, disconnectCts.Token)
                .OrTimeout(TimeSpan.FromSeconds(15));
            }
            catch (StartException stex) when(stex.InnerException is OperationCanceledException)
            {
                // An OCE is expected sometimes, depending on a race condition.
            }

            await pollingTcs.Task.OrTimeout(TimeSpan.FromSeconds(2));

            // give it some time to make sure a new poll was not setup after verification
            await Task.Delay(1000);

            mockHttpClient
            .Verify(c => c.Post(It.Is <string>(url => url.StartsWith("poll?")), It.IsAny <Action <Client.Http.IRequest> >(),
                                It.IsAny <IDictionary <string, string> >(), It.IsAny <bool>()), Times.Once());
        }