【问题标题】:HttpClient hits timeout but server is available and working flawlesslyHttpClient 超时,但服务器可用并且工作正常
【发布时间】:2021-04-25 08:42:05
【问题描述】:

我的问题是 HttpClient 永远不会到达目标。目标在同一个网络上(所以我不需要代理),它肯定是启动的。并且超时设置得非常高(120 秒),服务器能够在不到一秒的时间内做出响应。 使用其他应用程序或curl 一切正常。

这是我的代码,我尝试了两种设置凭据的方法,它们都用 cmets 标记。在我的测试中,我启用了第一个然后另一个:

HttpRequest request = HttpRequest.newBuilder()
    .uri(new URI( "https://target:8443/foo/bar"))
    .version(HttpClient.Version.HTTP_1_1)
    // approach 1:
    .header("Authorization", basicAuth("foo", "bar"))
    .timeout(Duration.ofSeconds(120)).POST(HttpRequest.BodyPublishers.ofFile(tempFile.toPath())).build();

HttpResponse<String> response = HttpClient.newBuilder()
    /* approach 2:
    .authenticator(new Authenticator() {
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            System.err.println("Was asked for a password");
            return new PasswordAuthentication("foo", "bar".toCharArray());
        }
    })
    */
    .followRedirects(HttpClient.Redirect.ALWAYS)
    .build()
    .send(request, HttpResponse.BodyHandlers.ofString());
                
                

相比之下,这个有效:

curl -u foo:bar -X POST -H "content-type: application/vnd.lucidworks-document" https://target:8443/foo/bar --data-binary @test.json -v

我的 Java 代码抛出此错误:

2021-04-25 10:26:56.730 INFO 12316 --- [SelectorManager] jdk.httpclient.HttpClient               CHANNEL: Read error signalled on channel java.nio.channels.SocketChannel[closed]: java.io.IOException: connection closed locally
    at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:561)
    at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:119)
...
Caused by: java.net.ConnectException: Connection timed out: no further information
    at java.base/sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
    at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:779)
    at java.net.http/jdk.internal.net.http.PlainHttpConnection$ConnectEvent.handle(PlainHttpConnection.java:128)
    at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.handleEvent(HttpClientImpl.java:957)
    at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.lambda$run$3(HttpClientImpl.java:912)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.run(HttpClientImpl.java:912)

启用的日志没有显示太多,但是这一行让我觉得身份验证可能不起作用,因此连接“卡住”了?!?

MISC: Applying jdk.internal.net.http.AuthenticationFilter@43b3184

我知道有些 Java 版本存在我所描述的问题,但我在 AdoptOpenJDK Java 11 (11.0.11+9) 和 15 (15.0.2+7) 的当前版本上尝试了这个,但仍然遇到一样。

【问题讨论】:

    标签: java https java-http-client java-15


    【解决方案1】:

    像往常一样,原因很简单:

    目标服务器只有一个 IPv4 地址。 Java 出于某种原因尝试使用 IPv6 访问目标但未能成功。我假设这种“停止”正在进行的过程,这只能通过中止挂起的线程来解决(超时有效的作用)

    只要在我的程序调用中添加-Djava.net.preferIPv4Stack=true,我就能够成功运行它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-11
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 2014-04-26
      • 1970-01-01
      相关资源
      最近更新 更多