Пример #1
0
        public async Task GetAsync_SetCookieContainerAndCookieHeader_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", s_customCookieHeaderValue);

                    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);
                    var cookies = cookieHeaderValue.Split(new string[] { "; " }, StringSplitOptions.None);
                    Assert.Contains(s_expectedCookieHeaderValue, cookies);
                    Assert.Contains(s_customCookieHeaderValue, cookies);
                    Assert.Equal(2, cookies.Count());
                }
            });
        }
        public async Task GetAsync_CancelDuringResponseBodyReceived_Buffered_TaskCanceledQuickly(bool chunkedTransfer, bool connectionClose, CancellationMode mode)
        {
            if (LoopbackServerFactory.Version >= HttpVersion20.Value && (chunkedTransfer || connectionClose))
            {
                // There is no chunked encoding or connection header in HTTP/2 and later
                return;
            }

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

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

                    Task serverTask = server.AcceptConnectionAsync(async connection =>
                    {
                        var headers = new List <HttpHeaderData>();
                        headers.Add(chunkedTransfer ? new HttpHeaderData("Transfer-Encoding", "chunked") : new HttpHeaderData("Content-Length", "20"));
                        if (connectionClose)
                        {
                            headers.Add(new HttpHeaderData("Connection", "close"));
                        }

                        await connection.ReadRequestDataAsync();
                        await connection.SendResponseAsync(HttpStatusCode.OK, headers: headers, content: "123", isFinal: false);
                        responseHeadersSent.TrySetResult(true);
                        await clientFinished.Task;
                    });

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

                        Task <HttpResponseMessage> getResponse = client.SendAsync(TestAsync, req, HttpCompletionOption.ResponseContentRead, cts.Token);
                        await responseHeadersSent.Task;
                        await Task.Delay(1); // make it more likely that client will have started processing response body
                        Cancel(mode, client, cts);
                        await getResponse;
                    });

                    try
                    {
                        clientFinished.SetResult(true);
                        await serverTask;
                    }
                    catch (Exception ex)
                    {
                        _output.WriteLine($"Ignored exception:{Environment.NewLine}{ex}");
                    }
                });
            }
        }
Пример #3
0
        public async Task GetAsync_CookiePathDoesNotMatchRequestPath_CookieAccepted()
        {
            await LoopbackServerFactory.CreateServerAsync(async (server, serverUrl) =>
            {
                Uri requestUrl            = new Uri(serverUrl, "original");
                Uri otherUrl              = new Uri(serverUrl, "other");
                HttpClientHandler handler = CreateHttpClientHandler();

                using (HttpClient client = CreateHttpClient(handler))
                {
                    Task <HttpResponseMessage> getResponseTask = client.GetAsync(requestUrl);
                    Task <HttpRequestData> serverTask          = server.HandleRequestAsync(
                        HttpStatusCode.OK,
                        new[]
                    {
                        new HttpHeaderData("Set-Cookie", "A=1; Path=/other"),
                    },
                        s_simpleContent);
                    await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                    Cookie cookie = handler.CookieContainer.GetCookies(otherUrl)[0];
                    Assert.Equal("/other", cookie.Path);
                }
            });
        }
Пример #4
0
        public async Task GetAsync_ReceiveSetCookieHeader_CookieAdded(string cookieName, string cookieValue, bool useCookies)
        {
            await LoopbackServerFactory.CreateServerAsync(async (server, url) =>
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                handler.UseCookies        = useCookies;

                using (HttpClient client = CreateHttpClient(handler))
                {
                    Task <HttpResponseMessage> getResponseTask = client.GetAsync(url);
                    Task <HttpRequestData> serverTask          = server.HandleRequestAsync(
                        HttpStatusCode.OK, new HttpHeaderData[] { new HttpHeaderData("Set-Cookie", GetCookieHeaderValue(cookieName, cookieValue)) }, s_simpleContent);
                    await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                    CookieCollection collection = handler.CookieContainer.GetCookies(url);

                    if (useCookies)
                    {
                        Assert.Equal(1, collection.Count);
                        Assert.Equal(cookieName, collection[0].Name);
                        Assert.Equal(cookieValue, collection[0].Value);
                    }
                    else
                    {
                        Assert.Equal(0, collection.Count);
                    }
                }
            });
        }
Пример #5
0
        public async Task GetAsync_ReceiveSetCookieHeader_CookieUpdated()
        {
            const string newCookieValue = "789";

            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}={newCookieValue}") },
                        s_simpleContent);
                    await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                    CookieCollection collection = handler.CookieContainer.GetCookies(url);
                    Assert.Equal(1, collection.Count);
                    Assert.Equal(s_cookieName, collection[0].Name);
                    Assert.Equal(newCookieValue, collection[0].Value);
                }
            });
        }
Пример #6
0
        public async Task GetAsync_ReceiveInvalidSetCookieHeader_ValidCookiesAdded()
        {
            await LoopbackServerFactory.CreateServerAsync(async (server, url) =>
            {
                HttpClientHandler handler = CreateHttpClientHandler();

                using (HttpClient client = CreateHttpClient(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");
                }
            });
        }
        public async Task GetAsync_CancelDuringResponseBodyReceived_Unbuffered_TaskCanceledQuickly(bool chunkedTransfer, bool connectionClose, bool readOrCopyToAsync)
        {
            if (LoopbackServerFactory.Version >= HttpVersion20.Value && (chunkedTransfer || connectionClose))
            {
                // There is no chunked encoding or connection header in HTTP/2 and later
                return;
            }

#if WINHTTPHANDLER_TEST
            if (UseVersion >= HttpVersion20.Value)
            {
                throw new SkipTestException($"Test doesn't support {UseVersion} protocol.");
            }
#endif

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

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

                    Task serverTask = server.AcceptConnectionAsync(async connection =>
                    {
                        var headers = new List<HttpHeaderData>();
                        headers.Add(chunkedTransfer ? new HttpHeaderData("Transfer-Encoding", "chunked") : new HttpHeaderData("Content-Length", "20"));
                        if (connectionClose)
                        {
                            headers.Add(new HttpHeaderData("Connection", "close"));
                        }

                        await connection.ReadRequestDataAsync();
                        await connection.SendResponseAsync(HttpStatusCode.OK, headers: headers, isFinal: false);
                        await clientFinished.Task;
                    });

                    var req = new HttpRequestMessage(HttpMethod.Get, url) { Version = UseVersion };
                    req.Headers.ConnectionClose = connectionClose;
                    Task<HttpResponseMessage> getResponse = client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead, cts.Token);
                    await ValidateClientCancellationAsync(async () =>
                    {
                        HttpResponseMessage resp = await getResponse;
                        Stream respStream = await resp.Content.ReadAsStreamAsync();
                        Task readTask = readOrCopyToAsync ?
                            respStream.ReadAsync(new byte[1], 0, 1, cts.Token) :
                            respStream.CopyToAsync(Stream.Null, 10, cts.Token);
                        cts.Cancel();
                        await readTask;
                    });

                    try
                    {
                        clientFinished.SetResult(true);
                        await serverTask;
                    } catch { }
                });
            }
        }
Пример #8
0
        public async Task GetAsync_SetCookieContainerAndCookieHeader_BothCookiesSent()
        {
            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.
                throw new SkipTestException("Platform limitation with curl");
            }

            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    = GetCookieValue(requestData);
                    var cookies = cookieHeaderValue.Split(new string[] { "; " }, StringSplitOptions.None);
                    Assert.Contains(s_expectedCookieHeaderValue, cookies);
                    Assert.Contains(s_customCookieHeaderValue, cookies);
                    Assert.Equal(2, cookies.Count());
                }
            });
        }
