public async Task GetAsync_MissingExpires_ReturnNull()
 {
     await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
     {
         using (HttpClient client = CreateHttpClient())
         {
             HttpResponseMessage response = await client.GetAsync(uri);
             Assert.Null(response.Content.Headers.Expires);
         }
     },
                                                            async server =>
     {
         await server.HandleRequestAsync(HttpStatusCode.OK);
     });
 }
Esempio n. 2
0
        private async Task CreateServerAndGetAsync(HttpClient client, HttpCompletionOption completionOption, List <HttpHeaderData> headers, string content)
        {
            await LoopbackServerFactory.CreateServerAsync(async (server, url) =>
            {
                Task <HttpResponseMessage> getAsync = client.GetAsync(url, completionOption);

                await new Task[]
                {
                    getAsync,
                    server.HandleRequestAsync(HttpStatusCode.OK, headers, content),
                }.WhenAllOrAnyFailed().ConfigureAwait(false);

                getAsync.Result.Dispose();
            });
        }
Esempio n. 3
0
        private void CreateServerAndGet(HttpClient client, HttpCompletionOption completionOption, List <HttpHeaderData> headers, string content)
        {
            LoopbackServerFactory.CreateServerAsync((server, url) =>
            {
                Task <HttpResponseMessage> getAsync = client.GetAsync(url, completionOption);

                new Task[] {
                    getAsync,
                    server.HandleRequestAsync(HttpStatusCode.OK, headers, content)
                }.WhenAllOrAnyFailed().GetAwaiter().GetResult();

                getAsync.Result.Dispose();
                return(Task.CompletedTask);
            }).GetAwaiter().GetResult();
        }
