进行POST时java.net.HttpClient失败并出现EOFException

时间:2019-09-19 00:10:28

标签: java java-http-client

我有一个使用openjdk-11.0.1 java.net.HttpClient向REST(ish)端点发出多部分POST请求的应用程序。该端点在执行任何工作时都会阻塞响应,当工作完成时,它将返回响应。此端点的性质是,响应可以在1s到1d的范围内进行,因此该连接可以保持非常很长时间。

因此,无论如何,即使目标服务器上的进程似乎仍然可以正常执行,最近我也开始遇到以下错误。是否有人对导致此错误的可能原因有任何想法?

Caused by: java.util.concurrent.ExecutionException: java.io.IOException: HTTP/1.1 header parser received no bytes
    at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:395)
    at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1999)
    at com.paxata.perf.rdp.profile.DatasetProfiler.toJson(DatasetProfiler.java:190)
    ... 9 common frames omitted
Caused by: java.io.IOException: HTTP/1.1 header parser received no bytes
    at java.net.http/jdk.internal.net.http.common.Utils.wrapWithExtraDetail(Utils.java:293)
    at java.net.http/jdk.internal.net.http.Http1Response$HeadersReader.onReadError(Http1Response.java:657)
    at java.net.http/jdk.internal.net.http.Http1AsyncReceiver.checkForErrors(Http1AsyncReceiver.java:297)
    at java.net.http/jdk.internal.net.http.Http1AsyncReceiver.flush(Http1AsyncReceiver.java:263)
    at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SynchronizedRestartableTask.run(SequentialScheduler.java:175)
    at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147)
    at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
    at java.net.http/jdk.internal.net.http.HttpClientImpl$DelegatingExecutor.execute(HttpClientImpl.java:153)
    at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:273)
    at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:242)
    at java.net.http/jdk.internal.net.http.Http1AsyncReceiver.onReadError(Http1AsyncReceiver.java:506)
    at java.net.http/jdk.internal.net.http.Http1AsyncReceiver$Http1TubeSubscriber.onComplete(Http1AsyncReceiver.java:591)
    at java.net.http/jdk.internal.net.http.common.SSLTube$DelegateWrapper.onComplete(SSLTube.java:268)
    at java.net.http/jdk.internal.net.http.common.SSLTube$SSLSubscriberWrapper.complete(SSLTube.java:411)
    at java.net.http/jdk.internal.net.http.common.SSLTube$SSLSubscriberWrapper.onComplete(SSLTube.java:540)
    at java.net.http/jdk.internal.net.http.common.SubscriberWrapper.checkCompletion(SubscriberWrapper.java:443)
    at java.net.http/jdk.internal.net.http.common.SubscriberWrapper$DownstreamPusher.run1(SubscriberWrapper.java:322)
    at java.net.http/jdk.internal.net.http.common.SubscriberWrapper$DownstreamPusher.run(SubscriberWrapper.java:261)
    at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SynchronizedRestartableTask.run(SequentialScheduler.java:175)
    at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147)
    at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
    at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:271)
    at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:224)
    at java.net.http/jdk.internal.net.http.common.SubscriberWrapper.outgoing(SubscriberWrapper.java:234)
    at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader.processData(SSLFlowDelegate.java:467)
    at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader$ReaderDownstreamPusher.run(SSLFlowDelegate.java:263)
    at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SynchronizedRestartableTask.run(SequentialScheduler.java:175)
    at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147)
    at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
    ... 3 common frames omitted
Caused by: java.io.EOFException: EOF reached while reading
    ... 21 common frames omitted

这是我的HttpClient的创建:

default HttpClient create() {
    final SSLContextBuilder sslContextBuilder;

    try {
        sslContextBuilder = new SSLContextBuilder().loadTrustMaterial(TrustSelfSignedStrategy.INSTANCE);
    } catch (NoSuchAlgorithmException | KeyStoreException e) {
        throw new RuntimeException("Unable to build SSLContext", e);
    }

    // PREVENTS HOST VALIDATION
    final Properties props = System.getProperties();
    props.setProperty("jdk.internal.httpclient.disableHostnameVerification", Boolean.TRUE.toString());

    // SHOULD PREVENT HOST VALIDATION
    final SSLParameters sslParams = new SSLParameters();
    sslParams.setEndpointIdentificationAlgorithm(null);

    try {
        final SSLContext sslContext = sslContextBuilder.build();
        ignoreExpiredCerts(sslContext);

        return HttpClient.newBuilder().version(Version.HTTP_1_1).sslContext(sslContext).sslParameters(sslParams)
            .build();
    } catch (KeyManagementException | NoSuchAlgorithmException e) {
        throw new RuntimeException("Unable to build HttpClient", e);
    }
}

private void ignoreExpiredCerts(final SSLContext sslContext) throws KeyManagementException {
    TrustManagerFactory tmf;

    try {
        tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    } catch (final NoSuchAlgorithmException e) {
        throw new RuntimeException("Unable to build HttpClient", e);
    }

    try {
        tmf.init((KeyStore) null);
    } catch (final KeyStoreException e) {
        throw new RuntimeException("Unable to build HttpClient", e);
    }

    final TrustManager[] trustManagers = tmf.getTrustManagers();
    final X509TrustManager origTrustmanager = (X509TrustManager) trustManagers[0];
    final AtomicBoolean logged = new AtomicBoolean(false);

    final TrustManager[] wrappedTrustManagers = new TrustManager[] { new X509TrustManager() {
        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
        return origTrustmanager.getAcceptedIssuers();
        }

        @Override
        public void checkClientTrusted(final X509Certificate[] certs, final String authType)
            throws CertificateException {
        origTrustmanager.checkClientTrusted(certs, authType);
        }

        @Override
        public void checkServerTrusted(final X509Certificate[] certs, final String authType)
            throws CertificateException {
        try {
            origTrustmanager.checkServerTrusted(certs, authType);
        } catch (final CertificateExpiredException e) {
            if (!logged.get()) {
            LOGGER.warn("Server certificate expired", e);
            logged.set(true);
            }
        } catch (final Exception e) {
            if (e.getCause() != null && e.getCause().getCause() != null
                && e.getCause().getCause() instanceof CertificateExpiredException) {
            if (!logged.get()) {
                LOGGER.warn("Server certificate expired", e.getCause().getCause());
                logged.set(true);
            }
            } else {
            throw e;
            }
        }
        }
    } };

    sslContext.init(null, wrappedTrustManagers, null);
}

0 个答案:

没有答案