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"))); } }); }
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)); } } }); }
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; }); }
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(); }); }); }
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); } }); }
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); }