Skip to content

Commit 7aa734f

Browse files
committed
Change connection logic
1 parent 47d7f27 commit 7aa734f

File tree

1 file changed

+54
-34
lines changed

1 file changed

+54
-34
lines changed

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

Lines changed: 54 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1713,60 +1713,80 @@ await Dns.GetHostAddressesAsync(context.DnsEndPoint.Host, cancellationToken).Con
17131713
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveInterval, keepAlive.Interval);
17141714
}
17151715

1716-
BindHelper(servicePoint, addresses, socket, context.DnsEndPoint.Port);
1717-
static void BindHelper(ServicePoint servicePoint, IPAddress[] addresses, Socket socket, int port)
1718-
{
1719-
if (servicePoint.BindIPEndPointDelegate is null)
1720-
{
1721-
return;
1722-
}
1716+
socket.NoDelay = !servicePoint.UseNagleAlgorithm;
17231717

1724-
const int MaxRetries = 100;
1718+
if (servicePoint.BindIPEndPointDelegate is not null)
1719+
{
17251720
foreach (IPAddress address in addresses)
17261721
{
1727-
int retryCount = 0;
1728-
for (; retryCount < MaxRetries; retryCount++)
1722+
IPEndPoint remoteEp = new IPEndPoint(address, context.DnsEndPoint.Port);
1723+
BindHelper(servicePoint, remoteEp, socket);
1724+
if (parameters.Async)
1725+
{
1726+
await socket.ConnectAsync(remoteEp, cancellationToken).ConfigureAwait(false);
1727+
}
1728+
else
17291729
{
1730-
IPEndPoint? endPoint = servicePoint.BindIPEndPointDelegate(servicePoint, new IPEndPoint(address, port), retryCount);
1731-
if (endPoint is null) // Get other address to try
1730+
using (cancellationToken.UnsafeRegister(s => ((Socket)s!).Dispose(), socket))
17321731
{
1733-
break;
1732+
socket.Connect(remoteEp);
17341733
}
17351734

1736-
try
1737-
{
1738-
socket.Bind(endPoint);
1739-
return; // Bind successful, exit loops.
1740-
}
1741-
catch
1742-
{
1743-
continue;
1744-
}
1735+
// Throw in case cancellation caused the socket to be disposed after the Connect completed
1736+
cancellationToken.ThrowIfCancellationRequested();
1737+
}
1738+
}
1739+
}
1740+
static void BindHelper(ServicePoint servicePoint, IPEndPoint remoteEp, Socket socket)
1741+
{
1742+
const int MaxRetries = 100;
1743+
int retryCount = 0;
1744+
for (; retryCount < MaxRetries; retryCount++)
1745+
{
1746+
IPEndPoint? endPoint = servicePoint.BindIPEndPointDelegate!(servicePoint, remoteEp, retryCount);
1747+
if (endPoint is null) // Get other address to try
1748+
{
1749+
return;
17451750
}
17461751

1747-
if (retryCount >= MaxRetries)
1752+
try
1753+
{
1754+
socket.Bind(endPoint);
1755+
return;
1756+
}
1757+
catch
17481758
{
1749-
throw new OverflowException(SR.net_maximumbindretries);
1759+
continue;
17501760
}
17511761
}
1762+
1763+
if (retryCount >= MaxRetries)
1764+
{
1765+
throw new OverflowException(SR.net_maximumbindretries);
1766+
}
17521767
}
17531768
}
1754-
1755-
socket.NoDelay = !(parameters.ServicePoint?.UseNagleAlgorithm) ?? true;
1756-
1757-
if (parameters.Async)
1769+
else
17581770
{
1759-
await socket.ConnectAsync(addresses, context.DnsEndPoint.Port, cancellationToken).ConfigureAwait(false);
1771+
socket.NoDelay = true;
17601772
}
1761-
else
1773+
1774+
if (!socket.Connected)
17621775
{
1763-
using (cancellationToken.UnsafeRegister(s => ((Socket)s!).Dispose(), socket))
1776+
if (parameters.Async)
17641777
{
1765-
socket.Connect(addresses, context.DnsEndPoint.Port);
1778+
await socket.ConnectAsync(addresses, context.DnsEndPoint.Port, cancellationToken).ConfigureAwait(false);
17661779
}
1780+
else
1781+
{
1782+
using (cancellationToken.UnsafeRegister(s => ((Socket)s!).Dispose(), socket))
1783+
{
1784+
socket.Connect(addresses, context.DnsEndPoint.Port);
1785+
}
17671786

1768-
// Throw in case cancellation caused the socket to be disposed after the Connect completed
1769-
cancellationToken.ThrowIfCancellationRequested();
1787+
// Throw in case cancellation caused the socket to be disposed after the Connect completed
1788+
cancellationToken.ThrowIfCancellationRequested();
1789+
}
17701790
}
17711791

17721792
if (parameters.ReadWriteTimeout > 0) // default is 5 minutes, so this is generally going to be true

0 commit comments

Comments
 (0)