diff options
author | Marek Safar <marek.safar@gmail.com> | 2017-02-13 18:05:54 +0300 |
---|---|---|
committer | Marek Safar <marek.safar@gmail.com> | 2017-02-14 00:38:15 +0300 |
commit | e4bd4dbb153c2986758bb1339989d9d1861df4f5 (patch) | |
tree | 129a43b661ee0eadf611c81fd3f60963d816b46e /mcs/class/System.Net.Http | |
parent | 7bfb9bcb78255b5314e3c9f5489a76e74154435b (diff) |
[System.Net.Http] Allow re-sending StreamContent. Fixes #52448
Diffstat (limited to 'mcs/class/System.Net.Http')
-rw-r--r-- | mcs/class/System.Net.Http/System.Net.Http/StreamContent.cs | 18 | ||||
-rw-r--r-- | mcs/class/System.Net.Http/Test/System.Net.Http/StreamContentTest.cs | 30 |
2 files changed, 45 insertions, 3 deletions
diff --git a/mcs/class/System.Net.Http/System.Net.Http/StreamContent.cs b/mcs/class/System.Net.Http/System.Net.Http/StreamContent.cs index a249aad6f5b..b8c27858a26 100644 --- a/mcs/class/System.Net.Http/System.Net.Http/StreamContent.cs +++ b/mcs/class/System.Net.Http/System.Net.Http/StreamContent.cs @@ -37,6 +37,8 @@ namespace System.Net.Http readonly Stream content; readonly int bufferSize; readonly CancellationToken cancellationToken; + readonly long startPosition; + bool contentCopied; public StreamContent (Stream content) : this (content, 16 * 1024) @@ -53,6 +55,10 @@ namespace System.Net.Http this.content = content; this.bufferSize = bufferSize; + + if (content.CanSeek) { + startPosition = content.Position; + } } // @@ -83,6 +89,16 @@ namespace System.Net.Http protected internal override Task SerializeToStreamAsync (Stream stream, TransportContext context) { + if (contentCopied) { + if (!content.CanSeek) { + throw new InvalidOperationException ("The stream was already consumed. It cannot be read again."); + } + + content.Seek (startPosition, SeekOrigin.Begin); + } else { + contentCopied = true; + } + return content.CopyToAsync (stream, bufferSize, cancellationToken); } @@ -92,7 +108,7 @@ namespace System.Net.Http length = 0; return false; } - length = content.Length; + length = content.Length - startPosition; return true; } } diff --git a/mcs/class/System.Net.Http/Test/System.Net.Http/StreamContentTest.cs b/mcs/class/System.Net.Http/Test/System.Net.Http/StreamContentTest.cs index e5609474126..a7c9875186c 100644 --- a/mcs/class/System.Net.Http/Test/System.Net.Http/StreamContentTest.cs +++ b/mcs/class/System.Net.Http/Test/System.Net.Http/StreamContentTest.cs @@ -149,8 +149,8 @@ namespace MonoTests.System.Net.Http /* sc = new StreamContent (new ExceptionStream ()); try { - sc.CopyToAsync (m).Wait (); - Assert.Fail ("#2"); + sc.CopyToAsync (m).Wait (); + Assert.Fail ("#2"); } catch (AggregateException) { } */ @@ -191,6 +191,32 @@ namespace MonoTests.System.Net.Http } [Test] + public void CopyToAsync_Twice () + { + var ms = new MemoryStream(); + ms.WriteByte(4); + ms.WriteByte(12); + ms.WriteByte(7); + ms.Seek(1, SeekOrigin.Begin); + + var sc = new StreamContent(ms); + + var dest = new MemoryStream(); + var task = sc.CopyToAsync(dest); + Assert.True(task.Wait(3000), "#0"); + Assert.AreEqual(2, dest.Length, "#1"); + dest.Seek(0, SeekOrigin.Begin); + Assert.AreEqual(12, dest.ReadByte(), "#2"); + + dest = new MemoryStream(); + task = sc.CopyToAsync(dest); + Assert.True(task.Wait(3000), "#10"); + Assert.AreEqual(2, dest.Length, "#11"); + dest.Seek(0, SeekOrigin.Begin); + Assert.AreEqual(12, dest.ReadByte(), "#12"); + } + + [Test] public void CopyToAsync_ClosedInput () { var stream = new MemoryStream (new byte[] { 1 }); |