Esempio n. 4
0
 public async Task GetAsync_DefaultCoookieContainer_NoCookieSent()
 {
     await LoopbackServerFactory.CreateClientAndServerAsync(
         async uri =>
     {
         using (HttpClient client = CreateHttpClient())
         {
             await client.GetAsync(uri);
         }
     },
         async server =>
     {
         HttpRequestData requestData = await server.HandleRequestAsync();
         Assert.Equal(0, requestData.GetHeaderValueCount("Cookie"));
     });
 }
        public async Task PostAsync_CancelDuringRequestContentSend_TaskCanceledQuickly(bool chunkedTransfer, CancellationMode mode)
        {
            if (LoopbackServerFactory.IsHttp2 && chunkedTransfer)
            {
                // There is no chunked encoding in HTTP/2
                return;
            }

            var serverRelease = new TaskCompletionSource <bool>();
            await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
            {
                try
                {
                    using (HttpClient client = CreateHttpClient())
                    {
                        client.Timeout = Timeout.InfiniteTimeSpan;
                        var cts        = new CancellationTokenSource();

                        var waitToSend     = new TaskCompletionSource <bool>();
                        var contentSending = new TaskCompletionSource <bool>();
                        var req            = new HttpRequestMessage(HttpMethod.Post, uri)
                        {
                            Version = VersionFromUseHttp2
                        };
                        req.Content = new ByteAtATimeContent(int.MaxValue, waitToSend.Task, contentSending, millisecondDelayBetweenBytes: 1);
                        req.Headers.TransferEncodingChunked = chunkedTransfer;

                        Task <HttpResponseMessage> resp = client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead, cts.Token);
                        waitToSend.SetResult(true);
                        await contentSending.Task;
                        Cancel(mode, client, cts);
                        await ValidateClientCancellationAsync(() => resp);
                    }
                }
                finally
                {
                    serverRelease.SetResult(true);
                }
            }, async server =>
            {
                try
                {
                    await server.AcceptConnectionAsync(connection => serverRelease.Task);
                }
                catch { };  // Ignore any closing errors since we did not really process anything.
            });
        }
        public async Task GetAsync_Redirect_CookiesArePreserved()
        {
            if (UseVersion == HttpVersion30)
            {
                // [ActiveIssue("https://github.com/dotnet/runtime/issues/56870")]
                return;
            }

            HttpClientHandler handler = CreateHttpClientHandler();

            string loginPath  = "/login/user";
            string returnPath = "/return";

            await LoopbackServerFactory.CreateClientAndServerAsync(async serverUrl =>
            {
                Uri loginUrl            = new Uri(serverUrl, loginPath);
                Uri returnUrl           = new Uri(serverUrl, returnPath);
                CookieContainer cookies = handler.CookieContainer;

                using (HttpClient client = CreateHttpClient(handler))
                {
                    client.DefaultRequestHeaders.ConnectionClose = true;     // to avoid issues with connection pooling
                    HttpResponseMessage response = await client.GetAsync(loginUrl);
                    string content = await response.Content.ReadAsStringAsync();
                    Assert.Equal(s_simpleContent, content);

                    Cookie cookie = handler.CookieContainer.GetCookies(returnUrl)[0];
                    Assert.Equal("LoggedIn", cookie.Name);
                }
            },
                                                                   async server =>
            {
                HttpRequestData requestData1 = await server.HandleRequestAsync(HttpStatusCode.Found, new[]
                {
                    new HttpHeaderData("Location", returnPath),
                    new HttpHeaderData("Set-Cookie", "LoggedIn=true; Path=/return"),
                });

                Assert.Equal(0, requestData1.GetHeaderValueCount("Cookie"));

                HttpRequestData requestData2 = await server.HandleRequestAsync(content: s_simpleContent, headers: new[] {
                    new HttpHeaderData("Set-Cookie", "LoggedIn=true; Path=/return"),
                });
                Assert.Equal("LoggedIn=true", requestData2.GetSingleHeaderValue("Cookie"));
            });
        }
        public async Task GetAsyncWithBasicAuth_ReceiveSetCookie_CookieSent()
        {
            await LoopbackServerFactory.CreateClientAndServerAsync(async url =>
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                handler.Credentials       = new NetworkCredential("user", "pass");

                using (HttpClient client = CreateHttpClient(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 =>
            {
                HttpRequestData requestData1 = await server.HandleRequestAsync(
                    HttpStatusCode.Unauthorized,
                    new HttpHeaderData[]
                {
                    new HttpHeaderData("WWW-Authenticate", "Basic realm=\"WallyWorld\""),
                    new HttpHeaderData("Set-Cookie", "A=1; Path=/")
                });

                Assert.Equal(0, requestData1.GetHeaderValueCount("Cookie"));

                HttpRequestData requestData2 = await server.HandleRequestAsync(
                    HttpStatusCode.OK,
                    new HttpHeaderData[]
                {
                    new HttpHeaderData("Set-Cookie", "B=2; Path=/")
                },
                    s_simpleContent);

                Assert.Equal("A=1", requestData2.GetSingleHeaderValue("Cookie"));
            });
        }
        public async Task GetAsync_CancelDuringResponseHeadersReceived_TaskCanceledQuickly(bool connectionClose, CancellationMode mode)
        {
            if (LoopbackServerFactory.IsHttp2 && connectionClose)
            {
                // There is no Connection header in HTTP/2
                return;
            }

            using (HttpClient client = CreateHttpClient())
            {
                client.Timeout = Timeout.InfiniteTimeSpan;
                var cts = new CancellationTokenSource();

                await LoopbackServerFactory.CreateServerAsync(async (server, url) =>
                {
                    var partialResponseHeadersSent = new TaskCompletionSource<bool>();
                    var clientFinished = new TaskCompletionSource<bool>();

                    Task serverTask = server.AcceptConnectionAsync(async connection =>
                    {
                        await connection.ReadRequestDataAsync();
                        await connection.SendResponseAsync(HttpStatusCode.OK, content: null, isFinal: false);

                        partialResponseHeadersSent.TrySetResult(true);
                        await clientFinished.Task;
                    });

                    await ValidateClientCancellationAsync(async () =>
                    {
                        var req = new HttpRequestMessage(HttpMethod.Get, url) { Version = VersionFromUseHttp2 };
                        req.Headers.ConnectionClose = connectionClose;

                        Task<HttpResponseMessage> getResponse = client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead, cts.Token);
                        await partialResponseHeadersSent.Task;
                        Cancel(mode, client, cts);
                        await getResponse;
                    });

                    try
                    {
                        clientFinished.SetResult(true);
                        await serverTask;
                    } catch { }
                });
            }
        }
Esempio n. 9
0
        public async Task GetAsync_SetCookieContainerAndCookieHeader_BothCookiesSent()
        {
            if (IsNetfxHandler)
            {
                // Netfx handler does not support custom cookie header
                return;
            }

            if (IsCurlHandler)
            {
                // CurlHandler ignores container cookies when custom Cookie header is set.
                // SocketsHttpHandler behaves the expected way. Not worth fixing in CurlHandler as it is going away.
                return;
            }

            if (LoopbackServerFactory.IsHttp2 && UseSocketsHttpHandler)
            {
                // ISSUE #34377: We are not handling multi-valued headers correctly
                return;
            }

            await LoopbackServerFactory.CreateServerAsync(async (server, url) =>
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                handler.CookieContainer   = CreateSingleCookieContainer(url);

                using (HttpClient client = new HttpClient(handler))
                {
                    HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, url);
                    requestMessage.Headers.Add("Cookie", s_customCookieHeaderValue);

                    Task <HttpResponseMessage> getResponseTask = client.SendAsync(requestMessage);
                    Task <HttpRequestData> serverTask          = server.HandleRequestAsync();
                    await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                    HttpRequestData requestData = await serverTask;
                    string cookieHeaderValue    = requestData.GetSingleHeaderValue("Cookie");

                    var cookies = cookieHeaderValue.Split(new string[] { "; " }, StringSplitOptions.None);
                    Assert.Contains(s_expectedCookieHeaderValue, cookies);
                    Assert.Contains(s_customCookieHeaderValue, cookies);
                    Assert.Equal(2, cookies.Count());
                }
            });
        }