Пример #9
0
        public async Task GetAsync_SetCookieContainerAndMultipleCookieHeaders_BothCookiesSent()
        {
            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.
                throw new SkipTestException("Platform limitation with curl");
            }

            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 = VersionFromUseHttp2
                    };
                    requestMessage.Headers.Add("Cookie", "A=1");
                    requestMessage.Headers.Add("Cookie", "B=2");

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

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

                    // 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 cookieValues = cookieHeaderValue.Split(new string[] { ", " }, StringSplitOptions.None);
                    Assert.Equal(2, cookieValues.Count());

                    // Find container cookie and remove it so we can validate the rest of the cookie header values
                    bool sawContainerCookie = false;
                    for (int i = 0; i < cookieValues.Length; i++)
                    {
                        if (cookieValues[i].Contains(';'))
                        {
                            Assert.False(sawContainerCookie);

                            var cookies = cookieValues[i].Split(new string[] { "; " }, StringSplitOptions.None);
                            Assert.Equal(2, cookies.Count());
                            Assert.Contains(s_expectedCookieHeaderValue, cookies);

                            sawContainerCookie = true;
                            cookieValues[i]    = cookies.Where(c => c != s_expectedCookieHeaderValue).Single();
                        }
                    }

                    Assert.Contains("A=1", cookieValues);
                    Assert.Contains("B=2", cookieValues);
                }
            });
        }
        public async Task GetAsync_CancelDuringResponseHeadersReceived_TaskCanceledQuickly(bool connectionClose, CancellationMode mode)
        {
            if (LoopbackServerFactory.Version >= HttpVersion20.Value && connectionClose)
            {
                // There is no Connection header in HTTP/2 and later
                return;
            }

            if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
            {
                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.SendPartialResponseHeadersAsync(HttpStatusCode.OK);

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

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

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

                    try
                    {
                        clientFinished.SetResult(true);
                        await serverTask;
                    }
                    catch (Exception ex)
                    {
                        _output.WriteLine($"Ignored exception:{Environment.NewLine}{ex}");
                    }
                });
            }
        }
Пример #11
0
        public async Task GetAsync_CancelDuringResponseHeadersReceived_TaskCanceledQuickly(bool connectionClose, CancellationMode mode)
        {
            if (LoopbackServerFactory.Version >= HttpVersion20.Value && connectionClose)
            {
                // There is no Connection header in HTTP/2 and later
                return;
            }

#if WINHTTPHANDLER_TEST
            if (UseVersion >= HttpVersion20.Value)
            {
                throw new SkipTestException($"Test doesn't support {UseVersion} protocol.");
            }
#endif

            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 = UseVersion
                        };
                        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 { }
                });
            }
        }
        public async Task GetAsync_CancelDuringResponseHeadersReceived_TaskCanceledQuickly(bool chunkedTransfer, 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 { }
                });
            }
        }
Пример #13
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();
            });
        }
Пример #14
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();
        }
Пример #15
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());
                }
            });
        }
Пример #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());
                }
            });
        }
Пример #18
0
        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");
                }
            });
        }
