-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes #6514 - How to warm up SslConnection.
Implemented "priming" of HTTP/1.1 connections using ConnectionPool.preCreateConnections(int) and HttpClientTransportOverHTTP.setInitializeConnections(true). This sends `OPTIONS * HTTP/1.1` to the server. I tried to implement this feature by forcing a write of 0 bytes from the layer above `SslConnection`, but it did not work when using TLS because in both WriteFlusher and SslConnection the fact that there are 0 bytes left to write is treated specially. Other HTTP versions have no problems because they must initialize the connection by e.g. sending a SETTINGS frame, so they would also initialize TLS. Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
- Loading branch information
Showing
8 changed files
with
208 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 91 additions & 0 deletions
91
...-transports/src/test/java/org/eclipse/jetty/test/client/transport/ConnectionPoolTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package org.eclipse.jetty.test.client.transport; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
import org.eclipse.jetty.client.Destination; | ||
import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP; | ||
import org.eclipse.jetty.fcgi.server.internal.ServerFCGIConnection; | ||
import org.eclipse.jetty.http2.server.internal.HTTP2ServerConnection; | ||
import org.eclipse.jetty.io.Connection; | ||
import org.eclipse.jetty.io.ssl.SslConnection; | ||
import org.eclipse.jetty.quic.server.ServerQuicConnection; | ||
import org.eclipse.jetty.server.internal.HttpConnection; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.MethodSource; | ||
|
||
import static org.hamcrest.MatcherAssert.assertThat; | ||
import static org.hamcrest.Matchers.empty; | ||
import static org.hamcrest.Matchers.greaterThan; | ||
import static org.hamcrest.Matchers.not; | ||
|
||
public class ConnectionPoolTest extends AbstractTest | ||
{ | ||
@ParameterizedTest | ||
@MethodSource("transports") | ||
public void testPreCreateConnections(Transport transport) throws Exception | ||
{ | ||
prepareServer(transport, new EmptyServerHandler()); | ||
ConnectionListener serverConnections = new ConnectionListener(); | ||
connector.addBean(serverConnections); | ||
server.start(); | ||
|
||
startClient(transport); | ||
client.setMaxConnectionsPerDestination(8); | ||
if (transport == Transport.HTTPS) | ||
((HttpClientTransportOverHTTP)client.getTransport()).setInitializeConnections(true); | ||
|
||
var request = client.newRequest(newURI(transport)); | ||
Destination destination = client.resolveDestination(request); | ||
destination.getConnectionPool().preCreateConnections(client.getMaxConnectionsPerDestination()) | ||
.get(5, TimeUnit.SECONDS); | ||
|
||
// Verify that connections have been created. | ||
List<Connection> connections = switch (transport) | ||
{ | ||
case HTTP, HTTPS -> serverConnections.filter(HttpConnection.class); | ||
case H2C, H2 -> serverConnections.filter(HTTP2ServerConnection.class); | ||
case H3 -> serverConnections.filter(ServerQuicConnection.class); | ||
case FCGI -> serverConnections.filter(ServerFCGIConnection.class); | ||
}; | ||
assertThat(connections, not(empty())); | ||
|
||
// Verify that TLS was performed. | ||
List<Connection> sslConnections = switch (transport) | ||
{ | ||
case HTTP, H2C, FCGI, H3 -> null; | ||
case HTTPS, H2 -> serverConnections.filter(SslConnection.class); | ||
}; | ||
if (sslConnections != null) | ||
{ | ||
assertThat(sslConnections.size(), greaterThan(0)); | ||
sslConnections.forEach(c -> assertThat(c.getBytesIn(), greaterThan(0L))); | ||
sslConnections.forEach(c -> assertThat(c.getBytesOut(), greaterThan(0L))); | ||
} | ||
} | ||
|
||
private static class ConnectionListener implements Connection.Listener | ||
{ | ||
private final List<Connection> connections = new ArrayList<>(); | ||
|
||
@Override | ||
public void onOpened(Connection connection) | ||
{ | ||
connections.add(connection); | ||
} | ||
|
||
@Override | ||
public void onClosed(Connection connection) | ||
{ | ||
connections.remove(connection); | ||
} | ||
|
||
private List<Connection> filter(Class<? extends Connection> klass) | ||
{ | ||
return connections.stream() | ||
.filter(klass::isInstance) | ||
.toList(); | ||
} | ||
} | ||
} |