Esempio n. 10
0
        [InlineData("Max-Forwards", "NotAnInteger", false)]                 // invalid format for header but added with TryAddWithoutValidation
        public async Task SendAsync_SpecialHeaderKeyOrValue_Success(string key, string value, bool parsable)
        {
            if (PlatformDetection.IsBrowser && (key == "Content-Location" || key == "Date" || key == "Accept-CharSet"))
            {
                // https://fetch.spec.whatwg.org/#forbidden-header-name
                return;
            }

            await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
            {
                bool contentHeader = false;
                using (HttpClient client = CreateHttpClient())
                {
                    var message = new HttpRequestMessage(HttpMethod.Get, uri)
                    {
                        Version = UseVersion
                    };
                    if (!message.Headers.TryAddWithoutValidation(key, value))
                    {
                        message.Content = new StringContent("");
                        contentHeader   = message.Content.Headers.TryAddWithoutValidation(key, value);
                    }
                    (await client.SendAsync(TestAsync, message).ConfigureAwait(false)).Dispose();
                }

                // Validate our test by validating our understanding of a header's parsability.
                HttpHeaders headers = contentHeader ? (HttpHeaders)
                                      new StringContent("").Headers :
                                      new HttpRequestMessage().Headers;
                if (parsable)
                {
                    headers.Add(key, value);
                }
                else
                {
                    Assert.Throws <FormatException>(() => headers.Add(key, value));
                }
            },
                                                                   async server =>
            {
                HttpRequestData requestData = await server.HandleRequestAsync(HttpStatusCode.OK);
                Assert.Equal(value, requestData.GetSingleHeaderValue(key));
            });
        }
