8336655
: java/net/httpclient/DigestEchoClient.java IOException: HTTP/1.1 header parser received no bytes
Reviewed-by: jpai
This commit is contained in:
parent
3859131505
commit
6169613d9f
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -44,6 +44,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import jdk.internal.net.http.common.Deadline;
|
import jdk.internal.net.http.common.Deadline;
|
||||||
import jdk.internal.net.http.common.FlowTube;
|
import jdk.internal.net.http.common.FlowTube;
|
||||||
|
import jdk.internal.net.http.common.Log;
|
||||||
import jdk.internal.net.http.common.Logger;
|
import jdk.internal.net.http.common.Logger;
|
||||||
import jdk.internal.net.http.common.TimeLine;
|
import jdk.internal.net.http.common.TimeLine;
|
||||||
import jdk.internal.net.http.common.TimeSource;
|
import jdk.internal.net.http.common.TimeSource;
|
||||||
@ -492,13 +493,13 @@ final class ConnectionPool {
|
|||||||
|
|
||||||
// Remove a connection from the pool.
|
// Remove a connection from the pool.
|
||||||
// should only be called while holding the ConnectionPool stateLock.
|
// should only be called while holding the ConnectionPool stateLock.
|
||||||
private void removeFromPool(HttpConnection c) {
|
private boolean removeFromPool(HttpConnection c) {
|
||||||
assert stateLock.isHeldByCurrentThread();
|
assert stateLock.isHeldByCurrentThread();
|
||||||
if (c instanceof PlainHttpConnection) {
|
if (c instanceof PlainHttpConnection) {
|
||||||
removeFromPool(c, plainPool);
|
return removeFromPool(c, plainPool);
|
||||||
} else {
|
} else {
|
||||||
assert c.isSecure() : "connection " + c + " is not secure!";
|
assert c.isSecure() : "connection " + c + " is not secure!";
|
||||||
removeFromPool(c, sslPool);
|
return removeFromPool(c, sslPool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,13 +530,29 @@ final class ConnectionPool {
|
|||||||
debug.log("%s : ConnectionPool.cleanup(%s)",
|
debug.log("%s : ConnectionPool.cleanup(%s)",
|
||||||
String.valueOf(c.getConnectionFlow()), error);
|
String.valueOf(c.getConnectionFlow()), error);
|
||||||
stateLock.lock();
|
stateLock.lock();
|
||||||
|
boolean removed;
|
||||||
try {
|
try {
|
||||||
removeFromPool(c);
|
removed = removeFromPool(c);
|
||||||
expiryList.remove(c);
|
expiryList.remove(c);
|
||||||
} finally {
|
} finally {
|
||||||
stateLock.unlock();
|
stateLock.unlock();
|
||||||
}
|
}
|
||||||
c.close();
|
if (!removed) {
|
||||||
|
// this should not happen; the cleanup may have consumed
|
||||||
|
// some data that wasn't supposed to be consumed, so
|
||||||
|
// the only thing we can do is log it and close the
|
||||||
|
// connection.
|
||||||
|
if (Log.errors()) {
|
||||||
|
Log.logError("WARNING: CleanupTrigger triggered for" +
|
||||||
|
" a connection not found in the pool: closing {0}", c);
|
||||||
|
} else if (debug.on()) {
|
||||||
|
debug.log("WARNING: CleanupTrigger triggered for" +
|
||||||
|
" a connection not found in the pool: closing %s", c);
|
||||||
|
}
|
||||||
|
c.close(new IOException("Unexpected cleanup triggered for non pooled connection"));
|
||||||
|
} else {
|
||||||
|
c.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -549,6 +566,7 @@ final class ConnectionPool {
|
|||||||
|
|
||||||
private final HttpConnection connection;
|
private final HttpConnection connection;
|
||||||
private volatile boolean done;
|
private volatile boolean done;
|
||||||
|
private volatile boolean dropped;
|
||||||
|
|
||||||
public CleanupTrigger(HttpConnection connection) {
|
public CleanupTrigger(HttpConnection connection) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
@ -566,6 +584,7 @@ final class ConnectionPool {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSubscribe(Flow.Subscription subscription) {
|
public void onSubscribe(Flow.Subscription subscription) {
|
||||||
|
if (dropped || done) return;
|
||||||
subscription.request(1);
|
subscription.request(1);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
@ -586,5 +605,10 @@ final class ConnectionPool {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "CleanupTrigger(" + connection.getConnectionFlow() + ")";
|
return "CleanupTrigger(" + connection.getConnectionFlow() + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dropSubscription() {
|
||||||
|
dropped = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -573,6 +573,8 @@ final class SocketTube implements FlowTube {
|
|||||||
debug.log("read publisher: dropping pending subscriber: "
|
debug.log("read publisher: dropping pending subscriber: "
|
||||||
+ previous.subscriber);
|
+ previous.subscriber);
|
||||||
previous.errorRef.compareAndSet(null, errorRef.get());
|
previous.errorRef.compareAndSet(null, errorRef.get());
|
||||||
|
// make sure no data will be routed to the old subscriber.
|
||||||
|
previous.stopReading();
|
||||||
previous.signalOnSubscribe();
|
previous.signalOnSubscribe();
|
||||||
if (subscriptionImpl.completed) {
|
if (subscriptionImpl.completed) {
|
||||||
previous.signalCompletion();
|
previous.signalCompletion();
|
||||||
@ -606,6 +608,7 @@ final class SocketTube implements FlowTube {
|
|||||||
volatile boolean subscribed;
|
volatile boolean subscribed;
|
||||||
volatile boolean cancelled;
|
volatile boolean cancelled;
|
||||||
volatile boolean completed;
|
volatile boolean completed;
|
||||||
|
volatile boolean stopped;
|
||||||
|
|
||||||
public ReadSubscription(InternalReadSubscription impl,
|
public ReadSubscription(InternalReadSubscription impl,
|
||||||
TubeSubscriber subscriber) {
|
TubeSubscriber subscriber) {
|
||||||
@ -623,11 +626,11 @@ final class SocketTube implements FlowTube {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void request(long n) {
|
public void request(long n) {
|
||||||
if (!cancelled) {
|
if (!cancelled && !stopped) {
|
||||||
impl.request(n);
|
impl.request(n);
|
||||||
} else {
|
} else {
|
||||||
if (debug.on())
|
if (debug.on())
|
||||||
debug.log("subscription cancelled, ignoring request %d", n);
|
debug.log("subscription stopped or cancelled, ignoring request %d", n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -661,6 +664,20 @@ final class SocketTube implements FlowTube {
|
|||||||
signalCompletion();
|
signalCompletion();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when switching subscriber on the {@link InternalReadSubscription}.
|
||||||
|
* This subscriber is the old subscriber. Demand on the internal
|
||||||
|
* subscription will be reset and reading will be paused until the
|
||||||
|
* new subscriber is subscribed.
|
||||||
|
* This should ensure that no data is routed to this subscriber
|
||||||
|
* until the new subscriber is subscribed.
|
||||||
|
*/
|
||||||
|
void stopReading() {
|
||||||
|
stopped = true;
|
||||||
|
impl.demand.reset();
|
||||||
|
impl.pauseReadEvent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class InternalReadSubscription implements Flow.Subscription {
|
final class InternalReadSubscription implements Flow.Subscription {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -64,7 +64,7 @@ import static java.lang.String.format;
|
|||||||
* @test
|
* @test
|
||||||
* @summary this test verifies that a client may provides authorization
|
* @summary this test verifies that a client may provides authorization
|
||||||
* headers directly when connecting with a server.
|
* headers directly when connecting with a server.
|
||||||
* @bug 8087112
|
* @bug 8087112 8336655
|
||||||
* @library /test/lib /test/jdk/java/net/httpclient/lib
|
* @library /test/lib /test/jdk/java/net/httpclient/lib
|
||||||
* @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext
|
* @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext
|
||||||
* DigestEchoServer ReferenceTracker DigestEchoClient
|
* DigestEchoServer ReferenceTracker DigestEchoClient
|
||||||
|
Loading…
Reference in New Issue
Block a user