Example #1
0
        public async Task HttpHeader_Set_Success()
        {
            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                HttpWebRequest request         = WebRequest.CreateHttp(url);
                request.Method                 = HttpMethod.Get.Method;
                Task <WebResponse> getResponse = request.GetResponseAsync();
                await server.AcceptConnectionSendResponseAndCloseAsync(HttpStatusCode.OK, "Content-Type: application/json;charset=UTF-8\r\n", "12345");

                using (WebResponse response = await getResponse)
                {
                    HttpWebResponse httpResponse = (HttpWebResponse)response;
                    Assert.Equal("UTF-8", httpResponse.CharacterSet);
                    Assert.Equal(HttpStatusCode.OK, httpResponse.StatusCode);
                    Assert.Equal("OK", httpResponse.StatusDescription);
                    CookieCollection cookieCollection = new CookieCollection();
                    httpResponse.Cookies = cookieCollection;
                    Assert.Equal(cookieCollection, httpResponse.Cookies);
                    Assert.Equal(5, httpResponse.ContentLength);
                    Assert.Equal(5, int.Parse(httpResponse.GetResponseHeader("Content-Length")));
                }
            });
        }
Example #2
0
        public async Task HttpWebResponse_Serialize_ExpectedResult()
        {
            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                HttpWebRequest request         = WebRequest.CreateHttp(url);
                request.Method                 = HttpMethod.Get.Method;
                Task <WebResponse> getResponse = request.GetResponseAsync();
                DateTimeOffset utcNow          = DateTimeOffset.UtcNow;
                await server.AcceptConnectionSendResponseAndCloseAsync();

                using (WebResponse response = await getResponse)
                {
                    HttpWebResponse httpResponse = (HttpWebResponse)response;
                    using (MemoryStream fs = new MemoryStream())
                    {
                        BinaryFormatter formatter = new BinaryFormatter();
                        HttpWebResponse hwr       = (HttpWebResponse)response;

                        // HttpWebResponse is not serializable on .NET Core.
                        Assert.Throws <SerializationException>(() => formatter.Serialize(fs, hwr));
                    }
                }
            });
        }
Example #3
0
        public static async Task RequestHeaders_SpecialHeaders_RequestSucceeds()
        {
            var wc = new WebClient();

            wc.Headers["Accept"]      = "text/html";
            wc.Headers["Connection"]  = "close";
            wc.Headers["ContentType"] = "text/html; charset=utf-8";
            wc.Headers["Expect"]      = "100-continue";
            wc.Headers["Referer"]     = "http://localhost";
            wc.Headers["User-Agent"]  = ".NET";
            wc.Headers["Host"]        = "http://localhost";

            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                Task <string> download = wc.DownloadStringTaskAsync(url.ToString());
                Assert.Null(wc.ResponseHeaders);
                await LoopbackServer.ReadRequestAndSendResponseAsync(server,
                                                                     "HTTP/1.1 200 OK\r\n" +
                                                                     $"Date: {DateTimeOffset.UtcNow:R}\r\n" +
                                                                     $"Content-Length: 0\r\n" +
                                                                     "\r\n");
                await download;
            });
        }