Esempio n. 11
0
        public async Task GetAsync_AddMultipleCookieHeaders_CookiesSent()
        {
            if (IsNetfxHandler)
            {
                // Netfx handler does not support custom cookie header
                return;
            }

            if (LoopbackServerFactory.IsHttp2 && UseSocketsHttpHandler)
            {
                // ISSUE #34377: We are not handling multi-valued headers correctly
                return;
            }

            await LoopbackServerFactory.CreateClientAndServerAsync(
                async uri =>
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                using (HttpClient client = new HttpClient(handler))
                {
                    HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
                    requestMessage.Headers.Add("Cookie", "A=1");
                    requestMessage.Headers.Add("Cookie", "B=2");
                    requestMessage.Headers.Add("Cookie", "C=3");

                    await client.SendAsync(requestMessage);
                }
            },
                async server =>
            {
                HttpRequestData requestData = await server.HandleRequestAsync();

                // Multiple Cookie header values are treated as any other header values and are
                // concatenated using ", " as the separator.

                string cookieHeaderValue = requestData.GetSingleHeaderValue("Cookie");

                var cookieValues = cookieHeaderValue.Split(new string[] { ", " }, StringSplitOptions.None);
                Assert.Contains("A=1", cookieValues);
                Assert.Contains("B=2", cookieValues);
                Assert.Contains("C=3", cookieValues);
                Assert.Equal(3, cookieValues.Count());
            });
        }
        public async Task SendAsync_Expires_Success(string value, bool isValid)
        {
            await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
            {
                using (var client = CreateHttpClient())
                {
                    var message = new HttpRequestMessage(HttpMethod.Get, uri);
                    HttpResponseMessage response = await client.SendAsync(message);
                    Assert.NotNull(response.Content.Headers.Expires);
                    // Invalid date should be converted to MinValue so everything is expired.
                    Assert.Equal(isValid ? DateTime.Parse(value) : DateTimeOffset.MinValue, response.Content.Headers.Expires);
                }
            },
                                                                   async server =>
            {
                IList <HttpHeaderData> headers = new HttpHeaderData[] { new HttpHeaderData("Expires", value) };

                HttpRequestData requestData = await server.HandleRequestAsync(HttpStatusCode.OK, headers);
            });
        }
        public async Task SendAsync_SpecialCharacterHeader_Success()
        {
            string headerValue = "header name with underscore";
            await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
            {
                using (var client = CreateHttpClient())
                {
                    var message = new HttpRequestMessage(HttpMethod.Get, uri);
                    message.Headers.TryAddWithoutValidation("x-Special_name", "header name with underscore");
                    (await client.SendAsync(message).ConfigureAwait(false)).Dispose();
                }
            },
                                                                   async server =>
            {
                HttpRequestData requestData = await server.HandleRequestAsync(HttpStatusCode.OK);

                string header = requestData.GetSingleHeaderValue("x-Special_name");
                Assert.Equal(header, headerValue);
            });
        }
Esempio n. 14
0
        public async Task GetAsync_AddCookieHeader_CookieHeaderSent()
        {
            await LoopbackServerFactory.CreateClientAndServerAsync(
                async uri =>
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                using (HttpClient client = new HttpClient(handler))
                {
                    HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
                    requestMessage.Headers.Add("Cookie", s_customCookieHeaderValue);

                    await client.SendAsync(requestMessage);
                }
            },
                async server =>
            {
                HttpRequestData requestData = await server.HandleRequestAsync();
                Assert.Equal(s_customCookieHeaderValue, requestData.GetSingleHeaderValue("Cookie"));
            });
        }
        public async Task SendAsync_UserAgent_CorrectlyWritten()
        {
            string userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.18 Safari/537.36";

            await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
            {
                using (var client = CreateHttpClient())
                {
                    var message = new HttpRequestMessage(HttpMethod.Get, uri);
                    message.Headers.TryAddWithoutValidation("User-Agent", userAgent);
                    (await client.SendAsync(message).ConfigureAwait(false)).Dispose();
                }
            },
                                                                   async server =>
            {
                HttpRequestData requestData = await server.HandleRequestAsync(HttpStatusCode.OK);

                string agent = requestData.GetSingleHeaderValue("User-Agent");
                Assert.Equal(userAgent, agent);
            });
        }
