admin管理员组

文章数量:1335825

My logic calls two consecutive POST requests from RestTemplate in SpringBoot. The first call always succeeds but the second call always fails with:

I/O error on POST request for ";: httpbin:443 failed to respond

Everything works fine, if I either

  • disable keep-alive by setting Connection=close
  • put a sleep between the request calls
  • remove the proxy

I've tested with spring-boot 3.3.5 and apache-httpclient 5.4.1 but the same issue occurs with spring-boot 2.7.8 and apache-httpclient 4.5.14 I'm using jdk17 and burp as proxy. Finally I've stripped down the code only using httpclient.

public class RestTemplateDemo {

  private static Logger logger = Logger.getLogger(RestTemplateDemo.class.getName());

  public static void main(String[] args) {
    System.setProperty("javax.debug", "all");
    HttpHost proxy = new HttpHost("localhost", 8888);
    CloseableHttpClient client = HttpClients.custom()
        .setProxy(proxy)
        .build();

    logger.info("1. call");
    callPost(client);
    logger.info("2. call");
    callPost(client);
  }

  static void callPost(CloseableHttpClient client) {
    String url = ";;
    HttpPost post = new HttpPost(url);
    post.setEntity(new StringEntity("test", Charset.defaultCharset()));
    try (CloseableHttpResponse response = client.execute(post)) {
      logger.info(response.getCode() + " " + response.getReasonPhrase());
    } catch (IOException e) {
      logger.log(Level.SEVERE, e.getMessage(), e);
    }
  }

Here's the log and stack trace:

...
INFO: 2. call
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.657 CET|SSLSocketOutputRecord.java:334|WRITE: TLSv1.3 application_data, length = 222
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.657 CET|SSLCipher.java:2066|Plaintext before ENCRYPTION (
...
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.657 CET|SSLSocketOutputRecord.java:349|Raw write (
...
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.657 CET|SSLSocketInputRecord.java:494|Raw read (
...
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.657 CET|SSLSocketInputRecord.java:214|READ: TLSv1.2 application_data, length = 35
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.657 CET|SSLSocketInputRecord.java:494|Raw read (
...
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.657 CET|SSLSocketInputRecord.java:247|READ: TLSv1.2 application_data, length = 35
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.657 CET|SSLCipher.java:1961|Plaintext after DECRYPTION (
...
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.658 CET|Alert.java:238|Received alert message (
"Alert": {
  "level"      : "warning",
  "description": "user_canceled"
}
)
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.658 CET|SSLSocketInputRecord.java:494|Raw read (
...
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.658 CET|SSLSocketInputRecord.java:214|READ: TLSv1.2 application_data, length = 35
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.658 CET|SSLSocketInputRecord.java:494|Raw read (
...
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.658 CET|SSLSocketInputRecord.java:247|READ: TLSv1.2 application_data, length = 35
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.658 CET|SSLCipher.java:1961|Plaintext after DECRYPTION (
...
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.658 CET|Alert.java:238|Received alert message (
"Alert": {
  "level"      : "warning",
  "description": "close_notify"
}
)
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.658 CET|SSLSocketOutputRecord.java:71|WRITE: TLSv1.3 alert(close_notify), length = 2
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.658 CET|SSLCipher.java:2066|Plaintext before ENCRYPTION (
..
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.658 CET|SSLSocketOutputRecord.java:85|Raw write (
...
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.659 CET|SSLSocketImpl.java:577|duplex close of SSLSocket
javax.ssl|DEBUG|10|main|2024-11-20 14:09:17.659 CET|SSLSocketImpl.java:1785|close the SSL connection (passive)
Nov 20, 2024 2:09:17 PM demo.RestTemplateDemo callPost
SEVERE: httpbin:443 failed to respond
.apache.hc.core5.http.NoHttpResponseException: httpbin:443 failed to respond
    at .apache.hc.core5.http.impl.io.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:333)
    at .apache.hc.core5.http.impl.io.HttpRequestExecutor.execute(HttpRequestExecutor.java:193)
    at .apache.hc.client5.http.impl.classic.InternalExecRuntime.lambda$execute$0(InternalExecRuntime.java:236)
    at .apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager$InternalConnectionEndpoint.execute(PoolingHttpClientConnectionManager.java:791)
    at .apache.hc.client5.http.impl.classic.InternalExecRuntime.execute(InternalExecRuntime.java:233)
    at .apache.hc.client5.http.impl.classic.MainClientExec.execute(MainClientExec.java:121)
    at .apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at .apache.hc.client5.http.impl.classic.ConnectExec.execute(ConnectExec.java:199)
    at .apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at .apache.hc.client5.http.impl.classic.ProtocolExec.execute(ProtocolExec.java:192)
    at .apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at .apache.hc.client5.http.impl.classic.ContentCompressionExec.execute(ContentCompressionExec.java:150)
    at .apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at .apache.hc.client5.http.impl.classic.HttpRequestRetryExec.execute(HttpRequestRetryExec.java:113)
    at .apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at .apache.hc.client5.http.impl.classic.RedirectExec.execute(RedirectExec.java:110)
    at .apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at .apache.hc.client5.http.impl.classic.InternalHttpClient.doExecute(InternalHttpClient.java:174)
    at .apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:123)
    at demo.RestTemplateDemo.callPost(RestTemplateDemo.java:36)
    at demo.RestTemplateDemo.main(RestTemplateDemo.java:29)


Process finished with exit code 0

PS I know, that RestTemplate is deprected, but my problem occurs with legacy code. This is only a stripped down reproducable sample. In real live I also call two POST requests at different endpoints.

本文标签: