diff options
author | Marek Safar <marek.safar@gmail.com> | 2017-02-14 18:20:31 +0300 |
---|---|---|
committer | Marek Safar <marek.safar@gmail.com> | 2017-02-15 15:10:43 +0300 |
commit | e98d3b9ca203a0d561e853209da88d621021cad7 (patch) | |
tree | 21694a44f350bc17678e4d8a4604f099188f5b99 /mcs/class/System.Net.Http | |
parent | b472a0391ca66b87e86e8406e0702dc2b1e66deb (diff) |
[System.Net.Http] Add Transfer-Encoding: chunked special handling. Fixes #47599
Diffstat (limited to 'mcs/class/System.Net.Http')
-rw-r--r-- | mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs | 28 | ||||
-rw-r--r-- | mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs | 104 |
2 files changed, 122 insertions, 10 deletions
diff --git a/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs b/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs index a3335ea5506..e1cd94a05a4 100644 --- a/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs +++ b/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs @@ -292,8 +292,9 @@ namespace System.Net.Http } if (header.Key == "Transfer-Encoding") { - // Chunked Transfer-Encoding is never set for HttpWebRequest. It's detected - // from ContentLength by HttpWebRequest + // + // Chunked Transfer-Encoding is set for HttpWebRequest later when Content length is checked + // values = values.Where (l => l != "chunked"); } @@ -354,15 +355,22 @@ namespace System.Net.Http } } - // - // Content length has to be set because HttpWebRequest is running without buffering - // - var contentLength = content.Headers.ContentLength; - if (contentLength != null) { - wrequest.ContentLength = contentLength.Value; + if (request.Headers.TransferEncodingChunked == true) { + wrequest.SendChunked = true; } else { - await content.LoadIntoBufferAsync (MaxRequestContentBufferSize).ConfigureAwait (false); - wrequest.ContentLength = content.Headers.ContentLength.Value; + // + // Content length has to be set because HttpWebRequest is running without buffering + // + var contentLength = content.Headers.ContentLength; + if (contentLength != null) { + wrequest.ContentLength = contentLength.Value; + } else { + if (MaxRequestContentBufferSize == 0) + throw new InvalidOperationException ("The content length of the request content can't be determined. Either set TransferEncodingChunked to true, load content into buffer, or set MaxRequestContentBufferSize."); + + await content.LoadIntoBufferAsync (MaxRequestContentBufferSize).ConfigureAwait (false); + wrequest.ContentLength = content.Headers.ContentLength.Value; + } } wrequest.ResendContentFactory = content.CopyTo; diff --git a/mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs b/mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs index d9aab417dfa..72508c48833 100644 --- a/mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs +++ b/mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs @@ -1094,6 +1094,110 @@ namespace MonoTests.System.Net.Http } [Test] +#if FEATURE_NO_BSD_SOCKETS + [ExpectedException (typeof (PlatformNotSupportedException))] +#endif + public void Post_TransferEncodingChunked () + { + bool? failed = null; + var listener = CreateListener (l => { + try { + var request = l.Request; + + Assert.IsNull (request.AcceptTypes, "#1"); + Assert.AreEqual (-1, request.ContentLength64, "#2"); + Assert.IsNull (request.ContentType, "#3"); + Assert.AreEqual (0, request.Cookies.Count, "#4"); + Assert.IsTrue (request.HasEntityBody, "#5"); + Assert.AreEqual (TestHost, request.Headers ["Host"], "#6b"); + Assert.AreEqual ("POST", request.HttpMethod, "#7"); + Assert.IsFalse (request.IsAuthenticated, "#8"); + Assert.IsTrue (request.IsLocal, "#9"); + Assert.IsFalse (request.IsSecureConnection, "#10"); + Assert.IsFalse (request.IsWebSocketRequest, "#11"); + Assert.IsTrue (request.KeepAlive, "#12"); + Assert.AreEqual (HttpVersion.Version11, request.ProtocolVersion, "#13"); + Assert.IsNull (request.ServiceName, "#14"); + Assert.IsNull (request.UrlReferrer, "#15"); + Assert.IsNull (request.UserAgent, "#16"); + Assert.IsNull (request.UserLanguages, "#17"); + Assert.AreEqual ("chunked", request.Headers ["Transfer-Encoding"], "#18"); + Assert.IsNull (request.Headers ["Content-Length"], "#19"); + failed = false; + } catch (Exception e) { + failed = true; + Console.WriteLine (e); + } + }); + + try { + var client = new HttpClient (); + + client.DefaultRequestHeaders.TransferEncodingChunked = true; + + var imageContent = new StreamContent (new MemoryStream ()); + + var response = client.PostAsync (LocalServer, imageContent).Result; + + Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, "#101"); + Assert.AreEqual(false, failed, "#102"); + } finally { + listener.Close (); + } + } + + [Test] +#if FEATURE_NO_BSD_SOCKETS + [ExpectedException (typeof (PlatformNotSupportedException))] +#endif + public void Post_StreamCaching () + { + bool? failed = null; + var listener = CreateListener (l => { + try { + var request = l.Request; + + Assert.IsNull (request.AcceptTypes, "#1"); + Assert.AreEqual (0, request.ContentLength64, "#2"); + Assert.IsNull (request.ContentType, "#3"); + Assert.AreEqual (0, request.Cookies.Count, "#4"); + Assert.IsFalse (request.HasEntityBody, "#5"); + Assert.AreEqual (TestHost, request.Headers ["Host"], "#6b"); + Assert.AreEqual ("POST", request.HttpMethod, "#7"); + Assert.IsFalse (request.IsAuthenticated, "#8"); + Assert.IsTrue (request.IsLocal, "#9"); + Assert.IsFalse (request.IsSecureConnection, "#10"); + Assert.IsFalse (request.IsWebSocketRequest, "#11"); + Assert.IsTrue (request.KeepAlive, "#12"); + Assert.AreEqual (HttpVersion.Version11, request.ProtocolVersion, "#13"); + Assert.IsNull (request.ServiceName, "#14"); + Assert.IsNull (request.UrlReferrer, "#15"); + Assert.IsNull (request.UserAgent, "#16"); + Assert.IsNull (request.UserLanguages, "#17"); + Assert.IsNull (request.Headers ["Transfer-Encoding"], "#18"); + Assert.AreEqual ("0", request.Headers ["Content-Length"], "#19"); + failed = false; + } catch (Exception e) { + failed = true; + Console.WriteLine (e); + } + }); + + try { + var client = new HttpClient (); + + var imageContent = new StreamContent (new MemoryStream ()); + + var response = client.PostAsync (LocalServer, imageContent).Result; + + Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, "#101"); + Assert.AreEqual(false, failed, "#102"); + } finally { + listener.Close (); + } + } + + [Test] [Category ("MobileNotWorking")] // Missing encoding #if FEATURE_NO_BSD_SOCKETS [ExpectedException (typeof (PlatformNotSupportedException))] |