Esempio n. 16
0
        public async Task GetAsync_ReceiveSetCookieHeader_CookieRemoved()
        {
            await LoopbackServerFactory.CreateServerAsync(async (server, url) =>
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                handler.CookieContainer   = CreateSingleCookieContainer(url);

                using (HttpClient client = CreateHttpClient(handler))
                {
                    Task <HttpResponseMessage> getResponseTask = client.GetAsync(url);
                    Task <HttpRequestData> serverTask          = server.HandleRequestAsync(
                        HttpStatusCode.OK,
                        new HttpHeaderData[] { new HttpHeaderData("Set-Cookie", $"{s_cookieName}=; Expires=Sun, 06 Nov 1994 08:49:37 GMT") },
                        s_simpleContent);
                    await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                    CookieCollection collection = handler.CookieContainer.GetCookies(url);
                    Assert.Equal(0, collection.Count);
                }
            });
        }
        public async Task GetAsync_SetCookieContainerAndMultipleCookieHeaders_BothCookiesSent()
        {
            await LoopbackServerFactory.CreateServerAsync(async (server, url) =>
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                handler.CookieContainer   = CreateSingleCookieContainer(url);

                using (HttpClient client = CreateHttpClient(handler))
                {
                    var requestMessage = new HttpRequestMessage(HttpMethod.Get, url)
                    {
                        Version = UseVersion
                    };
                    requestMessage.Headers.Add("Cookie", "A=1");
                    requestMessage.Headers.Add("Cookie", "B=2");

                    Task <HttpResponseMessage> getResponseTask = client.SendAsync(TestAsync, requestMessage);
                    Task <HttpRequestData> serverTask          = server.HandleRequestAsync();
                    await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                    HttpRequestData requestData = await serverTask;
                    string cookieHeaderValue    = GetCookieValue(requestData);

#if NETFRAMEWORK
                    // On .NET Framework multiple Cookie header values are treated as any other header values and are
                    // concatenated using ", " as the separator.  The container cookie is concatenated to
                    // one of these values using the "; " cookie separator.

                    var separators = new string[] { "; ", ", " };
#else
                    var separators = new string[] { "; " };
#endif
                    var cookieValues = cookieHeaderValue.Split(separators, StringSplitOptions.None);
                    Assert.Contains(s_expectedCookieHeaderValue, cookieValues);
                    Assert.Contains("A=1", cookieValues);
                    Assert.Contains("B=2", cookieValues);
                    Assert.Equal(3, cookieValues.Count());
                }
            });
        }
        public async Task GetAsyncWithRedirect_SetCookieContainer_CorrectCookiesSent()
        {
            if (UseVersion == HttpVersion30)
            {
                // [ActiveIssue("https://github.com/dotnet/runtime/issues/56870")]
                return;
            }

            const string path1      = "/foo";
            const string path2      = "/bar";
            const string unusedPath = "/unused";

            await LoopbackServerFactory.CreateClientAndServerAsync(async url =>
            {
                Uri url1      = new Uri(url, path1);
                Uri url2      = new Uri(url, path2);
                Uri unusedUrl = new Uri(url, unusedPath);

                HttpClientHandler handler = CreateHttpClientHandler();
                handler.CookieContainer   = new CookieContainer();
                handler.CookieContainer.Add(url1, new Cookie("cookie1", "value1", path1));
                handler.CookieContainer.Add(url2, new Cookie("cookie2", "value2", path2));
                handler.CookieContainer.Add(unusedUrl, new Cookie("cookie3", "value3", unusedPath));

                using (HttpClient client = CreateHttpClient(handler))
                {
                    client.DefaultRequestHeaders.ConnectionClose = true; // to avoid issues with connection pooling
                    await client.GetAsync(url1);
                }
            },
                                                                   async server =>
            {
                HttpRequestData requestData1 = await server.HandleRequestAsync(HttpStatusCode.Found, new HttpHeaderData[] { new HttpHeaderData("Location", path2) });
                Assert.Equal("cookie1=value1", requestData1.GetSingleHeaderValue("Cookie"));

                HttpRequestData requestData2 = await server.HandleRequestAsync(content: s_simpleContent);
                Assert.Equal("cookie2=value2", requestData2.GetSingleHeaderValue("Cookie"));
            });
        }
        public async Task PostAsync_Cancel_CancellationTokenPassedToContent(HttpContent content, CancellationTokenSource cancellationTokenSource)
        {
            if (IsWinHttpHandler)
            {
                return;
            }
            // Skipping test for a sync scenario becasue DelegateStream drops the original cancellationToken when it calls Read/Write methods.
            // As a result, ReadAsyncFunc receives default in cancellationToken, which will never get signaled through the cancellationTokenSource.
            if (!TestAsync)
            {
                return;
            }

            await LoopbackServerFactory.CreateClientAndServerAsync(
                async uri =>
            {
                using (var invoker = new HttpMessageInvoker(CreateHttpClientHandler()))
                    using (var req = new HttpRequestMessage(HttpMethod.Post, uri)
                    {
                        Content = content, Version = UseVersion
                    })
                        try
                        {
                            using (HttpResponseMessage resp = await invoker.SendAsync(TestAsync, req, cancellationTokenSource.Token))
                            {
                                Assert.Equal("Hello World", await resp.Content.ReadAsStringAsync());
                            }
                        }
                        catch (OperationCanceledException) { }
            },
                async server =>
            {
                try
                {
                    await server.HandleRequestAsync(content: "Hello World");
                }
                catch (Exception) { }
            });
        }
