Merged branch 'jetty-12.0.x' into 'jetty-12.1.x'.
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
commit
7aaca7d74d
|
@ -17,6 +17,7 @@ import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.net.SocketAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
@ -34,6 +35,7 @@ import org.eclipse.jetty.client.BasicAuthentication;
|
||||||
import org.eclipse.jetty.client.BufferingResponseListener;
|
import org.eclipse.jetty.client.BufferingResponseListener;
|
||||||
import org.eclipse.jetty.client.BytesRequestContent;
|
import org.eclipse.jetty.client.BytesRequestContent;
|
||||||
import org.eclipse.jetty.client.CompletableResponseListener;
|
import org.eclipse.jetty.client.CompletableResponseListener;
|
||||||
|
import org.eclipse.jetty.client.Connection;
|
||||||
import org.eclipse.jetty.client.ConnectionPool;
|
import org.eclipse.jetty.client.ConnectionPool;
|
||||||
import org.eclipse.jetty.client.ContentResponse;
|
import org.eclipse.jetty.client.ContentResponse;
|
||||||
import org.eclipse.jetty.client.Destination;
|
import org.eclipse.jetty.client.Destination;
|
||||||
|
@ -72,6 +74,7 @@ import org.eclipse.jetty.http3.client.transport.HttpClientTransportOverHTTP3;
|
||||||
import org.eclipse.jetty.io.ClientConnectionFactory;
|
import org.eclipse.jetty.io.ClientConnectionFactory;
|
||||||
import org.eclipse.jetty.io.ClientConnector;
|
import org.eclipse.jetty.io.ClientConnector;
|
||||||
import org.eclipse.jetty.io.Content;
|
import org.eclipse.jetty.io.Content;
|
||||||
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
import org.eclipse.jetty.io.Transport;
|
import org.eclipse.jetty.io.Transport;
|
||||||
import org.eclipse.jetty.io.ssl.SslHandshakeListener;
|
import org.eclipse.jetty.io.ssl.SslHandshakeListener;
|
||||||
import org.eclipse.jetty.quic.client.ClientQuicConfiguration;
|
import org.eclipse.jetty.quic.client.ClientQuicConfiguration;
|
||||||
|
@ -1180,4 +1183,29 @@ public class HTTPClientDocs
|
||||||
.send();
|
.send();
|
||||||
// end::mixedTransports[]
|
// end::mixedTransports[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void connectionInformation() throws Exception
|
||||||
|
{
|
||||||
|
// tag::connectionInformation[]
|
||||||
|
HttpClient httpClient = new HttpClient();
|
||||||
|
httpClient.start();
|
||||||
|
|
||||||
|
ContentResponse response = httpClient.newRequest("http://domain.com/path")
|
||||||
|
// The connection information is only available starting from the request begin event.
|
||||||
|
.onRequestBegin(request ->
|
||||||
|
{
|
||||||
|
Connection connection = request.getConnection();
|
||||||
|
|
||||||
|
// Obtain the address of the server.
|
||||||
|
SocketAddress remoteAddress = connection.getRemoteSocketAddress();
|
||||||
|
System.getLogger("connection").log(INFO, "Server address: %s", remoteAddress);
|
||||||
|
|
||||||
|
// Obtain the SslSessionData.
|
||||||
|
EndPoint.SslSessionData sslSessionData = connection.getSslSessionData();
|
||||||
|
if (sslSessionData != null)
|
||||||
|
System.getLogger("connection").log(INFO, "SslSessionData: %s", sslSessionData);
|
||||||
|
})
|
||||||
|
.send();
|
||||||
|
// end::connectionInformation[]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -235,7 +235,12 @@ A second request with the same origin sent _after_ the first request/response cy
|
||||||
A second request with the same origin sent _concurrently_ with the first request will likely cause the opening of a second connection, depending on the connection pool implementation.
|
A second request with the same origin sent _concurrently_ with the first request will likely cause the opening of a second connection, depending on the connection pool implementation.
|
||||||
The configuration parameter `HttpClient.maxConnectionsPerDestination` (see also the <<configuration,configuration section>>) controls the max number of connections that can be opened for a destination.
|
The configuration parameter `HttpClient.maxConnectionsPerDestination` (see also the <<configuration,configuration section>>) controls the max number of connections that can be opened for a destination.
|
||||||
|
|
||||||
NOTE: If opening connections to a given origin takes a long time, then requests for that origin will queue up in the corresponding destination until the connections are established.
|
[NOTE]
|
||||||
|
====
|
||||||
|
If opening connections to a given origin takes a long time, then requests for that origin will queue up in the corresponding destination until the connections are established.
|
||||||
|
|
||||||
|
To save the time spent opening connections, you can xref:connection-pool-precreate-connections[pre-create connections].
|
||||||
|
====
|
||||||
|
|
||||||
Each connection can handle a limited number of concurrent requests.
|
Each connection can handle a limited number of concurrent requests.
|
||||||
For HTTP/1.1, this number is always `1`: there can only be one outstanding request for each connection.
|
For HTTP/1.1, this number is always `1`: there can only be one outstanding request for each connection.
|
||||||
|
@ -528,6 +533,28 @@ This is a fancy example of how to mix HTTP versions and low-level transports:
|
||||||
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/client/http/HTTPClientDocs.java[tag=mixedTransports]
|
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/client/http/HTTPClientDocs.java[tag=mixedTransports]
|
||||||
----
|
----
|
||||||
|
|
||||||
|
[[connection-information]]
|
||||||
|
=== Request Connection Information
|
||||||
|
|
||||||
|
In order to send a request, it is necessary to obtain a connection, as explained in the xref:request-processing[request processing section].
|
||||||
|
|
||||||
|
The HTTP/1.1 protocol may send only one request at a time on a single connection, while multiplexed protocols such as HTTP/2 may send many requests at a time on a single connection.
|
||||||
|
|
||||||
|
You can access the connection information, for example the local and remote `SocketAddress`, or the `SslSessionData` if the connection is secured, in the following way:
|
||||||
|
|
||||||
|
[,java,indent=0]
|
||||||
|
----
|
||||||
|
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/client/http/HTTPClientDocs.java[tag=connectionInformation]
|
||||||
|
----
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
====
|
||||||
|
The connection information is only available when the request is associated with a connection.
|
||||||
|
|
||||||
|
This means that the connection is not available in the _request queued_ event, but only starting from the _request begin_ event.
|
||||||
|
For more information about request events, see xref:non-blocking[this section].
|
||||||
|
====
|
||||||
|
|
||||||
[[configuration]]
|
[[configuration]]
|
||||||
== HttpClient Configuration
|
== HttpClient Configuration
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ package org.eclipse.jetty.client;
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
import org.eclipse.jetty.util.Promise;
|
import org.eclipse.jetty.util.Promise;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,4 +64,13 @@ public interface Connection extends Closeable
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the {@link EndPoint.SslSessionData} associated with
|
||||||
|
* the connection, or {@code null} if the connection is not secure.
|
||||||
|
*/
|
||||||
|
default EndPoint.SslSessionData getSslSessionData()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -346,6 +346,12 @@ public class HttpProxy extends ProxyConfiguration.Proxy
|
||||||
return connection.getRemoteSocketAddress();
|
return connection.getRemoteSocketAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EndPoint.SslSessionData getSslSessionData()
|
||||||
|
{
|
||||||
|
return connection.getSslSessionData();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void send(Request request, Response.CompleteListener listener)
|
public void send(Request request, Response.CompleteListener listener)
|
||||||
{
|
{
|
||||||
|
|
|
@ -116,6 +116,12 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements IConne
|
||||||
return delegate.getRemoteSocketAddress();
|
return delegate.getRemoteSocketAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EndPoint.SslSessionData getSslSessionData()
|
||||||
|
{
|
||||||
|
return delegate.getSslSessionData();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getBytesIn()
|
public long getBytesIn()
|
||||||
{
|
{
|
||||||
|
@ -350,6 +356,12 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements IConne
|
||||||
return getEndPoint().getRemoteSocketAddress();
|
return getEndPoint().getRemoteSocketAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EndPoint.SslSessionData getSslSessionData()
|
||||||
|
{
|
||||||
|
return getEndPoint().getSslSessionData();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SendFailure send(HttpExchange exchange)
|
public SendFailure send(HttpExchange exchange)
|
||||||
{
|
{
|
||||||
|
|
|
@ -101,6 +101,12 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements IConne
|
||||||
return delegate.getRemoteSocketAddress();
|
return delegate.getRemoteSocketAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EndPoint.SslSessionData getSslSessionData()
|
||||||
|
{
|
||||||
|
return delegate.getSslSessionData();
|
||||||
|
}
|
||||||
|
|
||||||
protected Flusher getFlusher()
|
protected Flusher getFlusher()
|
||||||
{
|
{
|
||||||
return flusher;
|
return flusher;
|
||||||
|
@ -359,6 +365,12 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements IConne
|
||||||
return getEndPoint().getRemoteSocketAddress();
|
return getEndPoint().getRemoteSocketAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EndPoint.SslSessionData getSslSessionData()
|
||||||
|
{
|
||||||
|
return getEndPoint().getSslSessionData();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SendFailure send(HttpExchange exchange)
|
public SendFailure send(HttpExchange exchange)
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,6 +44,7 @@ import org.eclipse.jetty.http2.HTTP2Session;
|
||||||
import org.eclipse.jetty.http2.api.Session;
|
import org.eclipse.jetty.http2.api.Session;
|
||||||
import org.eclipse.jetty.http2.api.Stream;
|
import org.eclipse.jetty.http2.api.Stream;
|
||||||
import org.eclipse.jetty.http2.frames.HeadersFrame;
|
import org.eclipse.jetty.http2.frames.HeadersFrame;
|
||||||
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
import org.eclipse.jetty.util.Callback;
|
import org.eclipse.jetty.util.Callback;
|
||||||
import org.eclipse.jetty.util.thread.Sweeper;
|
import org.eclipse.jetty.util.thread.Sweeper;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -85,6 +86,12 @@ public class HttpConnectionOverHTTP2 extends HttpConnection implements Sweeper.S
|
||||||
return session.getRemoteSocketAddress();
|
return session.getRemoteSocketAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EndPoint.SslSessionData getSslSessionData()
|
||||||
|
{
|
||||||
|
return connection.getEndPoint().getSslSessionData();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isRecycleHttpChannels()
|
public boolean isRecycleHttpChannels()
|
||||||
{
|
{
|
||||||
return recycleHttpChannels;
|
return recycleHttpChannels;
|
||||||
|
|
|
@ -30,6 +30,8 @@ import org.eclipse.jetty.client.transport.HttpRequest;
|
||||||
import org.eclipse.jetty.client.transport.SendFailure;
|
import org.eclipse.jetty.client.transport.SendFailure;
|
||||||
import org.eclipse.jetty.http.HttpVersion;
|
import org.eclipse.jetty.http.HttpVersion;
|
||||||
import org.eclipse.jetty.http3.client.HTTP3SessionClient;
|
import org.eclipse.jetty.http3.client.HTTP3SessionClient;
|
||||||
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
|
import org.eclipse.jetty.quic.common.QuicSession;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -64,6 +66,13 @@ public class HttpConnectionOverHTTP3 extends HttpConnection implements Connectio
|
||||||
return session.getRemoteSocketAddress();
|
return session.getRemoteSocketAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EndPoint.SslSessionData getSslSessionData()
|
||||||
|
{
|
||||||
|
QuicSession quicSession = getSession().getProtocolSession().getQuicSession();
|
||||||
|
return EndPoint.SslSessionData.from(null, null, null, quicSession.getPeerCertificates());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxMultiplex()
|
public int getMaxMultiplex()
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,6 +33,7 @@ import java.util.stream.IntStream;
|
||||||
|
|
||||||
import org.eclipse.jetty.client.BytesRequestContent;
|
import org.eclipse.jetty.client.BytesRequestContent;
|
||||||
import org.eclipse.jetty.client.CompletableResponseListener;
|
import org.eclipse.jetty.client.CompletableResponseListener;
|
||||||
|
import org.eclipse.jetty.client.Connection;
|
||||||
import org.eclipse.jetty.client.ContentResponse;
|
import org.eclipse.jetty.client.ContentResponse;
|
||||||
import org.eclipse.jetty.client.Destination;
|
import org.eclipse.jetty.client.Destination;
|
||||||
import org.eclipse.jetty.client.InputStreamResponseListener;
|
import org.eclipse.jetty.client.InputStreamResponseListener;
|
||||||
|
@ -45,6 +46,7 @@ import org.eclipse.jetty.http.HttpStatus;
|
||||||
import org.eclipse.jetty.http.HttpURI;
|
import org.eclipse.jetty.http.HttpURI;
|
||||||
import org.eclipse.jetty.http2.FlowControlStrategy;
|
import org.eclipse.jetty.http2.FlowControlStrategy;
|
||||||
import org.eclipse.jetty.io.Content;
|
import org.eclipse.jetty.io.Content;
|
||||||
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
import org.eclipse.jetty.server.Handler;
|
import org.eclipse.jetty.server.Handler;
|
||||||
import org.eclipse.jetty.server.NetworkConnector;
|
import org.eclipse.jetty.server.NetworkConnector;
|
||||||
import org.eclipse.jetty.server.Request;
|
import org.eclipse.jetty.server.Request;
|
||||||
|
@ -1035,9 +1037,19 @@ public class HttpClientTest extends AbstractTest
|
||||||
ContentResponse response = client.newRequest(newURI(transport))
|
ContentResponse response = client.newRequest(newURI(transport))
|
||||||
.onRequestBegin(r ->
|
.onRequestBegin(r ->
|
||||||
{
|
{
|
||||||
if (r.getConnection() == null)
|
Connection connection = r.getConnection();
|
||||||
|
if (connection == null)
|
||||||
r.abort(new IllegalStateException());
|
r.abort(new IllegalStateException());
|
||||||
})
|
})
|
||||||
|
.onRequestHeaders(r ->
|
||||||
|
{
|
||||||
|
if (transport.isSecure())
|
||||||
|
{
|
||||||
|
EndPoint.SslSessionData sslSessionData = r.getConnection().getSslSessionData();
|
||||||
|
if (sslSessionData == null)
|
||||||
|
r.abort(new IllegalStateException());
|
||||||
|
}
|
||||||
|
})
|
||||||
.send();
|
.send();
|
||||||
|
|
||||||
assertEquals(200, response.getStatus());
|
assertEquals(200, response.getStatus());
|
||||||
|
|
Loading…
Reference in New Issue