Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Information Provided
-
4.5.14
-
None
-
None
-
None
Description
It seems BasicHttpClientConnectionManager does not validate connection before leasing it (unlike PoolingHttpClientConnectionManager).
Originally reported and discussed at: https://github.com/googleapis/google-http-java-client/issues/1791
Sample code to reproduce:
@Test void testDelayBetweenRequestsApacheHttpClient() throws Exception { BasicHttpClientConnectionManager connectionManager = new BasicHttpClientConnectionManager(); // PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); // connectionManager.setDefaultMaxPerRoute(1); try (CloseableHttpClient httpClient = HttpClients.custom() .setConnectionManager(connectionManager) .build()) { HttpPost request = new HttpPost("https://customsearch.googleapis.com/customsearch/v1"); consume(httpClient.execute(request)); Thread.sleep(5 * 60 * 1000); HttpPost request2 = new HttpPost("https://customsearch.googleapis.com/customsearch/v1"); consume(httpClient.execute(request2)); } } private static void consume(HttpResponse response) throws IOException { InputStream content = response.getEntity().getContent(); while (content.read() != -1) { } content.close(); }
When using `BasicHttpClientConnectionManager` the above code fails to execute second request:
2023/01/03 15:40:49:994 EST [DEBUG] BasicHttpClientConnectionManager - Get connection for route {s}->https://customsearch.googleapis.com:443 2023/01/03 15:40:50:010 EST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-0: set socket timeout to 0 2023/01/03 15:40:50:039 EST [DEBUG] DefaultHttpClientConnectionOperator - Connecting to customsearch.googleapis.com/142.250.176.202:443 2023/01/03 15:40:50:246 EST [DEBUG] DefaultHttpClientConnectionOperator - Connection established 192.168.154.214:62686<->142.250.176.202:443 2023/01/03 15:40:50:308 EST [DEBUG] BasicHttpClientConnectionManager - Releasing connection 192.168.154.214:62686<->142.250.176.202:443 2023/01/03 15:40:50:309 EST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-0: set socket timeout to 0 2023/01/03 15:40:50:309 EST [DEBUG] BasicHttpClientConnectionManager - Connection can be kept alive indefinitely 2023/01/03 15:45:50:312 EST [DEBUG] BasicHttpClientConnectionManager - Get connection for route {s}->https://customsearch.googleapis.com:443 2023/01/03 15:45:50:312 EST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-0: set socket timeout to 0 2023/01/03 15:45:50:314 EST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-0: Close connection 2023/01/03 15:45:50:314 EST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-0: Shutdown connection 2023/01/03 15:45:50:314 EST [DEBUG] BasicHttpClientConnectionManager - Releasing connection [Not bound]org.apache.http.NoHttpResponseException: customsearch.googleapis.com:443 failed to respond at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:141) at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56) at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259) at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163) at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273) at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186) at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89) at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
On the other side when using `PoolingHttpClientConnectionManager`, connection is successfully re-established and code executes successfully:
2023/01/03 15:52:18:116 EST [DEBUG] PoolingHttpClientConnectionManager - Connection request: [route: {s}->https://customsearch.googleapis.com:443][total available: 0; route allocated: 0 of 1; total allocated: 0 of 20] 2023/01/03 15:52:18:135 EST [DEBUG] PoolingHttpClientConnectionManager - Connection leased: [id: 0][route: {s}->https://customsearch.googleapis.com:443][total available: 0; route allocated: 1 of 1; total allocated: 1 of 20] 2023/01/03 15:52:18:142 EST [DEBUG] DefaultHttpClientConnectionOperator - Connecting to customsearch.googleapis.com/142.251.40.138:443 2023/01/03 15:52:18:344 EST [DEBUG] DefaultHttpClientConnectionOperator - Connection established 192.168.154.214:49406<->142.251.40.138:443 2023/01/03 15:52:18:405 EST [DEBUG] PoolingHttpClientConnectionManager - Connection [id: 0][route: {s}->https://customsearch.googleapis.com:443] can be kept alive indefinitely 2023/01/03 15:52:18:405 EST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-0: set socket timeout to 0 2023/01/03 15:52:18:405 EST [DEBUG] PoolingHttpClientConnectionManager - Connection released: [id: 0][route: {s}->https://customsearch.googleapis.com:443][total available: 1; route allocated: 1 of 1; total allocated: 1 of 20] 2023/01/03 15:57:18:415 EST [DEBUG] PoolingHttpClientConnectionManager - Connection request: [route: {s}->https://customsearch.googleapis.com:443][total available: 1; route allocated: 1 of 1; total allocated: 1 of 20] 2023/01/03 15:57:18:416 EST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-0: Close connection 2023/01/03 15:57:18:417 EST [DEBUG] PoolingHttpClientConnectionManager - Connection leased: [id: 1][route: {s}->https://customsearch.googleapis.com:443][total available: 0; route allocated: 1 of 1; total allocated: 1 of 20] 2023/01/03 15:57:18:435 EST [DEBUG] DefaultHttpClientConnectionOperator - Connecting to customsearch.googleapis.com/142.250.65.202:443 2023/01/03 15:57:18:478 EST [DEBUG] DefaultHttpClientConnectionOperator - Connection established 192.168.154.214:50689<->142.250.65.202:443 2023/01/03 15:57:18:711 EST [DEBUG] PoolingHttpClientConnectionManager - Connection [id: 1][route: {s}->https://customsearch.googleapis.com:443] can be kept alive indefinitely 2023/01/03 15:57:18:711 EST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-1: set socket timeout to 0 2023/01/03 15:57:18:711 EST [DEBUG] PoolingHttpClientConnectionManager - Connection released: [id: 1][route: {s}->https://customsearch.googleapis.com:443][total available: 1; route allocated: 1 of 1; total allocated: 1 of 20] 2023/01/03 15:57:18:711 EST [DEBUG] PoolingHttpClientConnectionManager - Connection manager is shutting down 2023/01/03 15:57:18:712 EST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-1: Close connection 2023/01/03 15:57:18:712 EST [DEBUG] PoolingHttpClientConnectionManager - Connection manager shut down