Esempio n. 20
0
        public async Task SendAsync_RequestHeaderInResponse_Success(string name, string value)
        {
            await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
            {
                using (HttpClient client = CreateHttpClient())
                {
                    var message = new HttpRequestMessage(HttpMethod.Get, uri)
                    {
                        Version = UseVersion
                    };
                    HttpResponseMessage response = await client.SendAsync(TestAsync, message);

                    Assert.Equal(value, response.Headers.GetValues(name).First());
                }
            },
                                                                   async server =>
            {
                IList <HttpHeaderData> headers = new HttpHeaderData[] { new HttpHeaderData(name, value) };

                HttpRequestData requestData = await server.HandleRequestAsync(HttpStatusCode.OK, headers);
            });
        }
Esempio n. 21
0
        public async Task GetAsync_LargeHeader_Success(string headerName, int headerValueLength)
        {
            var    rand        = new Random(42);
            string headerValue = string.Concat(Enumerable.Range(0, headerValueLength).Select(_ => (char)('A' + rand.Next(26))));

            const string ContentString = "hello world";
            await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
            {
                using (HttpClient client = CreateHttpClient())
                    using (HttpResponseMessage resp = await client.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead))
                    {
                        Assert.Equal(headerValue, resp.Headers.GetValues(headerName).Single());
                        Assert.Equal(ContentString, await resp.Content.ReadAsStringAsync());
                    }
            },
                                                                   async server =>
            {
                var headers = new List <HttpHeaderData>();
                headers.Add(new HttpHeaderData(headerName, headerValue));
                await server.HandleRequestAsync(HttpStatusCode.OK, headers: headers, content: ContentString);
            });
        }
        public async Task SendAsync_Cancel_CancellationTokenPropagates()
        {
            TaskCompletionSource <bool> clientCanceled = new TaskCompletionSource <bool>();
            await LoopbackServerFactory.CreateClientAndServerAsync(
                async uri =>
            {
                var cts = new CancellationTokenSource();
                cts.Cancel();

                using (HttpClient client = CreateHttpClient())
                {
                    OperationCanceledException ex = null;
                    try
                    {
                        await client.GetAsync(uri, cts.Token);
                    }
                    catch (OperationCanceledException e)
                    {
                        ex = e;
                    }
                    Assert.True(ex != null, "Expected OperationCancelledException, but no exception was thrown.");

                    Assert.True(cts.Token.IsCancellationRequested, "cts token IsCancellationRequested");

                    if (!PlatformDetection.IsFullFramework)
                    {
                        // .NET Framework has bug where it doesn't propagate token information.
                        Assert.True(ex.CancellationToken.IsCancellationRequested, "exception token IsCancellationRequested");
                    }
                    clientCanceled.SetResult(true);
                }
            },
                async server =>
            {
                Task serverTask = server.HandleRequestAsync();
                await clientCanceled.Task;
            });
        }
        public async Task GetAsync_AddMultipleCookieHeaders_CookiesSent()
        {
            await LoopbackServerFactory.CreateClientAndServerAsync(
                async uri =>
            {
                using (HttpClient client = CreateHttpClient())
                {
                    var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri)
                    {
                        Version = UseVersion
                    };
                    requestMessage.Headers.Add("Cookie", "A=1");
                    requestMessage.Headers.Add("Cookie", "B=2");
                    requestMessage.Headers.Add("Cookie", "C=3");

                    await client.SendAsync(TestAsync, requestMessage);
                }
            },
                async server =>
            {
                HttpRequestData requestData = await server.HandleRequestAsync();

                // Multiple Cookie header values are concatenated using "; " as the separator.

                string cookieHeaderValue = requestData.GetSingleHeaderValue("Cookie");

#if NETFRAMEWORK
                var separator = ", ";
#else
                var separator = "; ";
#endif
                var cookieValues = cookieHeaderValue.Split(new string[] { separator }, StringSplitOptions.None);
                Assert.Contains("A=1", cookieValues);
                Assert.Contains("B=2", cookieValues);
                Assert.Contains("C=3", cookieValues);
                Assert.Equal(3, cookieValues.Count());
            });
        }