Example #4
0
 public async Task UseClientCertOnHttp2_DowngradedToHttp1MutualAuth_Success()
 {
     using X509Certificate2 clientCert = Test.Common.Configuration.Certificates.GetClientCertificate();
     await LoopbackServer.CreateClientAndServerAsync(
         async address =>
     {
         var handler = new WinHttpHandler();
         handler.ServerCertificateValidationCallback = CustomServerCertificateValidationCallback;
         handler.ClientCertificates.Add(clientCert);
         handler.ClientCertificateOption = ClientCertificateOption.Manual;
         using (var client = new HttpClient(handler))
             using (HttpResponseMessage response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, address)
             {
                 Version = HttpVersion20.Value
             }))
             {
                 Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                 Assert.True(_validationCallbackHistory.WasCalled);
                 Assert.NotEmpty(_validationCallbackHistory.CertificateChain);
                 Assert.Equal(Test.Common.Configuration.Certificates.GetServerCertificate(), _validationCallbackHistory.CertificateChain[0]);
             }
     },
         async s =>
     {
         using (LoopbackServer.Connection connection = await s.EstablishConnectionAsync().ConfigureAwait(false))
         {
             SslStream sslStream = connection.Stream as SslStream;
             Assert.NotNull(sslStream);
             Assert.True(sslStream.IsMutuallyAuthenticated);
             Assert.Equal(clientCert, sslStream.RemoteCertificate);
             await connection.ReadRequestHeaderAndSendResponseAsync(HttpStatusCode.OK);
         }
     }, new LoopbackServer.Options {
         UseSsl = true
     });
 }
 public async Task HttpWebResponse_Close_Success()
 {
     await LoopbackServer.CreateServerAsync(async (server, url) =>
     {
         HttpWebRequest request         = WebRequest.CreateHttp(url);
         request.Method                 = HttpMethod.Get.Method;
         Task <WebResponse> getResponse = request.GetResponseAsync();
         DateTimeOffset utcNow          = DateTimeOffset.UtcNow;
         await LoopbackServer.ReadRequestAndSendResponseAsync(server,
                                                              $"HTTP/1.1 200 OK\r\n" +
                                                              $"Date: {utcNow:R}\r\n" +
                                                              "Content-Type: application/json;charset=UTF-8\r\n" +
                                                              "Content-Length: 5\r\n" +
                                                              "\r\n" +
                                                              "12345");
         WebResponse response         = await getResponse;
         HttpWebResponse httpResponse = (HttpWebResponse)response;
         httpResponse.Close();
         Assert.Throws <ObjectDisposedException>(() =>
         {
             httpResponse.GetResponseStream();
         });
     });
 }
Example #6
0
        public async Task DownloadData_Success()
        {
            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                var wc = new WebClient();

                var downloadProgressInvoked = new TaskCompletionSource <bool>();
                wc.DownloadProgressChanged += (s, e) => downloadProgressInvoked.TrySetResult(true);

                Task <byte[]> download = DownloadDataAsync(wc, url.ToString());
                await LoopbackServer.ReadRequestAndSendResponseAsync(server,
                                                                     "HTTP/1.1 200 OK\r\n" +
                                                                     $"Date: {DateTimeOffset.UtcNow:R}\r\n" +
                                                                     $"Content-Length: {ExpectedText.Length}\r\n" +
                                                                     "\r\n" +
                                                                     $"{ExpectedText}");
                Assert.Equal(ExpectedText, Encoding.ASCII.GetString(await download));

                if (IsAsync)
                {
                    await downloadProgressInvoked.Task.TimeoutAfter(TimeoutMilliseconds);
                }
            });
        }
