HTTPCLIENT-2288 - Retry logic in DefaultHttpClientConnectionOperator doesn't handle SocketException

This commit is contained in:
Liam Miller-Cushon 2023-07-28 18:33:52 -07:00 committed by Oleg Kalnichevski
parent 7aca075c6e
commit 54900db465
3 changed files with 46 additions and 3 deletions

View File

@ -30,7 +30,7 @@ import java.io.IOException;
import java.net.ConnectException; import java.net.ConnectException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.NoRouteToHostException; import java.net.SocketException;
import java.net.Socket; import java.net.Socket;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
@ -157,7 +157,7 @@ public class DefaultHttpClientConnectionOperator implements HttpClientConnection
? new ConnectTimeoutException(ex, host, addresses) ? new ConnectTimeoutException(ex, host, addresses)
: new HttpHostConnectException(ex, host, addresses); : new HttpHostConnectException(ex, host, addresses);
} }
} catch (final NoRouteToHostException ex) { } catch (final SocketException ex) {
if (last) { if (last) {
throw ex; throw ex;
} }

View File

@ -28,6 +28,7 @@
package org.apache.http.impl.client.integration; package org.apache.http.impl.client.integration;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
import java.net.SocketException; import java.net.SocketException;
@ -446,7 +447,8 @@ public class TestConnectionManagement extends LocalServerTestBase {
this.connManager.setMaxTotal(1); this.connManager.setMaxTotal(1);
final HttpHost target = start(); final HttpHost target = new HttpHost(
InetAddress.getByName("localhost"), "localhost", start().getPort(), this.scheme.name());
final HttpRoute route = new HttpRoute(target, null, false); final HttpRoute route = new HttpRoute(target, null, false);
final HttpContext context = new BasicHttpContext(); final HttpContext context = new BasicHttpContext();

View File

@ -28,6 +28,7 @@
package org.apache.http.impl.conn; package org.apache.http.impl.conn;
import java.net.ConnectException; import java.net.ConnectException;
import java.net.SocketException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
@ -206,6 +207,46 @@ public class TestHttpClientConnectionOperator {
Mockito.verify(conn, Mockito.times(3)).bind(socket); Mockito.verify(conn, Mockito.times(3)).bind(socket);
} }
@Test
public void testConnectFailoverSocketException() throws Exception {
final HttpContext context = new BasicHttpContext();
final HttpHost host = new HttpHost("somehost");
final InetAddress local = InetAddress.getByAddress(new byte[] {127, 0, 0, 0});
final InetAddress ip1 = InetAddress.getByAddress(new byte[] {10, 0, 0, 1});
final InetAddress ip2 = InetAddress.getByAddress(new byte[] {10, 0, 0, 2});
Mockito.when(dnsResolver.resolve("somehost")).thenReturn(new InetAddress[] { ip1, ip2 });
Mockito.when(socketFactoryRegistry.lookup("http")).thenReturn(plainSocketFactory);
Mockito.when(schemePortResolver.resolve(host)).thenReturn(80);
Mockito.when(plainSocketFactory.createSocket(Mockito.<HttpContext>any())).thenReturn(socket);
Mockito.when(plainSocketFactory.connectSocket(
Mockito.anyInt(),
Mockito.<Socket>any(),
Mockito.<HttpHost>any(),
Mockito.eq(new InetSocketAddress(ip1, 80)),
Mockito.<InetSocketAddress>any(),
Mockito.<HttpContext>any())).thenThrow(new SocketException());
Mockito.when(plainSocketFactory.connectSocket(
Mockito.anyInt(),
Mockito.<Socket>any(),
Mockito.<HttpHost>any(),
Mockito.eq(new InetSocketAddress(ip2, 80)),
Mockito.<InetSocketAddress>any(),
Mockito.<HttpContext>any())).thenReturn(socket);
final InetSocketAddress localAddress = new InetSocketAddress(local, 0);
connectionOperator.connect(conn, host, localAddress, 1000, SocketConfig.DEFAULT, context);
Mockito.verify(plainSocketFactory).connectSocket(
1000,
socket,
host,
new InetSocketAddress(ip2, 80),
localAddress,
context);
Mockito.verify(conn, Mockito.times(3)).bind(socket);
}
@Test @Test
public void testConnectExplicitAddress() throws Exception { public void testConnectExplicitAddress() throws Exception {
final HttpContext context = new BasicHttpContext(); final HttpContext context = new BasicHttpContext();