我有一个使用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);
}