Example #7
0
        public async Task SendReceive_ConnectionClosedPrematurely_ReceiveAsyncFailsAndWebSocketStateUpdated()
        {
            var options = new LoopbackServer.Options {
                WebSocketEndpoint = true
            };

            Func <ClientWebSocket, LoopbackServer, Uri, Task> connectToServerThatAbortsConnection = async(clientSocket, server, url) =>
            {
                var pendingReceiveAsyncPosted = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

                // Start listening for incoming connections on the server side.
                Task acceptTask = server.AcceptConnectionAsync(async connection =>
                {
                    // Complete the WebSocket upgrade. After this is done, the client-side ConnectAsync should complete.
                    Assert.NotNull(await LoopbackHelper.WebSocketHandshakeAsync(connection));

                    // Wait for client-side ConnectAsync to complete and for a pending ReceiveAsync to be posted.
                    await pendingReceiveAsyncPosted.Task.WaitAsync(TimeSpan.FromMilliseconds(TimeOutMilliseconds));

                    // Close the underlying connection prematurely (without sending a WebSocket Close frame).
                    connection.Socket.Shutdown(SocketShutdown.Both);
                    connection.Socket.Close();
                });

                // Initiate a connection attempt.
                var cts = new CancellationTokenSource(TimeOutMilliseconds);
                await clientSocket.ConnectAsync(url, cts.Token);

                // Post a pending ReceiveAsync before the TCP connection is torn down.
                var  recvBuffer          = new byte[100];
                var  recvSegment         = new ArraySegment <byte>(recvBuffer);
                Task pendingReceiveAsync = ReceiveAsync(clientSocket, recvSegment, cts.Token);
                pendingReceiveAsyncPosted.SetResult();

                // Wait for the server to close the underlying connection.
                await acceptTask.WaitAsync(cts.Token);

                WebSocketException pendingReceiveException = await Assert.ThrowsAsync <WebSocketException>(() => pendingReceiveAsync);

                Assert.Equal(WebSocketError.ConnectionClosedPrematurely, pendingReceiveException.WebSocketErrorCode);

                if (PlatformDetection.IsInAppContainer)
                {
                    const uint WININET_E_CONNECTION_ABORTED = 0x80072EFE;

                    Assert.NotNull(pendingReceiveException.InnerException);
                    Assert.Equal(WININET_E_CONNECTION_ABORTED, (uint)pendingReceiveException.InnerException.HResult);
                }

                WebSocketException newReceiveException =
                    await Assert.ThrowsAsync <WebSocketException>(() => ReceiveAsync(clientSocket, recvSegment, cts.Token));

                Assert.Equal(
                    ResourceHelper.GetExceptionMessage("net_WebSockets_InvalidState", "Aborted", "Open, CloseSent"),
                    newReceiveException.Message);

                Assert.Equal(WebSocketState.Aborted, clientSocket.State);
                Assert.Null(clientSocket.CloseStatus);
            };

            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                using (ClientWebSocket clientSocket = new ClientWebSocket())
                {
                    await connectToServerThatAbortsConnection(clientSocket, server, url);
                }
            }, options);
        }
        public async Task ReadAsStreamAsync_InvalidServerResponse_ThrowsIOException(
            LoopbackServer.TransferType transferType,
            LoopbackServer.TransferError transferError)
        {
            IPEndPoint serverEndPoint;
            Task serverTask = LoopbackServer.StartServer(transferType, transferError, out serverEndPoint);

            await Assert.ThrowsAsync<IOException>(() => ReadAsStreamHelper(serverEndPoint));

            await serverTask;
        }
        public async Task ReadAsStreamAsync_ValidServerResponse_Success(
            LoopbackServer.TransferType transferType,
            LoopbackServer.TransferError transferError)
        {
            IPEndPoint serverEndPoint;
            Task serverTask = LoopbackServer.StartServer(transferType, transferError, out serverEndPoint);

            await ReadAsStreamHelper(serverEndPoint);

            await serverTask;
        }
        public async Task SendReceive_ConnectionClosedPrematurely_ReceiveAsyncFailsAndWebSocketStateUpdated()
        {
            var options = new LoopbackServer.Options {
                WebSocketEndpoint = true
            };

            Func <ClientWebSocket, Socket, Uri, Task> connectToServerThatAbortsConnection = async(clientSocket, server, url) =>
            {
                AutoResetEvent pendingReceiveAsyncPosted = new AutoResetEvent(false);

                // Start listening for incoming connections on the server side.
                Task <List <string> > acceptTask = LoopbackServer.AcceptSocketAsync(server, async(socket, stream, reader, writer) =>
                {
                    // Complete the WebSocket upgrade. After this is done, the client-side ConnectAsync should complete.
                    Assert.True(await LoopbackServer.WebSocketHandshakeAsync(socket, reader, writer));

                    // Wait for client-side ConnectAsync to complete and for a pending ReceiveAsync to be posted.
                    pendingReceiveAsyncPosted.WaitOne(TimeOutMilliseconds);

                    // Close the underlying connection prematurely (without sending a WebSocket Close frame).
                    socket.Shutdown(SocketShutdown.Both);
                    socket.Close();

                    return(null);
                }, options);

                // Initiate a connection attempt.
                var cts = new CancellationTokenSource(TimeOutMilliseconds);
                await clientSocket.ConnectAsync(url, cts.Token);

                // Post a pending ReceiveAsync before the TCP connection is torn down.
                var  recvBuffer          = new byte[100];
                var  recvSegment         = new ArraySegment <byte>(recvBuffer);
                Task pendingReceiveAsync = ReceiveAsync(clientSocket, recvSegment, cts.Token);
                pendingReceiveAsyncPosted.Set();

                // Wait for the server to close the underlying connection.
                acceptTask.Wait(cts.Token);

                // Validate I/O errors and socket state.
                if (PlatformDetection.IsFullFramework)
                {
                    _output.WriteLine("[Windows] ManagedWebSocket-based implementation.");

                    WebSocketException pendingReceiveException = await Assert.ThrowsAsync <WebSocketException>(() => pendingReceiveAsync);

                    Assert.Equal(WebSocketError.ConnectionClosedPrematurely, pendingReceiveException.WebSocketErrorCode);

                    WebSocketException newReceiveException =
                        await Assert.ThrowsAsync <WebSocketException>(() => ReceiveAsync(clientSocket, recvSegment, cts.Token));

                    Assert.Equal(WebSocketError.Success, newReceiveException.WebSocketErrorCode);
                    Assert.Equal(
                        ResourceHelper.GetExceptionMessage("net_WebSockets_InvalidState", "Aborted", "Open, CloseSent"),
                        newReceiveException.Message);

                    Assert.Equal(WebSocketState.Aborted, clientSocket.State);
                    Assert.Null(clientSocket.CloseStatus);
                }
                else if (PlatformDetection.IsUap)
                {
                    _output.WriteLine("WinRTWebSocket-based implementation.");

                    const uint WININET_E_CONNECTION_ABORTED = 0x80072EFE;

                    WebSocketException pendingReceiveException = await Assert.ThrowsAsync <WebSocketException>(() => pendingReceiveAsync);

                    Assert.Equal(WebSocketError.ConnectionClosedPrematurely, pendingReceiveException.WebSocketErrorCode);
                    Assert.NotNull(pendingReceiveException.InnerException);
                    Assert.Equal(WININET_E_CONNECTION_ABORTED, (uint)pendingReceiveException.InnerException.HResult);

                    WebSocketException newReceiveException =
                        await Assert.ThrowsAsync <WebSocketException>(() => ReceiveAsync(clientSocket, recvSegment, cts.Token));

                    Assert.Equal(WebSocketError.Success, newReceiveException.WebSocketErrorCode);
                    Assert.Equal(
                        ResourceHelper.GetExceptionMessage("net_WebSockets_InvalidState", "Aborted", "Open, CloseSent"),
                        newReceiveException.Message);

                    Assert.Equal(WebSocketState.Aborted, clientSocket.State);
                    Assert.Null(clientSocket.CloseStatus);
                }
                else
                {
                    _output.WriteLine("[Non-Windows] ManagedWebSocket-based implementation.");

                    WebSocketException pendingReceiveException = await Assert.ThrowsAsync <WebSocketException>(() => pendingReceiveAsync);

                    Assert.Equal(WebSocketError.ConnectionClosedPrematurely, pendingReceiveException.WebSocketErrorCode);

                    WebSocketException newReceiveException =
                        await Assert.ThrowsAsync <WebSocketException>(() => ReceiveAsync(clientSocket, recvSegment, cts.Token));

                    Assert.Equal(WebSocketError.ConnectionClosedPrematurely, newReceiveException.WebSocketErrorCode);

                    Assert.Equal(WebSocketState.Open, clientSocket.State);
                    Assert.Null(clientSocket.CloseStatus);
                }
            };

            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                using (ClientWebSocket clientSocket = new ClientWebSocket())
                {
                    await connectToServerThatAbortsConnection(clientSocket, server, url);
                }
            }, options);
        }