Esempio n. 24
0
        public async Task GetAsync_ReceiveInvalidSetCookieHeader_ValidCookiesAdded()
        {
            if (IsNetfxHandler)
            {
                // NetfxHandler incorrectly only processes one valid cookie
                return;
            }

            await LoopbackServerFactory.CreateServerAsync(async (server, url) =>
            {
                HttpClientHandler handler = CreateHttpClientHandler();

                using (HttpClient client = new HttpClient(handler))
                {
                    Task <HttpResponseMessage> getResponseTask = client.GetAsync(url);
                    Task <HttpRequestData> serverTask          = server.HandleRequestAsync(
                        HttpStatusCode.OK,
                        new HttpHeaderData[]
                    {
                        new HttpHeaderData("Set-Cookie", "A=1; Path=/;Expires=asdfsadgads"),     // invalid Expires
                        new HttpHeaderData("Set-Cookie", "B=2; Path=/"),
                        new HttpHeaderData("Set-Cookie", "C=3; Path=/")
                    },
                        s_simpleContent);
                    await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                    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[3];
                    collection.CopyTo(cookies, 0);

                    Assert.Contains(cookies, c => c.Name == "B" && c.Value == "2");
                    Assert.Contains(cookies, c => c.Name == "C" && c.Value == "3");
                }
            });
        }
        [InlineData("Max-Forwards", "NotAnInteger", false)]                 // invalid format for header but added with TryAddWithoutValidation
        public async Task SendAsync_SpecialHeaderKeyOrValue_Success(string key, string value, bool parsable)
        {
            await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
            {
                bool contentHeader = false;
                using (HttpClient client = CreateHttpClient())
                {
                    var message = new HttpRequestMessage(HttpMethod.Get, uri)
                    {
                        Version = VersionFromUseHttp2
                    };
                    if (!message.Headers.TryAddWithoutValidation(key, value))
                    {
                        message.Content = new StringContent("");
                        contentHeader   = message.Content.Headers.TryAddWithoutValidation(key, value);
                    }
                    (await client.SendAsync(message).ConfigureAwait(false)).Dispose();
                }

                // Validate our test by validating our understanding of a header's parsability.
                HttpHeaders headers = contentHeader ? (HttpHeaders)
                                      new StringContent("").Headers :
                                      new HttpRequestMessage().Headers;
                if (parsable)
                {
                    headers.Add(key, value);
                }
                else
                {
                    Assert.Throws <FormatException>(() => headers.Add(key, value));
                }
            },
                                                                   async server =>
            {
                HttpRequestData requestData = await server.HandleRequestAsync(HttpStatusCode.OK);
                Assert.Equal(value, requestData.GetSingleHeaderValue(key));
            });
        }
        public async Task UnreadResponseMessage_Collectible()
        {
            await LoopbackServerFactory.CreateServerAsync(async (server, url) =>
            {
                using (HttpClient client = CreateHttpClient())
                {
                    Func <Task <WeakReference> > getAsync = () => client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).ContinueWith(t => new WeakReference(t.Result));

                    Task <WeakReference> wrt = getAsync();

                    await server.HandleRequestAsync(content: new string('a', 16 * 1024));

                    WeakReference wr = wrt.GetAwaiter().GetResult();
                    Assert.True(SpinWait.SpinUntil(() =>
                    {
                        GC.Collect();
                        GC.WaitForPendingFinalizers();
                        GC.Collect();
                        return(!wr.IsAlive);
                    }, 10 * 1000), "Response object should have been collected");
                }
            });
        }
