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

Commit f602b21

Browse files
authored
Fix HttpWebRequest when using system proxy settings (#31123)
While investigating other HttpClient/HttpWebRequest proxy-related bugs, I discovered that HttpWebRequest was not honoring system proxy settings as defined on Windows with IE settings or on Linux using environment variables. The problem is due to how HttpClient and HttpWebRequest differ in how they represent the default behavior of using system proxy settings with the various properties. Fixed HttpWebRequest so that it will translate the system proxy settings to the internal HttpClient/HttpClientHandler objects. I also removed an invalid Assert in HttpConnection. This assert was firing when using a proxy that was defined on the loopback adapter using IPv6 literal "[::1]". Due to issue #28863 with Uri, the Uri.IdnHost property doesn't have the brackets for IPv6 literals. So, the Assert was occuring. I did not add any new CI tests because it is currently not possible to test system proxy settings in CI since it involves changing machine configuration. But I ran manual tests.
1 parent 6c6b536 commit f602b21

3 files changed

Lines changed: 28 additions & 4 deletions

File tree

src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ public HttpConnectionPool(HttpConnectionPoolManager poolManager, HttpConnectionK
110110
Debug.Assert(port != 0);
111111
Debug.Assert(sslHostName == null);
112112
Debug.Assert(proxyUri != null);
113-
Debug.Assert(proxyUri.IdnHost == host && proxyUri.Port == port);
114113
break;
115114

116115
default:

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2180,6 +2180,18 @@ public async Task Dispose_DisposingHandlerCancelsActiveOperationsWithoutResponse
21802180
return;
21812181
}
21822182

2183+
if (PlatformDetection.IsFullFramework)
2184+
{
2185+
// Skip test on .NET Framework. It will sometimes not throw TaskCanceledException.
2186+
// Instead it might throw the following top-level and inner exceptions depending
2187+
// on race conditions.
2188+
//
2189+
// System.Net.Http.HttpRequestException : Error while copying content to a stream.
2190+
// ---- System.IO.IOException : The read operation failed, see inner exception.
2191+
//-------- System.Net.WebException : The request was aborted: The request was canceled.
2192+
return;
2193+
}
2194+
21832195
await LoopbackServer.CreateServerAsync(async (server1, url1) =>
21842196
{
21852197
await LoopbackServer.CreateServerAsync(async (server2, url2) =>
@@ -2658,8 +2670,10 @@ public async Task PostAsync_Redirect_LargePayload_Helper(int statusCode, bool ex
26582670
}
26592671
}
26602672

2661-
[OuterLoop] // TODO: Issue #11345
2662-
[Theory, MemberData(nameof(EchoServers))] // NOTE: will not work for in-box System.Net.Http.dll due to disposal of request content
2673+
[OuterLoop("Uses external server")]
2674+
[Theory, MemberData(nameof(EchoServers))]
2675+
[SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, ".NET Framework disposes request content after send")]
2676+
[ActiveIssue(31104, TestPlatforms.AnyUnix)]
26632677
public async Task PostAsync_ReuseRequestContent_Success(Uri remoteServer)
26642678
{
26652679
const string ContentString = "This is the content string.";

src/System.Net.Requests/src/System/Net/HttpWebRequest.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1138,11 +1138,22 @@ private async Task<WebResponse> SendRequest()
11381138

11391139
Debug.Assert(handler.UseProxy); // Default of handler.UseProxy is true.
11401140
Debug.Assert(handler.Proxy == null); // Default of handler.Proxy is null.
1141+
1142+
// HttpClientHandler default is to use a proxy which is the system proxy.
1143+
// This is indicated by the properties 'UseProxy == true' and 'Proxy == null'.
1144+
//
1145+
// However, HttpWebRequest doesn't have a separate 'UseProxy' property. Instead,
1146+
// the default of the 'Proxy' property is a non-null IWebProxy object which is the
1147+
// system default proxy object. If the 'Proxy' property were actually null, then
1148+
// that means don't use any proxy.
1149+
//
1150+
// So, we need to map the desired HttpWebRequest proxy settings to equivalent
1151+
// HttpClientHandler settings.
11411152
if (_proxy == null)
11421153
{
11431154
handler.UseProxy = false;
11441155
}
1145-
else
1156+
else if (!object.ReferenceEquals(_proxy, WebRequest.GetSystemWebProxy()))
11461157
{
11471158
handler.Proxy = _proxy;
11481159
}

0 commit comments

Comments
 (0)