Пример #19
0
        public async Task GetAsync_NoPathDefined_CookieAddedWithDefaultPath()
        {
            await LoopbackServerFactory.CreateServerAsync(async (server, serverUrl) =>
            {
                Uri requestUrl            = new Uri(serverUrl, "path/sub");
                HttpClientHandler handler = CreateHttpClientHandler();

                using (HttpClient client = CreateHttpClient(handler))
                {
                    Task <HttpResponseMessage> getResponseTask = client.GetAsync(requestUrl);
                    Task <HttpRequestData> serverTask          = server.HandleRequestAsync(
                        HttpStatusCode.OK,
                        new HttpHeaderData[]
                    {
                        new HttpHeaderData("Set-Cookie", "A=1"),
                    },
                        s_simpleContent);
                    await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                    Cookie cookie = handler.CookieContainer.GetCookies(requestUrl)[0];
                    Assert.Equal("/path", cookie.Path);
                }
            });
        }
        public async Task GetAsync_CancelPendingRequests_DoesntCancelReadAsyncOnResponseStream(CancellationMode mode, bool copyToAsync)
        {
            if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
            {
                return;
            }

            using (HttpClient client = CreateHttpClient())
            {
                client.Timeout = Timeout.InfiniteTimeSpan;

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

                    var responseContentSegment = new string('s', 3000);
                    int responseSegments       = 4;
                    int contentLength          = responseContentSegment.Length * responseSegments;

                    Task serverTask = server.AcceptConnectionAsync(async connection =>
                    {
                        await connection.ReadRequestDataAsync();
                        await connection.SendResponseAsync(HttpStatusCode.OK, headers: new HttpHeaderData[] { new HttpHeaderData("Content-Length", contentLength.ToString()) }, isFinal: false);
                        for (int i = 0; i < responseSegments; i++)
                        {
                            await connection.SendResponseBodyAsync(responseContentSegment, isFinal: i == responseSegments - 1);
                            if (i == 0)
                            {
                                await clientReadSomeBody.Task;
                            }
                        }

                        await clientFinished.Task;
                    });


                    using (HttpResponseMessage resp = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
                        using (Stream respStream = await resp.Content.ReadAsStreamAsync(TestAsync))
                        {
                            var result = new MemoryStream();
                            int b      = respStream.ReadByte();
                            Assert.NotEqual(-1, b);
                            result.WriteByte((byte)b);

                            Cancel(mode, client, null); // should not cancel the operation, as using ResponseHeadersRead
                            clientReadSomeBody.SetResult(true);

                            if (copyToAsync)
                            {
                                await respStream.CopyToAsync(result, 10, new CancellationTokenSource().Token);
                            }
                            else
                            {
                                byte[] buffer = new byte[10];
                                int bytesRead;
                                while ((bytesRead = await respStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                                {
                                    result.Write(buffer, 0, bytesRead);
                                }
                            }

                            Assert.Equal(contentLength, result.Length);
                        }

                    clientFinished.SetResult(true);
                    await serverTask;
                });
            }
        }
Пример #21
0
        public async Task GetAsync_CancelDuringResponseBodyReceived_Unbuffered_TaskCanceledQuickly(bool chunkedTransfer, bool connectionClose, bool readOrCopyToAsync)
        {
            if (LoopbackServerFactory.Version >= HttpVersion20.Value && (chunkedTransfer || connectionClose))
            {
                // There is no chunked encoding or connection header in HTTP/2 and later
                return;
            }

            if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
            {
                return;
            }

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

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

                    Task serverTask = server.AcceptConnectionAsync(async connection =>
                    {
                        var headers = new List <HttpHeaderData>();
                        headers.Add(chunkedTransfer ? new HttpHeaderData("Transfer-Encoding", "chunked") : new HttpHeaderData("Content-Length", "20"));
                        if (connectionClose)
                        {
                            headers.Add(new HttpHeaderData("Connection", "close"));
                        }

                        await connection.ReadRequestDataAsync();
                        await connection.SendResponseAsync(HttpStatusCode.OK, headers: headers, isFinal: false);
                        await clientFinished.Task;

#if TARGET_BROWSER
                        // make sure that the browser closed the connection
                        await connection.WaitForCloseAsync(CancellationToken.None);
#endif
                    });

                    var req = new HttpRequestMessage(HttpMethod.Get, url)
                    {
                        Version = UseVersion
                    };
                    req.Headers.ConnectionClose = connectionClose;

#if TARGET_BROWSER
                    var WebAssemblyEnableStreamingResponseKey = new HttpRequestOptionsKey <bool>("WebAssemblyEnableStreamingResponse");
                    req.Options.Set(WebAssemblyEnableStreamingResponseKey, true);
#endif

                    Task <HttpResponseMessage> getResponse = client.SendAsync(TestAsync, req, HttpCompletionOption.ResponseHeadersRead, cts.Token);
                    await ValidateClientCancellationAsync(async() =>
                    {
                        HttpResponseMessage resp = await getResponse;
                        Stream respStream        = await resp.Content.ReadAsStreamAsync(TestAsync);
                        Task readTask            = readOrCopyToAsync ?
                                                   respStream.ReadAsync(new byte[1], 0, 1, cts.Token) :
                                                   respStream.CopyToAsync(Stream.Null, 10, cts.Token);
                        cts.Cancel();
                        await readTask;
                    }).WaitAsync(TimeSpan.FromSeconds(30));
                    try
                    {
                        clientFinished.SetResult(true);
                        await serverTask;
                    }
                    catch (Exception ex)
                    {
                        _output.WriteLine($"Ignored exception:{Environment.NewLine}{ex}");
                    }
                });
            }
        }