public async Task GetAsyncWithBasicAuth_ReceiveSetCookie_CookieSent() { if (IsWinHttpHandler) { // Issue #26986 // WinHttpHandler does not process the cookie. return; } await LoopbackServer.CreateServerAndClientAsync(async url => { HttpClientHandler handler = CreateHttpClientHandler(); handler.Credentials = new NetworkCredential("user", "pass"); using (HttpClient client = new HttpClient(handler)) { await client.GetAsync(url); CookieCollection collection = handler.CookieContainer.GetCookies(url); Assert.Equal(2, collection.Count); // Convert to array so we can more easily process contents, since CookieCollection does not implement IEnumerable<Cookie> Cookie[] cookies = new Cookie[2]; collection.CopyTo(cookies, 0); Assert.Contains(cookies, c => c.Name == "A" && c.Value == "1"); Assert.Contains(cookies, c => c.Name == "B" && c.Value == "2"); } }, async server => { await LoopbackServer.AcceptSocketAsync(server, async(_, stream, reader, writer) => { List <string> request1Lines = await LoopbackServer.ReadWriteAcceptedAsync(server, reader, writer, $"HTTP/1.1 401 Unauthorized\r\nContent-Length: 0\r\nWWW-Authenticate: Basic realm=\"WallyWorld\"\r\nSet-Cookie: A=1; Path=/\r\n\r\n"); Assert.Equal(0, request1Lines.Count(s => s.StartsWith("Cookie:"))); List <string> request2Lines = await LoopbackServer.ReadWriteAcceptedAsync(server, reader, writer, $"HTTP/1.1 200 OK\r\nContent-Length: {s_simpleContent.Length}\r\nSet-Cookie: B=2; Path=/\r\n\r\n{s_simpleContent}"); Assert.Contains($"Cookie: A=1", request2Lines); Assert.Equal(1, request2Lines.Count(s => s.StartsWith("Cookie:"))); return(null); }); }); }
public async Task GetAsync_RetryOnConnectionClosed_Success() { if (!IsRetrySupported) { return; } await LoopbackServer.CreateServerAndClientAsync(async url => { using (HttpClient client = CreateHttpClient()) { // Send initial request and receive response so connection is established HttpResponseMessage response1 = await client.GetAsync(url); Assert.Equal(HttpStatusCode.OK, response1.StatusCode); Assert.Equal(s_simpleContent, await response1.Content.ReadAsStringAsync()); // Send second request. Should reuse same connection. // The server will close the connection, but HttpClient should retry the request. HttpResponseMessage response2 = await client.GetAsync(url); Assert.Equal(HttpStatusCode.OK, response1.StatusCode); Assert.Equal(s_simpleContent, await response1.Content.ReadAsStringAsync()); } }, async server => { await LoopbackServer.AcceptSocketAsync(server, async(s, stream, reader, writer) => { // Initial response await LoopbackServer.ReadWriteAcceptedAsync(s, reader, writer, s_simpleResponse); // Second response: Read request headers, then close connection await LoopbackServer.ReadWriteAcceptedAsync(s, reader, writer, ""); s.Close(); // Client should reconnect. Accept that connection and send response. await LoopbackServer.ReadRequestAndSendResponseAsync(server, s_simpleResponse); return(null); }); }); }
public async Task GetAsyncWithRedirect_ReceiveSetCookie_CookieSent() { const string path1 = "/foo"; const string path2 = "/bar"; await LoopbackServer.CreateServerAndClientAsync(async url => { Uri url1 = new Uri(url, path1); HttpClientHandler handler = CreateHttpClientHandler(); using (HttpClient client = new HttpClient(handler)) { await client.GetAsync(url1); CookieCollection collection = handler.CookieContainer.GetCookies(url); Assert.Equal(2, collection.Count); // Convert to array so we can more easily process contents, since CookieCollection does not implement IEnumerable<Cookie> Cookie[] cookies = new Cookie[2]; collection.CopyTo(cookies, 0); Assert.Contains(cookies, c => c.Name == "A" && c.Value == "1"); Assert.Contains(cookies, c => c.Name == "B" && c.Value == "2"); } }, async server => { List <string> request1Lines = await LoopbackServer.ReadRequestAndSendResponseAsync(server, $"HTTP/1.1 302 Found\r\nContent-Length: 0\r\nLocation: {path2}\r\nSet-Cookie: A=1; Path=/\r\nConnection: close\r\n\r\n"); Assert.Equal(0, request1Lines.Count(s => s.StartsWith("Cookie:"))); List <string> request2Lines = await LoopbackServer.ReadRequestAndSendResponseAsync(server, $"HTTP/1.1 200 OK\r\nContent-Length: {s_simpleContent.Length}\r\nSet-Cookie: B=2; Path=/\r\n\r\n{s_simpleContent}"); Assert.Contains($"Cookie: A=1", request2Lines); Assert.Equal(1, request2Lines.Count(s => s.StartsWith("Cookie:"))); }); }
public async Task GetAsyncWithRedirect_SetCookieContainer_CorrectCookiesSent() { const string path1 = "/foo"; const string path2 = "/bar"; await LoopbackServer.CreateServerAndClientAsync(async url => { Uri url1 = new Uri(url, path1); Uri url2 = new Uri(url, path2); Uri unusedUrl = new Uri(url, "/unused"); HttpClientHandler handler = CreateHttpClientHandler(); handler.CookieContainer = new CookieContainer(); handler.CookieContainer.Add(url1, new Cookie("cookie1", "value1")); handler.CookieContainer.Add(url2, new Cookie("cookie2", "value2")); handler.CookieContainer.Add(unusedUrl, new Cookie("cookie3", "value3")); using (HttpClient client = new HttpClient(handler)) { await client.GetAsync(url1); } }, async server => { List <string> request1Lines = await LoopbackServer.ReadRequestAndSendResponseAsync(server, $"HTTP/1.1 302 Found\r\nContent-Length: 0\r\nLocation: {path2}\r\nConnection: close\r\n\r\n"); Assert.Contains($"Cookie: cookie1=value1", request1Lines); Assert.Equal(1, request1Lines.Count(s => s.StartsWith("Cookie:"))); List <string> request2Lines = await LoopbackServer.ReadRequestAndSendResponseAsync(server, $"HTTP/1.1 200 OK\r\nContent-Length: {s_simpleContent.Length}\r\n\r\n{s_simpleContent}"); Assert.Contains($"Cookie: cookie2=value2", request2Lines); Assert.Equal(1, request2Lines.Count(s => s.StartsWith("Cookie:"))); }); }
public async Task PostAsyncExpect100Continue_RetryOnConnectionClosed_Success() { if (!IsRetrySupported) { return; } await LoopbackServer.CreateServerAndClientAsync(async url => { using (HttpClient client = CreateHttpClient()) { // Send initial request and receive response so connection is established HttpResponseMessage response1 = await client.GetAsync(url); Assert.Equal(HttpStatusCode.OK, response1.StatusCode); Assert.Equal(s_simpleContent, await response1.Content.ReadAsStringAsync()); // Send second request. Should reuse same connection. // The server will close the connection, but HttpClient should retry the request. HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url); request.Headers.ExpectContinue = true; var content = new CustomContent(); request.Content = content; HttpResponseMessage response2 = await client.SendAsync(request); Assert.Equal(HttpStatusCode.OK, response1.StatusCode); Assert.Equal(s_simpleContent, await response1.Content.ReadAsStringAsync()); Assert.Equal(1, content.SerializeCount); } }, async server => { await LoopbackServer.AcceptSocketAsync(server, async(s, stream, reader, writer) => { // Initial response await LoopbackServer.ReadWriteAcceptedAsync(s, reader, writer, s_simpleResponse); // Second response: Read request headers, then close connection List <string> lines = await LoopbackServer.ReadWriteAcceptedAsync(s, reader, writer, ""); Assert.Contains("Expect: 100-continue", lines); s.Close(); // Client should reconnect. Accept that connection and send response. await LoopbackServer.AcceptSocketAsync(server, async(s2, stream2, reader2, writer2) => { List <string> lines2 = await LoopbackServer.ReadWriteAcceptedAsync(s2, reader2, writer2, ""); Assert.Contains("Expect: 100-continue", lines2); await writer2.WriteAsync("HTTP/1.1 100 Continue\r\n\r\n"); string contentLine = await reader2.ReadLineAsync(); Assert.Equal(s_simpleContent, contentLine + "\r\n"); await writer2.WriteAsync(s_simpleResponse); return(null); }); return(null); }); }); }