HTTPCLIENT-2328: Blocking i/o connections to check if the opposite TLS endpoint has been closed by the opposite endpoint while writing out request body
This commit is contained in:
parent
10e8a7acbc
commit
ee0a102104
|
@ -235,8 +235,8 @@ public class DefaultHttpClientConnectionOperator implements HttpClientConnection
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug("{} {} upgrading to TLS", ConnPoolSupport.getId(conn), tlsName);
|
LOG.debug("{} {} upgrading to TLS", ConnPoolSupport.getId(conn), tlsName);
|
||||||
}
|
}
|
||||||
final Socket upgradedSocket = tlsSocketStrategy.upgrade(socket, tlsName.getHostName(), tlsName.getPort(), attachment, context);
|
final SSLSocket sslSocket = tlsSocketStrategy.upgrade(socket, tlsName.getHostName(), tlsName.getPort(), attachment, context);
|
||||||
conn.bind(upgradedSocket);
|
conn.bind(sslSocket, socket);
|
||||||
onAfterTlsHandshake(context, endpointHost);
|
onAfterTlsHandshake(context, endpointHost);
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug("{} {} upgraded to TLS", ConnPoolSupport.getId(conn), tlsName);
|
LOG.debug("{} {} upgraded to TLS", ConnPoolSupport.getId(conn), tlsName);
|
||||||
|
|
|
@ -184,6 +184,14 @@ final class DefaultManagedHttpClientConnection
|
||||||
socketTimeout = Timeout.ofMilliseconds(socket.getSoTimeout());
|
socketTimeout = Timeout.ofMilliseconds(socket.getSoTimeout());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bind(final SSLSocket sslSocket, final Socket socket) throws IOException {
|
||||||
|
super.bind(WIRE_LOG.isDebugEnabled() ?
|
||||||
|
new LoggingSocketHolder(sslSocket, socket, this.id, WIRE_LOG) :
|
||||||
|
new SocketHolder(sslSocket, socket));
|
||||||
|
socketTimeout = Timeout.ofMilliseconds(sslSocket.getSoTimeout());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onResponseReceived(final ClassicHttpResponse response) {
|
protected void onResponseReceived(final ClassicHttpResponse response) {
|
||||||
if (response != null && HEADER_LOG.isDebugEnabled()) {
|
if (response != null && HEADER_LOG.isDebugEnabled()) {
|
||||||
|
|
|
@ -32,6 +32,8 @@ import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLSocket;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.impl.Wire;
|
import org.apache.hc.client5.http.impl.Wire;
|
||||||
import org.apache.hc.core5.http.impl.io.SocketHolder;
|
import org.apache.hc.core5.http.impl.io.SocketHolder;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -45,6 +47,11 @@ class LoggingSocketHolder extends SocketHolder {
|
||||||
this.wire = new Wire(log, id);
|
this.wire = new Wire(log, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LoggingSocketHolder(final SSLSocket sslSocket, final Socket baseSocket, final String id, final Logger log) {
|
||||||
|
super(sslSocket, baseSocket);
|
||||||
|
this.wire = new Wire(log, id);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected InputStream getInputStream(final Socket socket) throws IOException {
|
protected InputStream getInputStream(final Socket socket) throws IOException {
|
||||||
return new LoggingInputStream(super.getInputStream(socket), wire);
|
return new LoggingInputStream(super.getInputStream(socket), wire);
|
||||||
|
|
|
@ -31,6 +31,7 @@ import java.io.IOException;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
|
||||||
import javax.net.ssl.SSLSession;
|
import javax.net.ssl.SSLSession;
|
||||||
|
import javax.net.ssl.SSLSocket;
|
||||||
|
|
||||||
import org.apache.hc.core5.annotation.Internal;
|
import org.apache.hc.core5.annotation.Internal;
|
||||||
import org.apache.hc.core5.http.io.HttpClientConnection;
|
import org.apache.hc.core5.http.io.HttpClientConnection;
|
||||||
|
@ -55,6 +56,21 @@ public interface ManagedHttpClientConnection extends HttpClientConnection {
|
||||||
*/
|
*/
|
||||||
void bind(Socket socket) throws IOException;
|
void bind(Socket socket) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds this connection to the SSL given socket and the underlying network
|
||||||
|
* socket. The connection is considered open if it is bound, the underlying
|
||||||
|
* network socket is connection to a remote host and the SSL socket is
|
||||||
|
* fully initialized (TLS handshake has been successfully executed).
|
||||||
|
*
|
||||||
|
* @param sslSocket the SSL socket to bind the connection to.
|
||||||
|
* @param socket the underlying network socket of the SSL socket.
|
||||||
|
*
|
||||||
|
* @since 5.4
|
||||||
|
*/
|
||||||
|
default void bind(SSLSocket sslSocket, Socket socket) throws IOException {
|
||||||
|
bind(sslSocket);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the underlying socket.
|
* Returns the underlying socket.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -62,6 +62,7 @@ import org.apache.hc.core5.http.ssl.TlsCiphers;
|
||||||
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
||||||
import org.apache.hc.core5.http2.ssl.ApplicationProtocol;
|
import org.apache.hc.core5.http2.ssl.ApplicationProtocol;
|
||||||
import org.apache.hc.core5.http2.ssl.H2TlsSupport;
|
import org.apache.hc.core5.http2.ssl.H2TlsSupport;
|
||||||
|
import org.apache.hc.core5.io.Closer;
|
||||||
import org.apache.hc.core5.net.NamedEndpoint;
|
import org.apache.hc.core5.net.NamedEndpoint;
|
||||||
import org.apache.hc.core5.reactor.ssl.SSLBufferMode;
|
import org.apache.hc.core5.reactor.ssl.SSLBufferMode;
|
||||||
import org.apache.hc.core5.reactor.ssl.TlsDetails;
|
import org.apache.hc.core5.reactor.ssl.TlsDetails;
|
||||||
|
@ -204,9 +205,14 @@ abstract class AbstractClientTlsStrategy implements TlsStrategy, TlsSocketStrate
|
||||||
socket,
|
socket,
|
||||||
target,
|
target,
|
||||||
port,
|
port,
|
||||||
true);
|
false);
|
||||||
|
try {
|
||||||
executeHandshake(upgradedSocket, target, attachment);
|
executeHandshake(upgradedSocket, target, attachment);
|
||||||
return upgradedSocket;
|
return upgradedSocket;
|
||||||
|
} catch (IOException | RuntimeException ex) {
|
||||||
|
Closer.closeQuietly(upgradedSocket);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeHandshake(
|
private void executeHandshake(
|
||||||
|
|
|
@ -147,7 +147,7 @@ public class TestHttpClientConnectionOperator {
|
||||||
Mockito.verify(socket).connect(new InetSocketAddress(ip1, 443), 123);
|
Mockito.verify(socket).connect(new InetSocketAddress(ip1, 443), 123);
|
||||||
Mockito.verify(conn, Mockito.times(2)).bind(socket);
|
Mockito.verify(conn, Mockito.times(2)).bind(socket);
|
||||||
Mockito.verify(tlsSocketStrategy).upgrade(socket, "somehost", -1, tlsConfig, context);
|
Mockito.verify(tlsSocketStrategy).upgrade(socket, "somehost", -1, tlsConfig, context);
|
||||||
Mockito.verify(conn, Mockito.times(1)).bind(upgradedSocket);
|
Mockito.verify(conn, Mockito.times(1)).bind(upgradedSocket, socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue