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

Commit dbfa1eb

Browse files
authored
Add missing Shutdown calls in HTTP loopback servers (#25694)
1 parent a1e5d5c commit dbfa1eb

File tree

3 files changed

+25
-15
lines changed

3 files changed

+25
-15
lines changed

src/Common/tests/System/Net/Http/LoopbackServer.cs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public static Task<List<string>> ReadRequestAndSendResponseAsync(Socket server,
8989
return AcceptSocketAsync(server, (s, stream, reader, writer) => ReadWriteAcceptedAsync(s, reader, writer, response), options);
9090
}
9191

92-
public static async Task<List<string>> ReadWriteAcceptedAsync(Socket s, StreamReader reader, StreamWriter writer, string response = null, bool shutdown = true)
92+
public static async Task<List<string>> ReadWriteAcceptedAsync(Socket s, StreamReader reader, StreamWriter writer, string response = null)
9393
{
9494
// Read request line and headers. Skip any request body.
9595
var lines = new List<string>();
@@ -101,11 +101,6 @@ public static async Task<List<string>> ReadWriteAcceptedAsync(Socket s, StreamRe
101101

102102
await writer.WriteAsync(response ?? DefaultHttpResponse).ConfigureAwait(false);
103103

104-
if (shutdown)
105-
{
106-
s.Shutdown(SocketShutdown.Send);
107-
}
108-
109104
return lines;
110105
}
111106

@@ -157,7 +152,8 @@ private static string ComputeWebSocketHandshakeSecurityAcceptValue(string secWeb
157152
public static async Task<List<string>> AcceptSocketAsync(Socket server, Func<Socket, Stream, StreamReader, StreamWriter, Task<List<string>>> funcAsync, Options options = null)
158153
{
159154
options = options ?? new Options();
160-
using (Socket s = await server.AcceptAsync().ConfigureAwait(false))
155+
Socket s = await server.AcceptAsync().ConfigureAwait(false);
156+
try
161157
{
162158
Stream stream = new NetworkStream(s, ownsSocket: false);
163159
if (options.UseSsl)
@@ -166,9 +162,9 @@ public static async Task<List<string>> AcceptSocketAsync(Socket server, Func<Soc
166162
using (var cert = Configuration.Certificates.GetServerCertificate())
167163
{
168164
await sslStream.AuthenticateAsServerAsync(
169-
cert,
165+
cert,
170166
clientCertificateRequired: true, // allowed but not required
171-
enabledSslProtocols: options.SslProtocols,
167+
enabledSslProtocols: options.SslProtocols,
172168
checkCertificateRevocation: false).ConfigureAwait(false);
173169
}
174170
stream = sslStream;
@@ -180,6 +176,18 @@ await sslStream.AuthenticateAsServerAsync(
180176
return await funcAsync(s, stream, reader, writer).ConfigureAwait(false);
181177
}
182178
}
179+
finally
180+
{
181+
try
182+
{
183+
s.Shutdown(SocketShutdown.Send);
184+
s.Dispose();
185+
}
186+
catch (ObjectDisposedException)
187+
{
188+
// In case the test itself disposes of the socket
189+
}
190+
}
183191
}
184192

185193
public enum TransferType
@@ -250,8 +258,6 @@ public static Task StartTransferTypeAndErrorServer(
250258
await writer.WriteAsync($"{content}\r\n").ConfigureAwait(false);
251259
}
252260

253-
client.Shutdown(SocketShutdown.Both);
254-
255261
return null;
256262
}), out localEndPoint);
257263
}

src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1213,7 +1213,7 @@ await LoopbackServer.CreateServerAsync(async (server, url) =>
12131213
Task serverTask =
12141214
LoopbackServer.AcceptSocketAsync(server, async (s, stream, reader, writer) =>
12151215
{
1216-
var list = await LoopbackServer.ReadWriteAcceptedAsync(s, reader, writer, partialResponse, shutdown: false);
1216+
var list = await LoopbackServer.ReadWriteAcceptedAsync(s, reader, writer, partialResponse);
12171217
await tcs.Task;
12181218
return list;
12191219
}, null);

src/System.Net.Http/tests/FunctionalTests/LoopbackGetRequestHttpProxy.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ private static async Task<ProxyResult> StartAsync(TcpListener listener, bool req
4444
{
4545
// Get and parse the incoming request.
4646
Func<Task> getAndReadRequest = async () => {
47+
if (clientSocket != null)
48+
{
49+
clientSocket.Shutdown(SocketShutdown.Send);
50+
clientSocket.Dispose();
51+
}
52+
4753
clientSocket = await listener.AcceptSocketAsync().ConfigureAwait(false);
4854
clientStream = new NetworkStream(clientSocket, ownsSocket: false);
4955
clientReader = new StreamReader(clientStream, Encoding.ASCII);
@@ -68,9 +74,6 @@ await clientSocket.SendAsync(
6874
new ArraySegment<byte>(Encoding.ASCII.GetBytes("HTTP/1.1 407 Proxy Auth Required\r\nProxy-Authenticate: Basic\r\n\r\n")),
6975
SocketFlags.None).ConfigureAwait(false);
7076

71-
clientSocket.Shutdown(SocketShutdown.Send);
72-
clientSocket.Dispose();
73-
7477
if (expectCreds)
7578
{
7679
// Wait for a new connection that should have an auth header this time and parse it.
@@ -127,6 +130,7 @@ await clientSocket.SendAsync(
127130
}
128131
finally
129132
{
133+
clientSocket.Shutdown(SocketShutdown.Send);
130134
clientSocket.Dispose();
131135
listener.Stop();
132136
}

0 commit comments

Comments
 (0)