Esempio n. 27
0
        public async Task Dispose_HandlerWithProxy_ProxyNotDisposed()
        {
            var proxy = new TrackDisposalProxy();

            await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
            {
                using (HttpClientHandler handler = CreateHttpClientHandler())
                {
                    handler.UseProxy = true;
                    handler.Proxy    = proxy;
                    using (HttpClient client = CreateHttpClient(handler))
                    {
                        Assert.Equal("hello", await client.GetStringAsync(uri));
                    }
                }
            }, async server =>
            {
                await server.HandleRequestAsync(content: "hello");
            });

            Assert.True(proxy.ProxyUsed);
            Assert.False(proxy.Disposed);
        }
        public async Task GetAsync_EmptyResponseHeader_Success()
        {
            IList <HttpHeaderData> headers = new HttpHeaderData[] {
                new HttpHeaderData("x-test", "SendAsync_EmptyHeader_Success"),
                new HttpHeaderData("x-empty", ""),
                new HttpHeaderData("x-last", "bye")
            };

            await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
            {
                using (HttpClient client = CreateHttpClient())
                {
                    HttpResponseMessage response = await client.GetAsync(uri).ConfigureAwait(false);
                    // HTTP/1.1 LoopbackServer adds Connection: close and Date to responses.
                    Assert.Equal(UseHttp2LoopbackServer ?  headers.Count : headers.Count + 2, response.Headers.Count());
                    Assert.NotNull(response.Headers.GetValues("x-empty"));
                }
            },
                                                                   async server =>
            {
                HttpRequestData requestData = await server.HandleRequestAsync(HttpStatusCode.OK, headers);
            });
        }
        public async Task SendAsync_InvalidHeader_Throw(string value)
        {
            await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                using (HttpClient client = CreateHttpClient())
                {
                    var request = new HttpRequestMessage(HttpMethod.Get, uri);
                    Assert.True(request.Headers.TryAddWithoutValidation("bad", value));

                    await Assert.ThrowsAsync <HttpRequestException>(() => client.SendAsync(request));
                }
            },
                                                                   async server =>
            {
                try
                {
                    // Client should abort at some point so this is going to throw.
                    HttpRequestData requestData = await server.HandleRequestAsync(HttpStatusCode.OK).ConfigureAwait(false);
                }
                catch (IOException) { };
            });
        }
Esempio n. 30
0
        public async Task IncompleteResponseStream_ResponseDropped_CancelsRequestToServer()
        {
            if (UseVersion == HttpVersion30)
            {
                // [ActiveIssue("https://github.com/dotnet/runtime/issues/58234")]
                return;
            }

            using (HttpClient client = CreateHttpClient())
            {
                bool stopGCs = false;
                await LoopbackServerFactory.CreateClientAndServerAsync(async url =>
                {
                    await GetAndDropResponse(client, url);

                    while (!Volatile.Read(ref stopGCs))
                    {
                        await Task.Delay(10);
                        GC.Collect();
                        GC.WaitForPendingFinalizers();
                    }
                },
                                                                       server => server.AcceptConnectionAsync(async connection =>
                {
                    try
                    {
                        HttpRequestData data = await connection.ReadRequestDataAsync(readBody: false);
                        await connection.SendResponseHeadersAsync(headers: new HttpHeaderData[] { new HttpHeaderData("SomeHeaderName", "AndValue") });
                        await connection.WaitForCancellationAsync();
                    }
                    finally
                    {
                        Volatile.Write(ref stopGCs, true);
                    }
                }));
            }
        }