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

Commit 90e9afd

Browse files
authored
Merge pull request #20469 from geoffkizer/port20428
Port HttpListener fix for disconnect while reading request body
2 parents a6c60a1 + d3318f1 commit 90e9afd

File tree

4 files changed

+28
-21
lines changed

4 files changed

+28
-21
lines changed

src/System.Net.HttpListener/src/System/Net/Managed/HttpRequestStream.Managed.cs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2929
//
3030

31+
using System.Diagnostics;
3132
using System.IO;
3233
using System.Net.Sockets;
3334
using System.Runtime.ExceptionServices;
@@ -103,9 +104,24 @@ protected virtual int ReadCore(byte[] buffer, int offset, int size)
103104
return nread;
104105
}
105106

107+
if (_remainingBody > 0)
108+
{
109+
size = (int)Math.Min(_remainingBody, (long)size);
110+
}
111+
106112
nread = _stream.Read(buffer, offset, size);
107-
if (nread > 0 && _remainingBody > 0)
113+
114+
if (_remainingBody > 0)
115+
{
116+
if (nread == 0)
117+
{
118+
throw new HttpListenerException((int)HttpStatusCode.BadRequest);
119+
}
120+
121+
Debug.Assert(nread <= _remainingBody);
108122
_remainingBody -= nread;
123+
}
124+
109125
return nread;
110126
}
111127

@@ -138,7 +154,7 @@ protected virtual IAsyncResult BeginReadCore(byte[] buffer, int offset, int size
138154
// for HTTP pipelining
139155
if (_remainingBody >= 0 && size > _remainingBody)
140156
{
141-
size = (int)Math.Min(int.MaxValue, _remainingBody);
157+
size = (int)Math.Min(_remainingBody, (long)size);
142158
}
143159

144160
return _stream.BeginRead(buffer, offset, size, cback, state);
@@ -182,8 +198,14 @@ public override int EndRead(IAsyncResult asyncResult)
182198
ExceptionDispatchInfo.Throw(e.InnerException);
183199
}
184200

185-
if (_remainingBody > 0 && nread > 0)
201+
if (_remainingBody > 0)
186202
{
203+
if (nread == 0)
204+
{
205+
throw new HttpListenerException((int)HttpStatusCode.BadRequest);
206+
}
207+
208+
Debug.Assert(nread <= _remainingBody);
187209
_remainingBody -= nread;
188210
}
189211

src/System.Net.HttpListener/tests/GetContextHelper.cs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,7 @@ public static class Helpers
6969

7070
public static void WaitForSocketShutdown(Socket socket)
7171
{
72-
if (PlatformDetection.IsWindows || PlatformDetection.IsOSX)
73-
{
74-
socket.Shutdown(SocketShutdown.Both);
75-
while (SocketConnected(socket));
76-
}
77-
else
78-
{
79-
socket.Close();
80-
}
72+
socket.Close();
8173
}
8274

8375
public static bool SocketConnected(Socket socket)

src/System.Net.HttpListener/tests/HttpListenerResponseTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,6 @@ public async Task CloseResponseEntity_SendMoreThanContentLength_ThrowsInvalidOpe
436436
}
437437
}
438438

439-
[ActiveIssue(20246)] // CI hanging frequently
440439
[ConditionalTheory(nameof(PlatformDetection) + "." + nameof(PlatformDetection.IsNotOneCoreUAP))]
441440
[InlineData(true)]
442441
[InlineData(false)]

src/System.Net.HttpListener/tests/HttpRequestStreamTests.cs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ public async Task EndRead_CalledTwice_ThrowsInvalidOperationException(bool chunk
482482
}
483483
}
484484

485-
[ConditionalFact(nameof(Helpers) + "." + nameof(Helpers.IsWindowsImplementationAndNotUap))] // [ActiveIssue(20246, TestPlatforms.AnyUnix)] // CI hanging frequently, [ActiveIssue(19983, platforms: TestPlatforms.AnyUnix)] // No exception thrown
485+
[ConditionalFact(nameof(PlatformDetection) + "." + nameof(PlatformDetection.IsNotOneCoreUAP))]
486486
public async Task Read_FromClosedConnectionAsynchronously_ThrowsHttpListenerException()
487487
{
488488
const string Text = "Some-String";
@@ -505,13 +505,10 @@ public async Task Read_FromClosedConnectionAsynchronously_ThrowsHttpListenerExce
505505
byte[] buffer = new byte[expected.Length];
506506
await Assert.ThrowsAsync<HttpListenerException>(() => context.Request.InputStream.ReadAsync(buffer, 0, buffer.Length));
507507
await Assert.ThrowsAsync<HttpListenerException>(() => context.Request.InputStream.ReadAsync(buffer, 0, buffer.Length));
508-
509-
// Closing a response from a closed client if no writing has failed should fail.
510-
Assert.Throws<HttpListenerException>(() => context.Response.Close());
511508
}
512509
}
513510

514-
[ConditionalFact(nameof(Helpers) + "." + nameof(Helpers.IsWindowsImplementationAndNotUap))] // [ActiveIssue(20246, TestPlatforms.AnyUnix)] // CI hanging frequently, [ActiveIssue(19983, platforms: TestPlatforms.AnyUnix)] // No exception thrown
511+
[ConditionalFact(nameof(PlatformDetection) + "." + nameof(PlatformDetection.IsNotOneCoreUAP))]
515512
public async Task Read_FromClosedConnectionSynchronously_ThrowsHttpListenerException()
516513
{
517514
const string Text = "Some-String";
@@ -534,9 +531,6 @@ public async Task Read_FromClosedConnectionSynchronously_ThrowsHttpListenerExcep
534531
byte[] buffer = new byte[expected.Length];
535532
Assert.Throws<HttpListenerException>(() => context.Request.InputStream.Read(buffer, 0, buffer.Length));
536533
Assert.Throws<HttpListenerException>(() => context.Request.InputStream.Read(buffer, 0, buffer.Length));
537-
538-
// Closing a response from a closed client if no writing has occured should fail.
539-
Assert.Throws<HttpListenerException>(() => context.Response.Close());
540534
}
541535
}
542536
}

0 commit comments

Comments
 (0)