Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit e298b31

Browse files
committed
Bug 1188675:Project N Bug: .NET HttpClient can't do Authenticated POSTs due to limitations of System.IO.NetFxToWinRtStreamAdapter
This bug revolves around a design limitations of the System.Runtime.WindowsRuntime System.IO.NetFxToWinRtStreamAdapter. Due to the way that the adapter works, the Windows.Web.Http layer is unable to "rewind" data in order to re-send it to the server for POST requests. Resending request entity-body data to the server is frequently needed due to authentication challenges. The nature of this bug has resulted in a few common scenarios being broken for UWP (Windows 10 Store) apps that use System.Net.HttpClient or System.Net.HttpWebRequest. Even for simple content like StringContent (which is already buffered and not a stream, per se), we are unable to POST the data since the code paths were always using the limited NetFxToWinRtStreamAdapter. The fix for this bug is multi-layered. In general, we try to avoid using the NetFxToWinRtStreamAdapter for the POST scenarios. For content that is ByteArrayContent (or derived classes), the data is already "buffered". So, we don't need to send it as a stream. We also check if the data has been buffered via the developer calling LoadIntoBufferAsync() explicitly and send it as a buffer. Then, if the data is not buffered, we check the stream itself. If it already supports the WinRT Stream interfaces, then we don't need to use the adapter. So, third-party devs can create compatible, multi-interface (.NET and WinRT) stream content to be POSTed. [tfs-changeset: 1511754]
1 parent 4b6ce97 commit e298b31

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

src/System.Net.Http/src/System/Net/Http/ByteArrayContent.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ public ByteArrayContent(byte[] content)
2323
_content = content;
2424
_offset = 0;
2525
_count = content.Length;
26+
27+
#if NETNative
28+
SetBuffer(_content, _offset, _count);
29+
#endif
2630
}
2731

2832
public ByteArrayContent(byte[] content, int offset, int count)
@@ -43,6 +47,10 @@ public ByteArrayContent(byte[] content, int offset, int count)
4347
_content = content;
4448
_offset = offset;
4549
_count = count;
50+
51+
#if NETNative
52+
SetBuffer(_content, _offset, _count);
53+
#endif
4654
}
4755

4856
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)

src/System.Net.Http/src/System/Net/Http/HttpContent.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,23 @@ private bool IsBuffered
5252
get { return _bufferedContent != null; }
5353
}
5454

55+
#if NETNative
56+
internal void SetBuffer(byte[] buffer, int offset, int count)
57+
{
58+
_bufferedContent = new MemoryStream(buffer, offset, count, false, true);
59+
}
60+
61+
internal bool TryGetBuffer(out ArraySegment<byte> buffer)
62+
{
63+
if (_bufferedContent == null)
64+
{
65+
return false;
66+
}
67+
68+
return _bufferedContent.TryGetBuffer(out buffer);
69+
}
70+
#endif
71+
5572
protected HttpContent()
5673
{
5774
// Log to get an ID for the current content. This ID is used when the content gets associated to a message.

0 commit comments

Comments
 (0)