change exceptions from socks proxy failure to be HttpRequestExceptions (#53516)
authorGeoff Kizer <geoffrek@microsoft.com>
Tue, 1 Jun 2021 14:00:25 +0000 (07:00 -0700)
committerGitHub <noreply@github.com>
Tue, 1 Jun 2021 14:00:25 +0000 (10:00 -0400)
Co-authored-by: Geoffrey Kizer <geoffrek@windows.microsoft.com>
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs
src/libraries/System.Net.Http/tests/FunctionalTests/SocksProxyTest.cs

index 1a3b68c..2e0f7dc 100644 (file)
@@ -1279,10 +1279,7 @@ namespace System.Net.Http
 
                     case HttpConnectionKind.SocksTunnel:
                     case HttpConnectionKind.SslSocksTunnel:
-                        Debug.Assert(_originAuthority != null);
-                        Debug.Assert(_proxyUri != null);
-                        (socket, stream) = await ConnectToTcpHostAsync(_proxyUri.IdnHost, _proxyUri.Port, request, async, cancellationToken).ConfigureAwait(false);
-                        await SocksHelper.EstablishSocksTunnelAsync(stream, _originAuthority.IdnHost, _originAuthority.Port, _proxyUri, ProxyCredentials, async, cancellationToken).ConfigureAwait(false);
+                        (socket, stream) = await EstablishSocksTunnel(request, async, cancellationToken).ConfigureAwait(false);
                         break;
                 }
 
@@ -1492,6 +1489,26 @@ namespace System.Net.Http
             }
         }
 
+        private async ValueTask<(Socket? socket, Stream stream)> EstablishSocksTunnel(HttpRequestMessage request, bool async, CancellationToken cancellationToken)
+        {
+            Debug.Assert(_originAuthority != null);
+            Debug.Assert(_proxyUri != null);
+
+            (Socket? socket, Stream stream) = await ConnectToTcpHostAsync(_proxyUri.IdnHost, _proxyUri.Port, request, async, cancellationToken).ConfigureAwait(false);
+
+            try
+            {
+                await SocksHelper.EstablishSocksTunnelAsync(stream, _originAuthority.IdnHost, _originAuthority.Port, _proxyUri, ProxyCredentials, async, cancellationToken).ConfigureAwait(false);
+            }
+            catch (Exception e) when (!(e is OperationCanceledException))
+            {
+                Debug.Assert(!(e is HttpRequestException));
+                throw new HttpRequestException(SR.net_http_request_aborted, e);
+            }
+
+            return (socket, stream);
+        }
+
         /// <summary>Enqueues a waiter to the waiters list.</summary>
         private TaskCompletionSourceWithCancellation<HttpConnection?> EnqueueWaiter()
         {
index 4f98bcf..633f562 100644 (file)
@@ -105,9 +105,10 @@ namespace System.Net.Http.Functional.Tests
             HttpRequestMessage request = CreateRequest(HttpMethod.Get, new Uri($"http://{host}/"), UseVersion, exactVersion: true);
 
             // SocksException is not public
-            var ex = await Assert.ThrowsAnyAsync<IOException>(() => client.SendAsync(TestAsync, request));
-            Assert.Equal(exceptionMessage, ex.Message);
-            Assert.Equal("SocksException", ex.GetType().Name);
+            var ex = await Assert.ThrowsAnyAsync<HttpRequestException>(() => client.SendAsync(TestAsync, request));
+            var innerException = ex.InnerException;
+            Assert.Equal(exceptionMessage, innerException.Message);
+            Assert.Equal("SocksException", innerException.GetType().Name);
         }
     }