Merge remote-tracking branch 'origin/jetty-12.0.x' into jetty-12.0.x-8426-aliaschecker-review
This commit is contained in:
commit
8e172f311e
|
@ -155,6 +155,18 @@ pipeline {
|
|||
}
|
||||
}
|
||||
}
|
||||
stage("Javadocs") {
|
||||
steps {
|
||||
container('jetty-build') {
|
||||
timeout(time: 120, unit: 'MINUTES') {
|
||||
dir("${env.WORKSPACE}/buildy") {
|
||||
mavenBuild("jdk17", "clean install -DskipTests", "maven3")
|
||||
mavenBuild("jdk17", "javadoc:javadoc", "maven3")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +189,7 @@ def mavenBuild(jdk, cmdline, mvnName) {
|
|||
"MAVEN_OPTS=-Xms2g -Xmx4g -Djava.awt.headless=true"]) {
|
||||
configFileProvider(
|
||||
[configFile(fileId: 'oss-settings.xml', variable: 'GLOBAL_MVN_SETTINGS')]) {
|
||||
sh "mvn --no-transfer-progress -s $GLOBAL_MVN_SETTINGS -Dmaven.repo.local=.repository -Pci -DexcludedGroups=\"external, large-disk-resource, stress, slow\" -V -B -e -Djetty.testtracker.log=true $cmdline"
|
||||
sh "mvn -Dmaven.test.failure.ignore=true --no-transfer-progress -s $GLOBAL_MVN_SETTINGS -Dmaven.repo.local=.repository -Pci -DexcludedGroups=\"external, large-disk-resource, stress, slow\" -V -B -e -Djetty.testtracker.log=true $cmdline"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
13
README.md
13
README.md
|
@ -22,11 +22,22 @@ Webapp Example
|
|||
--------------
|
||||
```shell
|
||||
$ mkdir base && cd base
|
||||
$ java -jar $JETTY_HOME/start.jar --add-modules=http,deploy
|
||||
$ java -jar $JETTY_HOME/start.jar --add-modules=http,ee10-deploy
|
||||
$ cp ~/src/myproj/target/mywebapp.war webapps
|
||||
$ java -jar $JETTY_HOME/start.jar
|
||||
```
|
||||
|
||||
Multiple Versions Webapp Example
|
||||
--------------------------------
|
||||
```shell
|
||||
$ mkdir base && cd base
|
||||
$ java -jar $JETTY_HOME/start.jar --add-modules=http,ee10-deploy,ee8-deploy
|
||||
$ cp ~/src/myproj/target/mywebapp10.war webapps
|
||||
$ cp ~/src/myproj/target/mywebapp8.war webapps
|
||||
$ echo environment: ee8 > webapps/mywebapp8.properties
|
||||
$ java -jar $JETTY_HOME/start.jar
|
||||
```
|
||||
|
||||
Embedded Example
|
||||
----------------
|
||||
```java
|
||||
|
|
|
@ -198,23 +198,23 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi-client</artifactId>
|
||||
<artifactId>jetty-fcgi-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-server</artifactId>
|
||||
<artifactId>jetty-http2-server</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-http-client-transport</artifactId>
|
||||
<artifactId>jetty-http2-client-transport</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http3</groupId>
|
||||
<artifactId>http3-server</artifactId>
|
||||
<artifactId>jetty-http3-server</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http3</groupId>
|
||||
<artifactId>http3-http-client-transport</artifactId>
|
||||
<artifactId>jetty-http3-client-transport</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
|
|
|
@ -31,7 +31,7 @@ The Maven artifact coordinates for the HTTP/2 client library are the following:
|
|||
----
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-client</artifactId>
|
||||
<artifactId>jetty-http2-client</artifactId>
|
||||
<version>{version}</version>
|
||||
</dependency>
|
||||
----
|
||||
|
|
|
@ -31,7 +31,7 @@ The Maven artifact coordinates for the HTTP/3 client library are the following:
|
|||
----
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http3</groupId>
|
||||
<artifactId>http3-client</artifactId>
|
||||
<artifactId>jetty-http3-client</artifactId>
|
||||
<version>{version}</version>
|
||||
</dependency>
|
||||
----
|
||||
|
|
|
@ -29,7 +29,7 @@ The Maven artifact coordinates for the HTTP/2 client library are the following:
|
|||
----
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-server</artifactId>
|
||||
<artifactId>jetty-http2-server</artifactId>
|
||||
<version>{version}</version>
|
||||
</dependency>
|
||||
----
|
||||
|
|
|
@ -29,7 +29,7 @@ The Maven artifact coordinates for the HTTP/3 client library are the following:
|
|||
----
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http3</groupId>
|
||||
<artifactId>http3-server</artifactId>
|
||||
<artifactId>jetty-http3-server</artifactId>
|
||||
<version>{version}</version>
|
||||
</dependency>
|
||||
----
|
||||
|
|
|
@ -60,10 +60,10 @@ import org.eclipse.jetty.http.HttpMethod;
|
|||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
import org.eclipse.jetty.http2.client.HTTP2Client;
|
||||
import org.eclipse.jetty.http2.client.http.ClientConnectionFactoryOverHTTP2;
|
||||
import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
|
||||
import org.eclipse.jetty.http2.client.transport.ClientConnectionFactoryOverHTTP2;
|
||||
import org.eclipse.jetty.http2.client.transport.HttpClientTransportOverHTTP2;
|
||||
import org.eclipse.jetty.http3.client.HTTP3Client;
|
||||
import org.eclipse.jetty.http3.client.http.HttpClientTransportOverHTTP3;
|
||||
import org.eclipse.jetty.http3.client.transport.HttpClientTransportOverHTTP3;
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.ClientConnectionFactory;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
|
|
|
@ -27,8 +27,8 @@ import org.eclipse.jetty.ee10.websocket.client.ClientUpgradeRequest;
|
|||
import org.eclipse.jetty.ee10.websocket.client.JettyUpgradeListener;
|
||||
import org.eclipse.jetty.ee10.websocket.client.WebSocketClient;
|
||||
import org.eclipse.jetty.http2.client.HTTP2Client;
|
||||
import org.eclipse.jetty.http2.client.http.ClientConnectionFactoryOverHTTP2;
|
||||
import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
|
||||
import org.eclipse.jetty.http2.client.transport.ClientConnectionFactoryOverHTTP2;
|
||||
import org.eclipse.jetty.http2.client.transport.HttpClientTransportOverHTTP2;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
|
|
@ -36,9 +36,6 @@ import org.eclipse.jetty.util.thread.SerializedInvoker;
|
|||
@SuppressWarnings("unused")
|
||||
public class HandlerDocs
|
||||
{
|
||||
// TODO this class has been temporarily moved to jetty-core/jetty-demo
|
||||
// move it back when documentation is re-enabled
|
||||
|
||||
public static class HelloHandler0 extends Handler.Abstract
|
||||
{
|
||||
@Override
|
||||
|
|
|
@ -135,17 +135,7 @@
|
|||
<doctitle>Eclipse Jetty API Doc - v${project.version}</doctitle>
|
||||
<windowtitle>Eclipse Jetty API Doc - v${project.version}</windowtitle>
|
||||
<excludePackageNames>
|
||||
org.eclipse.jetty.http3.client.http.internal;
|
||||
org.eclipse.jetty.http3.client.internal;
|
||||
org.eclipse.jetty.http3.internal;
|
||||
org.eclipse.jetty.http3.internal.*;
|
||||
org.eclipse.jetty.http3.qpack.internal;
|
||||
org.eclipse.jetty.http3.qpack.internal.*;
|
||||
org.eclipse.jetty.http3.server.internal;
|
||||
org.eclipse.jetty.quic.common.internal;
|
||||
org.eclipse.jetty.quic.quiche;
|
||||
org.eclipse.jetty.quic.quiche.*;
|
||||
org.eclipse.jetty.quic.server.internal;
|
||||
org.eclipse.jetty.http3.client.transport.internal; org.eclipse.jetty.http3.client.internal; org.eclipse.jetty.http3.internal; org.eclipse.jetty.http3.internal.*; org.eclipse.jetty.http3.qpack.internal; org.eclipse.jetty.http3.qpack.internal.*; org.eclipse.jetty.http3.server.internal; org.eclipse.jetty.quic.common.internal; org.eclipse.jetty.quic.quiche; org.eclipse.jetty.quic.quiche.*; org.eclipse.jetty.quic.server.internal;
|
||||
</excludePackageNames>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
@ -160,11 +150,6 @@
|
|||
<artifactId>jetty-annotations</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-ant</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-client</artifactId>
|
||||
|
@ -217,12 +202,12 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi-client</artifactId>
|
||||
<artifactId>jetty-fcgi-client</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi-server</artifactId>
|
||||
<artifactId>jetty-fcgi-server</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -237,32 +222,32 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-client</artifactId>
|
||||
<artifactId>jetty-http2-client</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-http-client-transport</artifactId>
|
||||
<artifactId>jetty-http2-client-transport</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-server</artifactId>
|
||||
<artifactId>jetty-http2-server</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http3</groupId>
|
||||
<artifactId>http3-client</artifactId>
|
||||
<artifactId>jetty-http3-client</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http3</groupId>
|
||||
<artifactId>http3-http-client-transport</artifactId>
|
||||
<artifactId>jetty-http3-client-transport</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http3</groupId>
|
||||
<artifactId>http3-server</artifactId>
|
||||
<artifactId>jetty-http3-server</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -297,12 +282,12 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.quic</groupId>
|
||||
<artifactId>quic-client</artifactId>
|
||||
<artifactId>jetty-quic-client</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.quic</groupId>
|
||||
<artifactId>quic-server</artifactId>
|
||||
<artifactId>jetty-quic-server</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -117,12 +117,12 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi-client</artifactId>
|
||||
<artifactId>jetty-fcgi-client</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi-server</artifactId>
|
||||
<artifactId>jetty-fcgi-server</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -149,52 +149,52 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-client</artifactId>
|
||||
<artifactId>jetty-http2-client</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-common</artifactId>
|
||||
<artifactId>jetty-http2-common</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-hpack</artifactId>
|
||||
<artifactId>jetty-http2-hpack</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-http-client-transport</artifactId>
|
||||
<artifactId>jetty-http2-client-transport</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-server</artifactId>
|
||||
<artifactId>jetty-http2-server</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http3</groupId>
|
||||
<artifactId>http3-client</artifactId>
|
||||
<artifactId>jetty-http3-client</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http3</groupId>
|
||||
<artifactId>http3-common</artifactId>
|
||||
<artifactId>jetty-http3-common</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http3</groupId>
|
||||
<artifactId>http3-http-client-transport</artifactId>
|
||||
<artifactId>jetty-http3-client-transport</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http3</groupId>
|
||||
<artifactId>http3-qpack</artifactId>
|
||||
<artifactId>jetty-http3-qpack</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http3</groupId>
|
||||
<artifactId>http3-server</artifactId>
|
||||
<artifactId>jetty-http3-server</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -294,27 +294,27 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.quic</groupId>
|
||||
<artifactId>quic-client</artifactId>
|
||||
<artifactId>jetty-quic-client</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.quic</groupId>
|
||||
<artifactId>quic-common</artifactId>
|
||||
<artifactId>jetty-quic-common</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.quic</groupId>
|
||||
<artifactId>quic-quiche-common</artifactId>
|
||||
<artifactId>jetty-quic-quiche-common</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.quic</groupId>
|
||||
<artifactId>quic-quiche-jna</artifactId>
|
||||
<artifactId>jetty-quic-quiche-jna</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.quic</groupId>
|
||||
<artifactId>quic-server</artifactId>
|
||||
<artifactId>jetty-quic-server</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -449,17 +449,17 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-core-common</artifactId>
|
||||
<artifactId>jetty-websocket-core-common</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-core-client</artifactId>
|
||||
<artifactId>jetty-websocket-core-client</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-core-server</artifactId>
|
||||
<artifactId>jetty-websocket-core-server</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -480,7 +480,7 @@
|
|||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.quic</groupId>
|
||||
<artifactId>quic-quiche-foreign-incubator</artifactId>
|
||||
<artifactId>jetty-quic-quiche-foreign-incubator</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-client</artifactId>
|
||||
<artifactId>jetty-http2-client</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-server</artifactId>
|
||||
<artifactId>jetty-http2-server</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -53,12 +53,12 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-client</artifactId>
|
||||
<artifactId>jetty-http2-client</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-http-client-transport</artifactId>
|
||||
<artifactId>jetty-http2-client-transport</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
|
|||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.http2.client.HTTP2Client;
|
||||
import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
|
||||
import org.eclipse.jetty.http2.client.transport.HttpClientTransportOverHTTP2;
|
||||
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-client</artifactId>
|
||||
<artifactId>jetty-http2-client</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-server</artifactId>
|
||||
<artifactId>jetty-http2-server</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -97,12 +97,12 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi-client</artifactId>
|
||||
<artifactId>jetty-fcgi-client</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi-server</artifactId>
|
||||
<artifactId>jetty-fcgi-server</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -129,52 +129,52 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-client</artifactId>
|
||||
<artifactId>jetty-http2-client</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-common</artifactId>
|
||||
<artifactId>jetty-http2-common</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-hpack</artifactId>
|
||||
<artifactId>jetty-http2-hpack</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-http-client-transport</artifactId>
|
||||
<artifactId>jetty-http2-client-transport</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-server</artifactId>
|
||||
<artifactId>jetty-http2-server</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http3</groupId>
|
||||
<artifactId>http3-client</artifactId>
|
||||
<artifactId>jetty-http3-client</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http3</groupId>
|
||||
<artifactId>http3-common</artifactId>
|
||||
<artifactId>jetty-http3-common</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http3</groupId>
|
||||
<artifactId>http3-http-client-transport</artifactId>
|
||||
<artifactId>jetty-http3-client-transport</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http3</groupId>
|
||||
<artifactId>http3-qpack</artifactId>
|
||||
<artifactId>jetty-http3-qpack</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http3</groupId>
|
||||
<artifactId>http3-server</artifactId>
|
||||
<artifactId>jetty-http3-server</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -244,27 +244,27 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.quic</groupId>
|
||||
<artifactId>quic-client</artifactId>
|
||||
<artifactId>jetty-quic-client</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.quic</groupId>
|
||||
<artifactId>quic-common</artifactId>
|
||||
<artifactId>jetty-quic-common</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.quic</groupId>
|
||||
<artifactId>quic-quiche-common</artifactId>
|
||||
<artifactId>jetty-quic-quiche-common</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.quic</groupId>
|
||||
<artifactId>quic-quiche-jna</artifactId>
|
||||
<artifactId>jetty-quic-quiche-jna</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.quic</groupId>
|
||||
<artifactId>quic-server</artifactId>
|
||||
<artifactId>jetty-quic-server</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -315,17 +315,17 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-core-common</artifactId>
|
||||
<artifactId>jetty-websocket-core-common</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-core-client</artifactId>
|
||||
<artifactId>jetty-websocket-core-client</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-core-server</artifactId>
|
||||
<artifactId>jetty-websocket-core-server</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -346,7 +346,7 @@
|
|||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.quic</groupId>
|
||||
<artifactId>quic-quiche-foreign-incubator</artifactId>
|
||||
<artifactId>jetty-quic-quiche-foreign-incubator</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
|
|
@ -51,24 +51,16 @@ public abstract class AbstractConnectionPool extends ContainerLifeCycle implemen
|
|||
private final Callback requester;
|
||||
private final Pool<Connection> pool;
|
||||
private boolean maximizeConnections;
|
||||
private volatile long maxDurationNanos = 0L;
|
||||
private volatile long maxDurationNanos;
|
||||
private volatile int maxUsage;
|
||||
private volatile int initialMaxMultiplex;
|
||||
|
||||
protected AbstractConnectionPool(HttpDestination destination, int maxConnections, boolean cache, Callback requester)
|
||||
{
|
||||
this(destination, Pool.StrategyType.FIRST, maxConnections, cache, requester);
|
||||
}
|
||||
|
||||
protected AbstractConnectionPool(HttpDestination destination, Pool.StrategyType strategy, int maxConnections, boolean cache, Callback requester)
|
||||
{
|
||||
this(destination, new Pool<>(strategy, maxConnections, cache), requester);
|
||||
}
|
||||
|
||||
protected AbstractConnectionPool(HttpDestination destination, Pool<Connection> pool, Callback requester)
|
||||
protected AbstractConnectionPool(HttpDestination destination, Pool<Connection> pool, Callback requester, int initialMaxMultiplex)
|
||||
{
|
||||
this.destination = destination;
|
||||
this.requester = requester;
|
||||
this.pool = pool;
|
||||
pool.setMaxMultiplex(1); // Force the use of multiplexing.
|
||||
this.initialMaxMultiplex = initialMaxMultiplex;
|
||||
addBean(pool);
|
||||
}
|
||||
|
||||
|
@ -101,14 +93,17 @@ public abstract class AbstractConnectionPool extends ContainerLifeCycle implemen
|
|||
}
|
||||
|
||||
/**
|
||||
* <p>Get the max usage duration in milliseconds of the pool's connections.
|
||||
* Values {@code 0} and negative mean that there is no limit.</p>
|
||||
* <p>This only guarantees that a connection cannot be acquired after the configured
|
||||
* duration elapses, so that is only enforced when {@link #acquire(boolean)} is called.
|
||||
* If a pool stays completely idle for a duration longer than the value
|
||||
* <p>Returns the max usage duration in milliseconds of a pooled connection.</p>
|
||||
* <p>Values {@code 0} and negative mean that there is no limit.</p>
|
||||
* <p>This property only guarantees that a connection cannot be acquired
|
||||
* after the configured duration elapses, so that is only enforced when
|
||||
* {@link #acquire(boolean)} is called.</p>
|
||||
* <p>If a pool stays completely idle for a duration longer than the value
|
||||
* returned by this method, the max duration will not be enforced.
|
||||
* It's up to the idle timeout mechanism (see {@link HttpClient#getIdleTimeout()})
|
||||
* to handle closing idle connections.</p>
|
||||
*
|
||||
* @return the max usage duration, in milliseconds, of a pooled connection
|
||||
*/
|
||||
@ManagedAttribute(value = "The maximum duration in milliseconds a connection can be used for before it gets closed")
|
||||
public long getMaxDuration()
|
||||
|
@ -121,24 +116,31 @@ public abstract class AbstractConnectionPool extends ContainerLifeCycle implemen
|
|||
this.maxDurationNanos = TimeUnit.MILLISECONDS.toNanos(maxDurationInMs);
|
||||
}
|
||||
|
||||
protected int getMaxMultiplex()
|
||||
protected int getInitialMaxMultiplex()
|
||||
{
|
||||
return pool.getMaxMultiplex();
|
||||
return initialMaxMultiplex;
|
||||
}
|
||||
|
||||
protected void setMaxMultiplex(int maxMultiplex)
|
||||
protected void setInitialMaxMultiplex(int initialMaxMultiplex)
|
||||
{
|
||||
pool.setMaxMultiplex(maxMultiplex);
|
||||
this.initialMaxMultiplex = initialMaxMultiplex;
|
||||
}
|
||||
|
||||
protected int getMaxUsageCount()
|
||||
/**
|
||||
* <p>Returns the max number of times a pooled connection can be used.</p>
|
||||
* <p>Values {@code 0} and negative mean that there is no limit.</p>
|
||||
*
|
||||
* @return the max number of times a pooled connection can be used
|
||||
*/
|
||||
@ManagedAttribute(value = "The maximum amount of times a connection is used before it gets closed")
|
||||
public int getMaxUsage()
|
||||
{
|
||||
return pool.getMaxUsageCount();
|
||||
return maxUsage;
|
||||
}
|
||||
|
||||
protected void setMaxUsageCount(int maxUsageCount)
|
||||
public void setMaxUsage(int maxUsage)
|
||||
{
|
||||
pool.setMaxUsageCount(maxUsageCount);
|
||||
this.maxUsage = maxUsage;
|
||||
}
|
||||
|
||||
@ManagedAttribute(value = "The number of active connections", readonly = true)
|
||||
|
@ -235,7 +237,7 @@ public abstract class AbstractConnectionPool extends ContainerLifeCycle implemen
|
|||
* <p>Whether a new connection is created is determined by the {@code create} parameter
|
||||
* and a count of demand and supply, where the demand is derived from the number of
|
||||
* queued requests, and the supply is the number of pending connections time the
|
||||
* {@link #getMaxMultiplex()} factor: if the demand is less than the supply, the
|
||||
* {@link #getInitialMaxMultiplex()} factor: if the demand is less than the supply, the
|
||||
* connection will not be created.</p>
|
||||
* <p>Since the number of queued requests used to derive the demand may be a stale
|
||||
* value, it is possible that few more connections than strictly necessary may be
|
||||
|
@ -250,7 +252,7 @@ public abstract class AbstractConnectionPool extends ContainerLifeCycle implemen
|
|||
LOG.debug("Try creating connection {}/{} with {} pending", connectionCount, getMaxConnectionCount(), getPendingConnectionCount());
|
||||
|
||||
// If we have already pending sufficient multiplexed connections, then do not create another.
|
||||
int multiplexed = getMaxMultiplex();
|
||||
int multiplexed = getInitialMaxMultiplex();
|
||||
while (true)
|
||||
{
|
||||
int pending = this.pending.get();
|
||||
|
@ -288,14 +290,13 @@ public abstract class AbstractConnectionPool extends ContainerLifeCycle implemen
|
|||
@Override
|
||||
public boolean accept(Connection connection)
|
||||
{
|
||||
if (!(connection instanceof Attachable))
|
||||
if (!(connection instanceof Attachable attachable))
|
||||
throw new IllegalArgumentException("Invalid connection object: " + connection);
|
||||
Pool<Connection>.Entry entry = pool.reserve();
|
||||
if (entry == null)
|
||||
return false;
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("onCreating {} {}", entry, connection);
|
||||
Attachable attachable = (Attachable)connection;
|
||||
attachable.setAttachment(new EntryHolder(entry));
|
||||
onCreated(connection);
|
||||
entry.enable(connection, false);
|
||||
|
@ -327,11 +328,29 @@ public abstract class AbstractConnectionPool extends ContainerLifeCycle implemen
|
|||
if (canClose)
|
||||
IO.close(connection);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Connection removed{} due to expiration {} {}", (canClose ? " and closed" : ""), entry, pool);
|
||||
LOG.debug("Connection removed{}: expired {} {}", (canClose ? " and closed" : ""), entry, pool);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
int maxUsage = getMaxUsage();
|
||||
if (connection instanceof MaxUsable maxUsable)
|
||||
maxUsage = maxUsable.getMaxUsage();
|
||||
if (maxUsage > 0)
|
||||
{
|
||||
EntryHolder holder = (EntryHolder)((Attachable)connection).getAttachment();
|
||||
if (!holder.use(maxUsage))
|
||||
{
|
||||
boolean canClose = remove(connection);
|
||||
if (canClose)
|
||||
IO.close(connection);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Connection removed{}: over used {} {}", (canClose ? " and closed" : ""), entry, pool);
|
||||
continue;
|
||||
}
|
||||
// Entry is now used, so it must be acquired.
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Activated {} {}", entry, pool);
|
||||
acquired(connection);
|
||||
|
@ -344,9 +363,8 @@ public abstract class AbstractConnectionPool extends ContainerLifeCycle implemen
|
|||
@Override
|
||||
public boolean isActive(Connection connection)
|
||||
{
|
||||
if (!(connection instanceof Attachable))
|
||||
if (!(connection instanceof Attachable attachable))
|
||||
throw new IllegalArgumentException("Invalid connection object: " + connection);
|
||||
Attachable attachable = (Attachable)connection;
|
||||
EntryHolder holder = (EntryHolder)attachable.getAttachment();
|
||||
if (holder == null)
|
||||
return false;
|
||||
|
@ -364,9 +382,8 @@ public abstract class AbstractConnectionPool extends ContainerLifeCycle implemen
|
|||
|
||||
protected boolean deactivate(Connection connection)
|
||||
{
|
||||
if (!(connection instanceof Attachable))
|
||||
if (!(connection instanceof Attachable attachable))
|
||||
throw new IllegalArgumentException("Invalid connection object: " + connection);
|
||||
Attachable attachable = (Attachable)connection;
|
||||
EntryHolder holder = (EntryHolder)attachable.getAttachment();
|
||||
if (holder == null)
|
||||
return true;
|
||||
|
@ -377,28 +394,33 @@ public abstract class AbstractConnectionPool extends ContainerLifeCycle implemen
|
|||
// Remove instead of release if the connection expired.
|
||||
return !remove(connection);
|
||||
}
|
||||
else
|
||||
|
||||
int maxUsage = getMaxUsage();
|
||||
if (connection instanceof MaxUsable maxUsable)
|
||||
maxUsage = maxUsable.getMaxUsage();
|
||||
if (maxUsage > 0 && holder.isOverUsed(maxUsage))
|
||||
{
|
||||
// Release if the connection has not expired, then remove if not reusable.
|
||||
boolean reusable = pool.release(holder.entry);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Released ({}) {} {}", reusable, holder.entry, pool);
|
||||
if (reusable)
|
||||
return true;
|
||||
// Remove instead of release if the connection is overused.
|
||||
return !remove(connection);
|
||||
}
|
||||
|
||||
boolean reusable = holder.entry.release();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Released ({}) {} {}", reusable, holder.entry, pool);
|
||||
if (reusable)
|
||||
return true;
|
||||
return !remove(connection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Connection connection)
|
||||
{
|
||||
if (!(connection instanceof Attachable))
|
||||
if (!(connection instanceof Attachable attachable))
|
||||
throw new IllegalArgumentException("Invalid connection object: " + connection);
|
||||
Attachable attachable = (Attachable)connection;
|
||||
EntryHolder holder = (EntryHolder)attachable.getAttachment();
|
||||
if (holder == null)
|
||||
return false;
|
||||
boolean removed = pool.remove(holder.entry);
|
||||
boolean removed = holder.entry.remove();
|
||||
if (removed)
|
||||
attachable.setAttachment(null);
|
||||
if (LOG.isDebugEnabled())
|
||||
|
@ -411,12 +433,6 @@ public abstract class AbstractConnectionPool extends ContainerLifeCycle implemen
|
|||
return removed;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
protected boolean remove(Connection connection, boolean force)
|
||||
{
|
||||
return remove(connection);
|
||||
}
|
||||
|
||||
protected void onCreated(Connection connection)
|
||||
{
|
||||
}
|
||||
|
@ -575,7 +591,8 @@ public abstract class AbstractConnectionPool extends ContainerLifeCycle implemen
|
|||
private static class EntryHolder
|
||||
{
|
||||
private final Pool<Connection>.Entry entry;
|
||||
private final long creationTimestamp = System.nanoTime();
|
||||
private final long creationNanos = System.nanoTime();
|
||||
private final AtomicInteger usage = new AtomicInteger();
|
||||
|
||||
private EntryHolder(Pool<Connection>.Entry entry)
|
||||
{
|
||||
|
@ -584,7 +601,24 @@ public abstract class AbstractConnectionPool extends ContainerLifeCycle implemen
|
|||
|
||||
private boolean isExpired(long timeoutNanos)
|
||||
{
|
||||
return System.nanoTime() - creationTimestamp >= timeoutNanos;
|
||||
return System.nanoTime() - creationNanos >= timeoutNanos;
|
||||
}
|
||||
|
||||
private boolean use(int maxUsage)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
int current = usage.get();
|
||||
if (current >= maxUsage)
|
||||
return false;
|
||||
if (usage.compareAndSet(current, current + 1))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOverUsed(int maxUsage)
|
||||
{
|
||||
return usage.get() >= maxUsage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,21 +108,12 @@ public interface ConnectionPool extends Closeable
|
|||
/**
|
||||
* Marks a connection as supporting multiplexed requests.
|
||||
*/
|
||||
interface Multiplexable
|
||||
interface MaxMultiplexable
|
||||
{
|
||||
/**
|
||||
* @return the max number of requests multiplexable on a single connection
|
||||
*/
|
||||
int getMaxMultiplex();
|
||||
|
||||
/**
|
||||
* @param maxMultiplex the max number of requests multiplexable on a single connection
|
||||
* @deprecated do not use, as the maxMultiplex value is pulled, rather than pushed
|
||||
*/
|
||||
@Deprecated
|
||||
default void setMaxMultiplex(int maxMultiplex)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -133,6 +124,6 @@ public interface ConnectionPool extends Closeable
|
|||
/**
|
||||
* @return the max number of requests on a single connection
|
||||
*/
|
||||
int getMaxUsageCount();
|
||||
int getMaxUsage();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,10 +13,8 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import org.eclipse.jetty.client.api.Connection;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Pool;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
|
||||
@ManagedObject
|
||||
|
@ -24,30 +22,6 @@ public class DuplexConnectionPool extends AbstractConnectionPool
|
|||
{
|
||||
public DuplexConnectionPool(HttpDestination destination, int maxConnections, Callback requester)
|
||||
{
|
||||
this(destination, maxConnections, false, requester);
|
||||
}
|
||||
|
||||
public DuplexConnectionPool(HttpDestination destination, int maxConnections, boolean cache, Callback requester)
|
||||
{
|
||||
super(destination, Pool.StrategyType.FIRST, maxConnections, cache, requester);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public DuplexConnectionPool(HttpDestination destination, Pool<Connection> pool, Callback requester)
|
||||
{
|
||||
super(destination, pool, requester);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ManagedAttribute(value = "The maximum amount of times a connection is used before it gets closed")
|
||||
public int getMaxUsageCount()
|
||||
{
|
||||
return super.getMaxUsageCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxUsageCount(int maxUsageCount)
|
||||
{
|
||||
super.setMaxUsageCount(maxUsageCount);
|
||||
super(destination, new Pool<>(Pool.StrategyType.FIRST, maxConnections, false), requester, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ManagedObject
|
||||
public abstract class HttpDestination extends ContainerLifeCycle implements Destination, Closeable, Callback, Dumpable
|
||||
public class HttpDestination extends ContainerLifeCycle implements Destination, Closeable, Callback, Dumpable
|
||||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(HttpDestination.class);
|
||||
|
||||
|
@ -519,12 +519,6 @@ public abstract class HttpDestination extends ContainerLifeCycle implements Dest
|
|||
getConnectionPool());
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Multiplexed
|
||||
{
|
||||
void setMaxRequestsPerConnection(int maxRequestsPerConnection);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Enforces the total timeout for for exchanges that are still in the queue.</p>
|
||||
* <p>The total timeout for exchanges that are not in the destination queue
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import org.eclipse.jetty.client.api.Connection;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Pool;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
|
@ -22,71 +21,32 @@ import org.eclipse.jetty.util.annotation.ManagedObject;
|
|||
@ManagedObject
|
||||
public class MultiplexConnectionPool extends AbstractConnectionPool
|
||||
{
|
||||
public MultiplexConnectionPool(HttpDestination destination, int maxConnections, Callback requester, int maxMultiplex)
|
||||
public MultiplexConnectionPool(HttpDestination destination, int maxConnections, Callback requester, int initialMaxMultiplex)
|
||||
{
|
||||
this(destination, maxConnections, false, requester, maxMultiplex);
|
||||
this(destination, Pool.StrategyType.FIRST, maxConnections, false, requester, initialMaxMultiplex);
|
||||
}
|
||||
|
||||
public MultiplexConnectionPool(HttpDestination destination, int maxConnections, boolean cache, Callback requester, int maxMultiplex)
|
||||
protected MultiplexConnectionPool(HttpDestination destination, Pool.StrategyType strategy, int maxConnections, boolean cache, Callback requester, int initialMaxMultiplex)
|
||||
{
|
||||
this(destination, Pool.StrategyType.FIRST, maxConnections, cache, requester, maxMultiplex);
|
||||
}
|
||||
|
||||
public MultiplexConnectionPool(HttpDestination destination, Pool.StrategyType strategy, int maxConnections, boolean cache, Callback requester, int maxMultiplex)
|
||||
{
|
||||
super(destination, new Pool<>(strategy, maxConnections, cache)
|
||||
super(destination, new Pool<>(strategy, maxConnections, cache, connection ->
|
||||
{
|
||||
@Override
|
||||
protected int getMaxUsageCount(Connection connection)
|
||||
{
|
||||
int maxUsage = (connection instanceof MaxUsable)
|
||||
? ((MaxUsable)connection).getMaxUsageCount()
|
||||
: super.getMaxUsageCount(connection);
|
||||
return maxUsage > 0 ? maxUsage : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxMultiplex(Connection connection)
|
||||
{
|
||||
int multiplex = (connection instanceof Multiplexable)
|
||||
? ((Multiplexable)connection).getMaxMultiplex()
|
||||
: super.getMaxMultiplex(connection);
|
||||
return multiplex > 0 ? multiplex : 1;
|
||||
}
|
||||
}, requester);
|
||||
setMaxMultiplex(maxMultiplex);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public MultiplexConnectionPool(HttpDestination destination, Pool<Connection> pool, Callback requester, int maxMultiplex)
|
||||
{
|
||||
super(destination, pool, requester);
|
||||
setMaxMultiplex(maxMultiplex);
|
||||
int maxMultiplex = initialMaxMultiplex;
|
||||
if (connection instanceof MaxMultiplexable maxMultiplexable)
|
||||
maxMultiplex = maxMultiplexable.getMaxMultiplex();
|
||||
return maxMultiplex;
|
||||
}), requester, initialMaxMultiplex);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ManagedAttribute(value = "The multiplexing factor of connections")
|
||||
public int getMaxMultiplex()
|
||||
@ManagedAttribute(value = "The initial multiplexing factor of connections")
|
||||
public int getInitialMaxMultiplex()
|
||||
{
|
||||
return super.getMaxMultiplex();
|
||||
return super.getInitialMaxMultiplex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxMultiplex(int maxMultiplex)
|
||||
public void setInitialMaxMultiplex(int initialMaxMultiplex)
|
||||
{
|
||||
super.setMaxMultiplex(maxMultiplex);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ManagedAttribute(value = "The maximum amount of times a connection is used before it gets closed")
|
||||
public int getMaxUsageCount()
|
||||
{
|
||||
return super.getMaxUsageCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxUsageCount(int maxUsageCount)
|
||||
{
|
||||
super.setMaxUsageCount(maxUsageCount);
|
||||
super.setInitialMaxMultiplex(initialMaxMultiplex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
|
||||
/**
|
||||
* <p>A destination for those transports that are multiplex (e.g. HTTP/2).</p>
|
||||
* <p>Transports that negotiate the protocol, and therefore do not know in advance
|
||||
* whether they are duplex or multiplex, should use this class and when the
|
||||
* cardinality is known call {@link #setMaxRequestsPerConnection(int)} with
|
||||
* the proper cardinality.</p>
|
||||
* <p>If the cardinality is {@code 1}, the behavior of this class is similar
|
||||
* to that of {@link DuplexHttpDestination}.</p>
|
||||
*/
|
||||
public class MultiplexHttpDestination extends HttpDestination implements HttpDestination.Multiplexed
|
||||
{
|
||||
public MultiplexHttpDestination(HttpClient client, Origin origin)
|
||||
{
|
||||
this(client, origin, false);
|
||||
}
|
||||
|
||||
public MultiplexHttpDestination(HttpClient client, Origin origin, boolean intrinsicallySecure)
|
||||
{
|
||||
super(client, origin, intrinsicallySecure);
|
||||
}
|
||||
|
||||
@ManagedAttribute(value = "The maximum number of concurrent requests per connection")
|
||||
public int getMaxRequestsPerConnection()
|
||||
{
|
||||
ConnectionPool connectionPool = getConnectionPool();
|
||||
if (connectionPool instanceof AbstractConnectionPool)
|
||||
return ((AbstractConnectionPool)connectionPool).getMaxMultiplex();
|
||||
return 1;
|
||||
}
|
||||
|
||||
public void setMaxRequestsPerConnection(int maxRequestsPerConnection)
|
||||
{
|
||||
ConnectionPool connectionPool = getConnectionPool();
|
||||
if (connectionPool instanceof AbstractConnectionPool)
|
||||
((AbstractConnectionPool)connectionPool).setMaxMultiplex(maxRequestsPerConnection);
|
||||
}
|
||||
}
|
|
@ -61,7 +61,7 @@ public class ValidatingConnectionPool extends DuplexConnectionPool
|
|||
|
||||
public ValidatingConnectionPool(HttpDestination destination, int maxConnections, Callback requester, Scheduler scheduler, long timeout)
|
||||
{
|
||||
super((HttpDestination)destination, maxConnections, requester);
|
||||
super(destination, maxConnections, requester);
|
||||
this.scheduler = scheduler;
|
||||
this.timeout = timeout;
|
||||
this.quarantine = new ConcurrentHashMap<>(maxConnections);
|
||||
|
@ -90,17 +90,12 @@ public class ValidatingConnectionPool extends DuplexConnectionPool
|
|||
public boolean remove(Connection connection)
|
||||
{
|
||||
Holder holder = quarantine.remove(connection);
|
||||
|
||||
if (holder == null)
|
||||
return super.remove(connection);
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Removed while validating {}", connection);
|
||||
|
||||
boolean cancelled = holder.cancel();
|
||||
if (cancelled)
|
||||
return remove(connection, true);
|
||||
|
||||
if (holder != null)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Removed while validating {}", connection);
|
||||
holder.cancel();
|
||||
}
|
||||
return super.remove(connection);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@ import org.eclipse.jetty.client.HttpClientTransport;
|
|||
import org.eclipse.jetty.client.HttpDestination;
|
||||
import org.eclipse.jetty.client.HttpRequest;
|
||||
import org.eclipse.jetty.client.MultiplexConnectionPool;
|
||||
import org.eclipse.jetty.client.MultiplexHttpDestination;
|
||||
import org.eclipse.jetty.client.Origin;
|
||||
import org.eclipse.jetty.client.http.HttpClientConnectionFactory;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
|
@ -179,7 +178,7 @@ public class HttpClientTransportDynamic extends AbstractConnectorHttpClientTrans
|
|||
public HttpDestination newHttpDestination(Origin origin)
|
||||
{
|
||||
SocketAddress address = origin.getAddress().getSocketAddress();
|
||||
return new MultiplexHttpDestination(getHttpClient(), origin, getClientConnector().isIntrinsicallySecure(address));
|
||||
return new HttpDestination(getHttpClient(), origin, getClientConnector().isIntrinsicallySecure(address));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,7 +20,6 @@ import java.util.Map;
|
|||
|
||||
import org.eclipse.jetty.client.AbstractConnectorHttpClientTransport;
|
||||
import org.eclipse.jetty.client.DuplexConnectionPool;
|
||||
import org.eclipse.jetty.client.DuplexHttpDestination;
|
||||
import org.eclipse.jetty.client.HttpDestination;
|
||||
import org.eclipse.jetty.client.HttpRequest;
|
||||
import org.eclipse.jetty.client.Origin;
|
||||
|
@ -70,7 +69,7 @@ public class HttpClientTransportOverHTTP extends AbstractConnectorHttpClientTran
|
|||
public HttpDestination newHttpDestination(Origin origin)
|
||||
{
|
||||
SocketAddress address = origin.getAddress().getSocketAddress();
|
||||
return new DuplexHttpDestination(getHttpClient(), origin, getClientConnector().isIntrinsicallySecure(address));
|
||||
return new HttpDestination(getHttpClient(), origin, getClientConnector().isIntrinsicallySecure(address));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.io.Content;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.Response;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
|
||||
public class ConnectionPoolMaxUsageTest
|
||||
{
|
||||
private Server server;
|
||||
private ServerConnector connector;
|
||||
private HttpClient httpClient;
|
||||
|
||||
public void start(Handler handler) throws Exception
|
||||
{
|
||||
server = new Server();
|
||||
connector = new ServerConnector(server, 1, 1);
|
||||
server.addConnector(connector);
|
||||
server.setHandler(handler);
|
||||
server.start();
|
||||
|
||||
httpClient = new HttpClient();
|
||||
httpClient.start();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void dispose()
|
||||
{
|
||||
LifeCycle.stop(httpClient);
|
||||
LifeCycle.stop(server);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxUsage() throws Exception
|
||||
{
|
||||
start(new Handler.Processor()
|
||||
{
|
||||
@Override
|
||||
public void process(Request request, Response response, Callback callback)
|
||||
{
|
||||
response.getHeaders().put(HttpHeader.CONTENT_TYPE, "text/plain");
|
||||
Content.Sink.write(response, true, String.valueOf(Request.getRemotePort(request)), callback);
|
||||
}
|
||||
});
|
||||
|
||||
String host = "localhost";
|
||||
int port = connector.getLocalPort();
|
||||
HttpDestination destination = httpClient.resolveDestination(new Origin("http", host, port, null, HttpClientTransportOverHTTP.HTTP11));
|
||||
AbstractConnectionPool connectionPool = (AbstractConnectionPool)destination.getConnectionPool();
|
||||
int maxUsage = 3;
|
||||
connectionPool.setMaxUsage(maxUsage);
|
||||
|
||||
Set<String> clientPorts = new HashSet<>();
|
||||
for (int i = 0; i < maxUsage; ++i)
|
||||
{
|
||||
ContentResponse response = httpClient.newRequest(host, port)
|
||||
.timeout(5, TimeUnit.SECONDS)
|
||||
.send();
|
||||
assertEquals(HttpStatus.OK_200, response.getStatus());
|
||||
int expected = i == maxUsage - 1 ? 0 : 1;
|
||||
assertEquals(expected, connectionPool.getConnectionCount());
|
||||
clientPorts.add(response.getContentAsString());
|
||||
}
|
||||
assertEquals(1, clientPorts.size());
|
||||
|
||||
// Make one more request, it must open a new connection.
|
||||
ContentResponse response = httpClient.newRequest(host, port)
|
||||
.timeout(5, TimeUnit.SECONDS)
|
||||
.send();
|
||||
assertEquals(HttpStatus.OK_200, response.getStatus());
|
||||
assertEquals(1, connectionPool.getConnectionCount());
|
||||
assertNotEquals(clientPorts.iterator().next(), response.getContentAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxUsageSetToSmallerValue() throws Exception
|
||||
{
|
||||
start(new Handler.Processor()
|
||||
{
|
||||
@Override
|
||||
public void process(Request request, Response response, Callback callback)
|
||||
{
|
||||
response.getHeaders().put(HttpHeader.CONTENT_TYPE, "text/plain");
|
||||
Content.Sink.write(response, true, String.valueOf(Request.getRemotePort(request)), callback);
|
||||
}
|
||||
});
|
||||
|
||||
String host = "localhost";
|
||||
int port = connector.getLocalPort();
|
||||
HttpDestination destination = httpClient.resolveDestination(new Origin("http", host, port, null, HttpClientTransportOverHTTP.HTTP11));
|
||||
AbstractConnectionPool connectionPool = (AbstractConnectionPool)destination.getConnectionPool();
|
||||
int maxUsage = 3;
|
||||
connectionPool.setMaxUsage(maxUsage);
|
||||
|
||||
// Make a number of requests smaller than maxUsage.
|
||||
Set<String> clientPorts = new HashSet<>();
|
||||
for (int i = 0; i < maxUsage - 1; ++i)
|
||||
{
|
||||
ContentResponse response = httpClient.newRequest(host, port)
|
||||
.timeout(5, TimeUnit.SECONDS)
|
||||
.send();
|
||||
assertEquals(HttpStatus.OK_200, response.getStatus());
|
||||
assertEquals(1, connectionPool.getConnectionCount());
|
||||
clientPorts.add(response.getContentAsString());
|
||||
}
|
||||
assertEquals(1, clientPorts.size());
|
||||
|
||||
// Set maxUsage to a smaller value.
|
||||
connectionPool.setMaxUsage(1);
|
||||
|
||||
// Make one more request, it must open a new connection.
|
||||
ContentResponse response = httpClient.newRequest(host, port)
|
||||
.timeout(5, TimeUnit.SECONDS)
|
||||
.send();
|
||||
assertEquals(HttpStatus.OK_200, response.getStatus());
|
||||
assertEquals(0, connectionPool.getConnectionCount());
|
||||
assertNotEquals(clientPorts.iterator().next(), response.getContentAsString());
|
||||
}
|
||||
}
|
|
@ -585,11 +585,11 @@ public class ConnectionPoolTest
|
|||
{
|
||||
startServer(new EmptyServerHandler());
|
||||
|
||||
int maxUsageCount = 2;
|
||||
int maxUsage = 2;
|
||||
startClient(destination ->
|
||||
{
|
||||
AbstractConnectionPool connectionPool = (AbstractConnectionPool)factory.factory.newConnectionPool(destination);
|
||||
connectionPool.setMaxUsageCount(maxUsageCount);
|
||||
connectionPool.setMaxUsage(maxUsage);
|
||||
connectionPool.setMaxDuration(0); // Disable max duration expiry as it may expire the connection between the 1st and 2nd request.
|
||||
return connectionPool;
|
||||
});
|
||||
|
|
|
@ -46,7 +46,7 @@ public class DuplexHttpDestinationTest extends AbstractHttpClientServerTest
|
|||
{
|
||||
start(scenario, new EmptyServerHandler());
|
||||
|
||||
try (HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", connector.getLocalPort())))
|
||||
try (HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", connector.getLocalPort()), false))
|
||||
{
|
||||
destination.start();
|
||||
DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool();
|
||||
|
@ -66,7 +66,7 @@ public class DuplexHttpDestinationTest extends AbstractHttpClientServerTest
|
|||
{
|
||||
start(scenario, new EmptyServerHandler());
|
||||
|
||||
try (HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", connector.getLocalPort())))
|
||||
try (HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", connector.getLocalPort()), false))
|
||||
{
|
||||
destination.start();
|
||||
DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool();
|
||||
|
@ -90,7 +90,7 @@ public class DuplexHttpDestinationTest extends AbstractHttpClientServerTest
|
|||
{
|
||||
start(scenario, new EmptyServerHandler());
|
||||
|
||||
try (HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", connector.getLocalPort())))
|
||||
try (HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", connector.getLocalPort()), false))
|
||||
{
|
||||
destination.start();
|
||||
DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool();
|
||||
|
@ -119,7 +119,7 @@ public class DuplexHttpDestinationTest extends AbstractHttpClientServerTest
|
|||
|
||||
CountDownLatch idleLatch = new CountDownLatch(1);
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
try (HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", connector.getLocalPort()))
|
||||
try (HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", connector.getLocalPort()), false)
|
||||
{
|
||||
@Override
|
||||
protected ConnectionPool newConnectionPool(HttpClient client)
|
||||
|
@ -181,7 +181,7 @@ public class DuplexHttpDestinationTest extends AbstractHttpClientServerTest
|
|||
{
|
||||
start(scenario, new EmptyServerHandler());
|
||||
|
||||
try (HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", connector.getLocalPort())))
|
||||
try (HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", connector.getLocalPort()), false))
|
||||
{
|
||||
destination.start();
|
||||
DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool();
|
||||
|
@ -218,7 +218,7 @@ public class DuplexHttpDestinationTest extends AbstractHttpClientServerTest
|
|||
long idleTimeout = 1000;
|
||||
startClient(scenario, httpClient -> httpClient.setIdleTimeout(idleTimeout));
|
||||
|
||||
try (HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", connector.getLocalPort())))
|
||||
try (HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", connector.getLocalPort()), false))
|
||||
{
|
||||
destination.start();
|
||||
DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool();
|
||||
|
|
|
@ -95,7 +95,7 @@ public class HttpClientIdleTimeoutTest
|
|||
@Override
|
||||
public HttpDestination newHttpDestination(Origin origin)
|
||||
{
|
||||
return new DuplexHttpDestination(getHttpClient(), origin)
|
||||
return new HttpDestination(getHttpClient(), origin, false)
|
||||
{
|
||||
@Override
|
||||
protected SendFailure send(IConnection connection, HttpExchange exchange)
|
||||
|
|
|
@ -21,7 +21,6 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jetty.client.DuplexHttpDestination;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.HttpDestination;
|
||||
import org.eclipse.jetty.client.HttpExchange;
|
||||
|
@ -74,7 +73,7 @@ public class HttpReceiverOverHTTPTest
|
|||
client = new HttpClient();
|
||||
client.setHttpCompliance(compliance);
|
||||
client.start();
|
||||
destination = new DuplexHttpDestination(client, new Origin("http", "localhost", 8080));
|
||||
destination = new HttpDestination(client, new Origin("http", "localhost", 8080), false);
|
||||
destination.start();
|
||||
endPoint = new ByteArrayEndPoint();
|
||||
connection = new HttpConnectionOverHTTP(endPoint, destination, new Promise.Adapter<>());
|
||||
|
|
|
@ -20,7 +20,6 @@ import java.util.Locale;
|
|||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.client.DuplexHttpDestination;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.HttpDestination;
|
||||
import org.eclipse.jetty.client.Origin;
|
||||
|
@ -61,7 +60,7 @@ public class HttpSenderOverHTTPTest
|
|||
public void testSendNoRequestContent() throws Exception
|
||||
{
|
||||
ByteArrayEndPoint endPoint = new ByteArrayEndPoint();
|
||||
HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", 8080));
|
||||
HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", 8080), false);
|
||||
destination.start();
|
||||
HttpConnectionOverHTTP connection = new HttpConnectionOverHTTP(endPoint, destination, new Promise.Adapter<Connection>());
|
||||
Request request = client.newRequest(URI.create("http://localhost/"));
|
||||
|
@ -94,7 +93,7 @@ public class HttpSenderOverHTTPTest
|
|||
public void testSendNoRequestContentIncompleteFlush() throws Exception
|
||||
{
|
||||
ByteArrayEndPoint endPoint = new ByteArrayEndPoint("", 16);
|
||||
HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", 8080));
|
||||
HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", 8080), false);
|
||||
destination.start();
|
||||
HttpConnectionOverHTTP connection = new HttpConnectionOverHTTP(endPoint, destination, new Promise.Adapter<Connection>());
|
||||
Request request = client.newRequest(URI.create("http://localhost/"));
|
||||
|
@ -124,7 +123,7 @@ public class HttpSenderOverHTTPTest
|
|||
ByteArrayEndPoint endPoint = new ByteArrayEndPoint();
|
||||
// Shutdown output to trigger the exception on write
|
||||
endPoint.shutdownOutput();
|
||||
HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", 8080));
|
||||
HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", 8080), false);
|
||||
destination.start();
|
||||
HttpConnectionOverHTTP connection = new HttpConnectionOverHTTP(endPoint, destination, new Promise.Adapter<Connection>());
|
||||
Request request = client.newRequest(URI.create("http://localhost/"));
|
||||
|
@ -154,7 +153,7 @@ public class HttpSenderOverHTTPTest
|
|||
public void testSendNoRequestContentIncompleteFlushException() throws Exception
|
||||
{
|
||||
ByteArrayEndPoint endPoint = new ByteArrayEndPoint("", 16);
|
||||
HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", 8080));
|
||||
HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", 8080), false);
|
||||
destination.start();
|
||||
HttpConnectionOverHTTP connection = new HttpConnectionOverHTTP(endPoint, destination, new Promise.Adapter<Connection>());
|
||||
Request request = client.newRequest(URI.create("http://localhost/"));
|
||||
|
@ -190,7 +189,7 @@ public class HttpSenderOverHTTPTest
|
|||
public void testSendSmallRequestContentInOneBuffer() throws Exception
|
||||
{
|
||||
ByteArrayEndPoint endPoint = new ByteArrayEndPoint();
|
||||
HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", 8080));
|
||||
HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", 8080), false);
|
||||
destination.start();
|
||||
HttpConnectionOverHTTP connection = new HttpConnectionOverHTTP(endPoint, destination, new Promise.Adapter<Connection>());
|
||||
Request request = client.newRequest(URI.create("http://localhost/"));
|
||||
|
@ -225,7 +224,7 @@ public class HttpSenderOverHTTPTest
|
|||
public void testSendSmallRequestContentInTwoBuffers() throws Exception
|
||||
{
|
||||
ByteArrayEndPoint endPoint = new ByteArrayEndPoint();
|
||||
HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", 8080));
|
||||
HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", 8080), false);
|
||||
destination.start();
|
||||
HttpConnectionOverHTTP connection = new HttpConnectionOverHTTP(endPoint, destination, new Promise.Adapter<Connection>());
|
||||
Request request = client.newRequest(URI.create("http://localhost/"));
|
||||
|
@ -261,7 +260,7 @@ public class HttpSenderOverHTTPTest
|
|||
public void testSendSmallRequestContentChunkedInTwoChunks() throws Exception
|
||||
{
|
||||
ByteArrayEndPoint endPoint = new ByteArrayEndPoint();
|
||||
HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", 8080));
|
||||
HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", 8080), false);
|
||||
destination.start();
|
||||
HttpConnectionOverHTTP connection = new HttpConnectionOverHTTP(endPoint, destination, new Promise.Adapter<Connection>());
|
||||
Request request = client.newRequest(URI.create("http://localhost/"));
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
|
||||
|
||||
<!-- ==================================================================
|
||||
Configure and deploy the test web application
|
||||
===================================================================== -->
|
||||
|
||||
<Configure id="coreDemo" class="org.eclipse.jetty.server.handler.ContextHandler">
|
||||
<Set name="handler">
|
||||
<New class="org.eclipse.jetty.core.demo.HandlerDocs$RootHandler">
|
||||
<Call name="addHandler"><Arg><New class="org.eclipse.jetty.core.demo.HandlerDocs$HelloHandler0"/></Arg></Call>
|
||||
<Call name="addHandler"><Arg><New class="org.eclipse.jetty.core.demo.HandlerDocs$HelloHandler1"/></Arg></Call>
|
||||
<Call name="addHandler"><Arg><New class="org.eclipse.jetty.core.demo.HandlerDocs$HelloHandler2"/></Arg></Call>
|
||||
<Call name="addHandler"><Arg><New class="org.eclipse.jetty.core.demo.HandlerDocs$HelloHandler3"/></Arg></Call>
|
||||
<Call name="addHandler"><Arg><New class="org.eclipse.jetty.core.demo.HandlerDocs$HelloHandler4"/></Arg></Call>
|
||||
<Call name="addHandler"><Arg><New class="org.eclipse.jetty.core.demo.HandlerDocs$HelloHandler5"/></Arg></Call>
|
||||
<Call name="addHandler"><Arg><New class="org.eclipse.jetty.core.demo.HandlerDocs$EchoHandler"/></Arg></Call>
|
||||
</New>
|
||||
</Set>
|
||||
</Configure>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
|
||||
|
||||
<Configure id="helloDemo" class="org.eclipse.jetty.server.handler.ContextHandler">
|
||||
<Set name="handler">
|
||||
<New class="org.eclipse.jetty.demo.HelloHandler" />
|
||||
</Set>
|
||||
</Configure>
|
|
@ -1,208 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.core.demo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.Flow;
|
||||
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.MimeTypes;
|
||||
import org.eclipse.jetty.io.Content;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.Response;
|
||||
import org.eclipse.jetty.util.Blocker;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.thread.SerializedInvoker;
|
||||
|
||||
public class HandlerDocs
|
||||
{
|
||||
public static class HelloHandler0 extends Handler.Abstract
|
||||
{
|
||||
@Override
|
||||
public Request.Processor handle(Request request) throws Exception
|
||||
{
|
||||
return (req, response, callback) ->
|
||||
{
|
||||
response.setStatus(200);
|
||||
response.getHeaders().add(HttpHeader.CONTENT_TYPE, "text/plain");
|
||||
response.write(true, BufferUtil.toBuffer("Hello World\n"), callback);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static class HelloHandler1 extends Handler.Abstract
|
||||
{
|
||||
@Override
|
||||
public Request.Processor handle(Request request) throws Exception
|
||||
{
|
||||
return this::process;
|
||||
}
|
||||
|
||||
private void process(Request request, Response response, Callback callback)
|
||||
{
|
||||
response.setStatus(200);
|
||||
response.getHeaders().add(HttpHeader.CONTENT_TYPE, "text/plain");
|
||||
Content.Sink.write(response, true, "Hello World", callback);
|
||||
}
|
||||
}
|
||||
|
||||
public static class HelloHandler2 extends Handler.Processor.NonBlocking
|
||||
{
|
||||
@Override
|
||||
public void process(Request request, Response response, Callback callback)
|
||||
{
|
||||
response.setStatus(200);
|
||||
response.getHeaders().add(HttpHeader.CONTENT_TYPE, "text/plain");
|
||||
response.write(true, BufferUtil.toBuffer("Hello World\n"), callback);
|
||||
}
|
||||
}
|
||||
|
||||
public static class HelloHandler3 extends Handler.Processor.Blocking
|
||||
{
|
||||
@Override
|
||||
public void process(Request request, Response response, Callback callback) throws IOException
|
||||
{
|
||||
response.setStatus(200);
|
||||
response.getHeaders().add(HttpHeader.CONTENT_TYPE, "text/plain");
|
||||
|
||||
try (Blocker.Callback blocker = Blocker.callback())
|
||||
{
|
||||
response.write(false, BufferUtil.toBuffer("Hello "), blocker);
|
||||
blocker.block();
|
||||
}
|
||||
|
||||
Content.Sink.write(response, true, BufferUtil.toBuffer("World\n"));
|
||||
|
||||
callback.succeeded();
|
||||
}
|
||||
}
|
||||
|
||||
public static class HelloHandler4 extends Handler.Processor.Blocking
|
||||
{
|
||||
@Override
|
||||
public void process(Request request, Response response, Callback callback) throws IOException
|
||||
{
|
||||
response.setStatus(200);
|
||||
response.getHeaders().add(HttpHeader.CONTENT_TYPE, "text/plain");
|
||||
try (PrintStream out = new PrintStream(Content.Sink.asOutputStream(response)))
|
||||
{
|
||||
out.print("Hello ");
|
||||
out.println("World");
|
||||
callback.succeeded();
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
callback.failed(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class HelloHandler5 extends Handler.Processor.NonBlocking
|
||||
{
|
||||
@Override
|
||||
public void process(Request request, Response response, Callback callback) throws IOException
|
||||
{
|
||||
response.setStatus(200);
|
||||
response.getHeaders().add(HttpHeader.CONTENT_TYPE, "text/plain");
|
||||
new HelloWorldPublisher().subscribe(Content.Sink.asSubscriber(response, callback));
|
||||
}
|
||||
}
|
||||
|
||||
public static class HelloWorldPublisher implements Flow.Publisher<Content.Chunk>
|
||||
{
|
||||
@Override
|
||||
public void subscribe(Flow.Subscriber<? super Content.Chunk> subscriber)
|
||||
{
|
||||
final SerializedInvoker invoker = new SerializedInvoker();
|
||||
final Queue<Content.Chunk> chunks = new LinkedList<>(List.of(
|
||||
Content.Chunk.from(BufferUtil.toBuffer("Hello "), false),
|
||||
Content.Chunk.from(BufferUtil.toBuffer("World "), false),
|
||||
Content.Chunk.EOF));
|
||||
|
||||
subscriber.onSubscribe(new Flow.Subscription()
|
||||
{
|
||||
@Override
|
||||
public void request(long n)
|
||||
{
|
||||
while (n-- > 0 && !chunks.isEmpty())
|
||||
invoker.run(() -> subscriber.onNext(chunks.poll()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel()
|
||||
{
|
||||
subscriber.onNext(Content.Chunk.from(new IOException("Cancelled")));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static class EchoHandler extends Handler.Processor.NonBlocking
|
||||
{
|
||||
@Override
|
||||
public void process(Request request, Response response, Callback callback)
|
||||
{
|
||||
response.setStatus(200);
|
||||
response.getHeaders().put(HttpHeader.CONTENT_TYPE, request.getHeaders().get(HttpHeader.CONTENT_TYPE));
|
||||
|
||||
long contentLength = request.getHeaders().getLongField(HttpHeader.CONTENT_LENGTH);
|
||||
if (contentLength >= 0)
|
||||
response.getHeaders().putLongField(HttpHeader.CONTENT_LENGTH, contentLength);
|
||||
|
||||
Content.copy(request, response, callback);
|
||||
}
|
||||
}
|
||||
|
||||
public static class RootHandler extends Handler.Collection
|
||||
{
|
||||
@Override
|
||||
public Request.Processor handle(Request request) throws Exception
|
||||
{
|
||||
final StringBuilder index = new StringBuilder();
|
||||
index.append("<h2>Handler Demos</h2>\n<ul>\n");
|
||||
|
||||
for (Handler handler : getHandlers())
|
||||
{
|
||||
String name = handler.getClass().getSimpleName().replace("Handler", "");
|
||||
String path = "/" + name;
|
||||
if (request.getPathInContext().equals(path))
|
||||
{
|
||||
Request.Processor processor = handler.handle(request);
|
||||
if (processor != null)
|
||||
return processor;
|
||||
}
|
||||
index.append("<li><a href=\"")
|
||||
.append(URIUtil.addPaths(request.getContext().getContextPath(), path))
|
||||
.append("\">")
|
||||
.append(name)
|
||||
.append("</a></li>\n");
|
||||
}
|
||||
|
||||
index.append("</ul>");
|
||||
return (req, res, callback) ->
|
||||
{
|
||||
res.setStatus(200);
|
||||
res.getHeaders().add(HttpHeader.CONTENT_TYPE, MimeTypes.Type.TEXT_HTML_UTF_8.asString());
|
||||
Content.Sink.write(res, true, index.toString(), callback);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,22 +11,23 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
package org.eclipse.jetty.demo;
|
||||
|
||||
/**
|
||||
* <p>A destination for those network transports that are duplex (e.g. HTTP/1.1 and FastCGI).</p>
|
||||
*
|
||||
* @see MultiplexHttpDestination
|
||||
*/
|
||||
public class DuplexHttpDestination extends HttpDestination
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
|
||||
public class HelloHandler extends Handler.Abstract
|
||||
{
|
||||
public DuplexHttpDestination(HttpClient client, Origin origin)
|
||||
@Override
|
||||
public Request.Processor handle(Request req)
|
||||
{
|
||||
this(client, origin, false);
|
||||
}
|
||||
|
||||
public DuplexHttpDestination(HttpClient client, Origin origin, boolean intrinsicallySecure)
|
||||
{
|
||||
super(client, origin, intrinsicallySecure);
|
||||
return (request, response, callback) ->
|
||||
{
|
||||
response.setStatus(200);
|
||||
response.getHeaders().add(HttpHeader.CONTENT_TYPE, "text/plain");
|
||||
response.write(true, BufferUtil.toBuffer("Hello World\n"), callback);
|
||||
};
|
||||
}
|
||||
}
|
|
@ -2,12 +2,12 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi</artifactId>
|
||||
<artifactId>jetty-fcgi</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>fcgi-client</artifactId>
|
||||
<artifactId>jetty-fcgi-client</artifactId>
|
||||
<name>Jetty Core :: FastCGI :: Client</name>
|
||||
|
||||
<properties>
|
|
@ -13,12 +13,12 @@
|
|||
|
||||
package org.eclipse.jetty.fcgi.client.http;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jetty.client.AbstractConnectorHttpClientTransport;
|
||||
import org.eclipse.jetty.client.DuplexConnectionPool;
|
||||
import org.eclipse.jetty.client.DuplexHttpDestination;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.HttpDestination;
|
||||
import org.eclipse.jetty.client.HttpRequest;
|
||||
|
@ -81,7 +81,8 @@ public class HttpClientTransportOverFCGI extends AbstractConnectorHttpClientTran
|
|||
@Override
|
||||
public HttpDestination newHttpDestination(Origin origin)
|
||||
{
|
||||
return new DuplexHttpDestination(getHttpClient(), origin);
|
||||
SocketAddress address = origin.getAddress().getSocketAddress();
|
||||
return new HttpDestination(getHttpClient(), origin, getClientConnector().isIntrinsicallySecure(address));
|
||||
}
|
||||
|
||||
@Override
|
|
@ -2,12 +2,12 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi</artifactId>
|
||||
<artifactId>jetty-fcgi</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>fcgi-server</artifactId>
|
||||
<artifactId>jetty-fcgi-server</artifactId>
|
||||
<name>Jetty Core :: FastCGI :: Server</name>
|
||||
|
||||
<properties>
|
||||
|
@ -26,7 +26,7 @@
|
|||
</dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi-client</artifactId>
|
||||
<artifactId>jetty-fcgi-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
|
@ -39,7 +39,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-server</artifactId>
|
||||
<artifactId>jetty-http2-server</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
|
@ -8,13 +8,13 @@
|
|||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi</artifactId>
|
||||
<artifactId>jetty-fcgi</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>Jetty Core :: FastCGI :: Parent</name>
|
||||
<name>Jetty Core :: FastCGI</name>
|
||||
|
||||
<modules>
|
||||
<module>fcgi-client</module>
|
||||
<module>fcgi-server</module>
|
||||
<module>jetty-fcgi-client</module>
|
||||
<module>jetty-fcgi-server</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
|
|
|
@ -18,12 +18,13 @@ import java.util.concurrent.ExecutorService;
|
|||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.util.VirtualThreads;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.eclipse.jetty.util.thread.ThreadPool;
|
||||
import org.eclipse.jetty.util.thread.TryExecutor;
|
||||
|
||||
public class DelegatingThreadPool extends ContainerLifeCycle implements ThreadPool, TryExecutor
|
||||
public class DelegatingThreadPool extends ContainerLifeCycle implements ThreadPool, TryExecutor, VirtualThreads.Configurable
|
||||
{
|
||||
private Executor _executor; // memory barrier provided by start/stop semantics
|
||||
private TryExecutor _tryExecutor;
|
||||
|
@ -61,6 +62,19 @@ public class DelegatingThreadPool extends ContainerLifeCycle implements ThreadPo
|
|||
return _tryExecutor.tryExecute(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseVirtualThreads()
|
||||
{
|
||||
return VirtualThreads.isUseVirtualThreads(_executor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUseVirtualThreads(boolean useVirtualThreads)
|
||||
{
|
||||
if (_executor instanceof VirtualThreads.Configurable)
|
||||
((VirtualThreads.Configurable)_executor).setUseVirtualThreads(useVirtualThreads);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIdleThreads()
|
||||
{
|
||||
|
|
|
@ -13,8 +13,12 @@
|
|||
|
||||
package org.eclipse.jetty.http;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.util.Attributes;
|
||||
|
@ -76,7 +80,7 @@ public class HttpCookie
|
|||
private final int _version;
|
||||
private final boolean _httpOnly;
|
||||
private final long _expiration;
|
||||
private final SameSite _sameSite;
|
||||
private final Map<String, String> _attributes;
|
||||
|
||||
public HttpCookie(String name, String value)
|
||||
{
|
||||
|
@ -100,10 +104,16 @@ public class HttpCookie
|
|||
|
||||
public HttpCookie(String name, String value, String domain, String path, long maxAge, boolean httpOnly, boolean secure, String comment, int version)
|
||||
{
|
||||
this(name, value, domain, path, maxAge, httpOnly, secure, comment, version, null);
|
||||
this(name, value, domain, path, maxAge, httpOnly, secure, comment, version, (SameSite)null);
|
||||
}
|
||||
|
||||
public HttpCookie(String name, String value, String domain, String path, long maxAge, boolean httpOnly, boolean secure, String comment, int version, SameSite sameSite)
|
||||
{
|
||||
|
||||
this(name, value, domain, path, maxAge, httpOnly, secure, comment, version, Collections.singletonMap("SameSite", sameSite == null ? null : sameSite.getAttributeValue()));
|
||||
}
|
||||
|
||||
public HttpCookie(String name, String value, String domain, String path, long maxAge, boolean httpOnly, boolean secure, String comment, int version, Map<String, String> attributes)
|
||||
{
|
||||
_name = name;
|
||||
_value = value;
|
||||
|
@ -115,29 +125,26 @@ public class HttpCookie
|
|||
_comment = comment;
|
||||
_version = version;
|
||||
_expiration = maxAge < 0 ? -1 : System.nanoTime() + TimeUnit.SECONDS.toNanos(maxAge);
|
||||
_sameSite = sameSite;
|
||||
_attributes = (attributes == null ? Collections.emptyMap() : attributes);
|
||||
}
|
||||
|
||||
public HttpCookie(String setCookie)
|
||||
|
||||
public HttpCookie(String name, String value, int version, Map<String, String> attributes)
|
||||
{
|
||||
List<java.net.HttpCookie> cookies = java.net.HttpCookie.parse(setCookie);
|
||||
if (cookies.size() != 1)
|
||||
throw new IllegalStateException();
|
||||
_name = name;
|
||||
_value = value;
|
||||
_version = version;
|
||||
_attributes = (attributes == null ? Collections.emptyMap() : new TreeMap<>(attributes));
|
||||
|
||||
//remove all of the well-known attributes, leaving only those pass-through ones
|
||||
_domain = _attributes.remove("Domain");
|
||||
_path = _attributes.remove("Path");
|
||||
|
||||
java.net.HttpCookie cookie = cookies.get(0);
|
||||
|
||||
_name = cookie.getName();
|
||||
_value = cookie.getValue();
|
||||
_domain = cookie.getDomain();
|
||||
_path = cookie.getPath();
|
||||
_maxAge = cookie.getMaxAge();
|
||||
_httpOnly = cookie.isHttpOnly();
|
||||
_secure = cookie.getSecure();
|
||||
_comment = cookie.getComment();
|
||||
_version = cookie.getVersion();
|
||||
String tmp = _attributes.remove("Max-Age");
|
||||
_maxAge = StringUtil.isBlank(tmp) ? -1L : Long.valueOf(tmp);
|
||||
_expiration = _maxAge < 0 ? -1 : System.nanoTime() + TimeUnit.SECONDS.toNanos(_maxAge);
|
||||
// support for SameSite values has not yet been added to java.net.HttpCookie
|
||||
_sameSite = getSameSiteFromComment(cookie.getComment());
|
||||
_httpOnly = Boolean.parseBoolean(_attributes.remove("HttpOnly"));
|
||||
_secure = Boolean.parseBoolean(_attributes.remove("Secure"));
|
||||
_comment = _attributes.remove("Comment");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -209,7 +216,10 @@ public class HttpCookie
|
|||
*/
|
||||
public SameSite getSameSite()
|
||||
{
|
||||
return _sameSite;
|
||||
String val = _attributes.get("SameSite");
|
||||
if (val == null)
|
||||
return null;
|
||||
return SameSite.valueOf(val.toUpperCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -421,12 +431,21 @@ public class HttpCookie
|
|||
buf.append("; Secure");
|
||||
if (_httpOnly)
|
||||
buf.append("; HttpOnly");
|
||||
if (_sameSite != null)
|
||||
|
||||
String sameSite = _attributes.get("SameSite");
|
||||
if (sameSite != null)
|
||||
{
|
||||
buf.append("; SameSite=");
|
||||
buf.append(_sameSite.getAttributeValue());
|
||||
buf.append(sameSite);
|
||||
}
|
||||
|
||||
//Add all other attributes
|
||||
_attributes.entrySet().stream().filter(e -> !"SameSite".equals(e.getKey())).forEach(e ->
|
||||
{
|
||||
buf.append("; " + e.getKey() + "=");
|
||||
buf.append(e.getValue());
|
||||
});
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
|
@ -491,6 +510,109 @@ public class HttpCookie
|
|||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the bare minimum of info from a Set-Cookie header string.
|
||||
*
|
||||
* Ideally this method should not be necessary, however as java.net.HttpCookie
|
||||
* does not yet support generic attributes, we have to use it in a minimal
|
||||
* fashion. When it supports attributes, we could look at reverting to a
|
||||
* constructor on o.e.j.h.HttpCookie to take the set-cookie header string.
|
||||
*
|
||||
* @param setCookieHeader the header as a string
|
||||
* @return a map containing the name, value, domain, path. max-age of the set cookie header
|
||||
*/
|
||||
public static Map<String, String> extractBasics(String setCookieHeader)
|
||||
{
|
||||
//Parse the bare minimum
|
||||
List<java.net.HttpCookie> cookies = java.net.HttpCookie.parse(setCookieHeader);
|
||||
if (cookies.size() != 1)
|
||||
return Collections.emptyMap();
|
||||
java.net.HttpCookie cookie = cookies.get(0);
|
||||
Map<String, String> fields = new HashMap<>();
|
||||
fields.put("name", cookie.getName());
|
||||
fields.put("value", cookie.getValue());
|
||||
fields.put("domain", cookie.getDomain());
|
||||
fields.put("path", cookie.getPath());
|
||||
fields.put("max-age", Long.toString(cookie.getMaxAge()));
|
||||
return fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the Set-Cookie header represented as a string is for the name, domain and path given.
|
||||
*
|
||||
* @param setCookieHeader a Set-Cookie header
|
||||
* @param name the cookie name to check
|
||||
* @param domain the cookie domain to check
|
||||
* @param path the cookie path to check
|
||||
* @return true if all of the name, domain and path match the Set-Cookie header, false otherwise
|
||||
*/
|
||||
public static boolean match(String setCookieHeader, String name, String domain, String path)
|
||||
{
|
||||
//Parse the bare minimum
|
||||
List<java.net.HttpCookie> cookies = java.net.HttpCookie.parse(setCookieHeader);
|
||||
if (cookies.size() != 1)
|
||||
return false;
|
||||
|
||||
java.net.HttpCookie cookie = cookies.get(0);
|
||||
return match(cookie.getName(), cookie.getDomain(), cookie.getPath(), name, domain, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the HttpCookie is for the given name, domain and path.
|
||||
*
|
||||
* @param cookie the jetty HttpCookie to check
|
||||
* @param name the cookie name to check
|
||||
* @param domain the cookie domain to check
|
||||
* @param path the cookie path to check
|
||||
* @return true if all of the name, domain and path all match the HttpCookie, false otherwise
|
||||
*/
|
||||
public static boolean match(HttpCookie cookie, String name, String domain, String path)
|
||||
{
|
||||
if (cookie == null)
|
||||
return false;
|
||||
return match(cookie.getName(), cookie.getDomain(), cookie.getPath(), name, domain, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if all old parameters match the new parameters.
|
||||
*
|
||||
* @param oldName
|
||||
* @param oldDomain
|
||||
* @param oldPath
|
||||
* @param newName
|
||||
* @param newDomain
|
||||
* @param newPath
|
||||
* @return true if old and new names match exactly and the old and new domains match case-insensitively and the paths match exactly
|
||||
*/
|
||||
private static boolean match(String oldName, String oldDomain, String oldPath, String newName, String newDomain, String newPath)
|
||||
{
|
||||
if (oldName == null)
|
||||
{
|
||||
if (newName != null)
|
||||
return false;
|
||||
}
|
||||
else if (!oldName.equals(newName))
|
||||
return false;
|
||||
|
||||
if (oldDomain == null)
|
||||
{
|
||||
if (newDomain != null)
|
||||
return false;
|
||||
}
|
||||
else if (!oldDomain.equalsIgnoreCase(newDomain))
|
||||
return false;
|
||||
|
||||
if (oldPath == null)
|
||||
{
|
||||
if (newPath != null)
|
||||
return false;
|
||||
}
|
||||
else if (!oldPath.equals(newPath))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated We should not need to do this now
|
||||
|
@ -563,7 +685,7 @@ public class HttpCookie
|
|||
return _cookie;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check that samesite is set on the cookie. If not, use a
|
||||
* context default value, if one has been set.
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
package org.eclipse.jetty.http;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jetty.http.HttpCookie.SameSite;
|
||||
|
@ -64,9 +65,28 @@ public class HttpCookieTest
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testConstructFromSetCookie()
|
||||
public void testMatchCookie()
|
||||
{
|
||||
HttpCookie cookie = new HttpCookie("everything=value; Path=path; Domain=domain; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Secure; HttpOnly");
|
||||
//match with header string
|
||||
assertTrue(HttpCookie.match("everything=value; Path=path; Domain=domain; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Secure; HttpOnly; SameSite=Lax; Foo=Bar",
|
||||
"everything", "domain", "path"));
|
||||
assertFalse(HttpCookie.match("everything=value; Path=path; Domain=domain; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Secure; HttpOnly; SameSite=Lax; Foo=Bar",
|
||||
"something", "domain", "path"));
|
||||
assertFalse(HttpCookie.match("everything=value; Path=path; Domain=domain; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Secure; HttpOnly; SameSite=Lax; Foo=Bar",
|
||||
"everything", "realm", "path"));
|
||||
assertFalse(HttpCookie.match("everything=value; Path=path; Domain=domain; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Secure; HttpOnly; SameSite=Lax; Foo=Bar",
|
||||
"everything", "domain", "street"));
|
||||
|
||||
//match including set-cookie:, this is really testing the java.net.HttpCookie parser, but worth throwing in there
|
||||
assertTrue(HttpCookie.match("Set-Cookie: everything=value; Path=path; Domain=domain; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Secure; HttpOnly; SameSite=Lax; Foo=Bar",
|
||||
"everything", "domain", "path"));
|
||||
|
||||
//match via cookie
|
||||
HttpCookie httpCookie = new HttpCookie("everything", "value", "domain", "path", 0, true, true, "comment", 0);
|
||||
assertTrue(HttpCookie.match(httpCookie, "everything", "domain", "path"));
|
||||
assertFalse(HttpCookie.match(httpCookie, "something", "domain", "path"));
|
||||
assertFalse(HttpCookie.match(httpCookie, "everything", "realm", "path"));
|
||||
assertFalse(HttpCookie.match(httpCookie, "everything", "domain", "street"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -131,6 +151,9 @@ public class HttpCookieTest
|
|||
|
||||
httpCookie = new HttpCookie("everything", "value", "domain", "path", 0, true, true, null, -1, HttpCookie.SameSite.STRICT);
|
||||
assertEquals("everything=value; Path=path; Domain=domain; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Secure; HttpOnly; SameSite=Strict", httpCookie.getRFC6265SetCookie());
|
||||
|
||||
httpCookie = new HttpCookie("everything", "value", "domain", "path", 0, true, true, null, -1, Collections.singletonMap("SameSite", "None"));
|
||||
assertEquals("everything=value; Path=path; Domain=domain; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Secure; HttpOnly; SameSite=None", httpCookie.getRFC6265SetCookie());
|
||||
}
|
||||
|
||||
public static Stream<String> rfc6265BadNameSource()
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2</artifactId>
|
||||
<artifactId>jetty-http2</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>http2-http-client-transport</artifactId>
|
||||
<name>Jetty Core :: HTTP2 :: HTTP Client Transport</name>
|
||||
<artifactId>jetty-http2-client-transport</artifactId>
|
||||
<name>Jetty Core :: HTTP2 :: Client Transport</name>
|
||||
|
||||
<properties>
|
||||
<bundle-symbolic-name>${project.groupId}.client.http</bundle-symbolic-name>
|
||||
|
@ -21,7 +21,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-client</artifactId>
|
||||
<artifactId>jetty-http2-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
|
@ -19,5 +19,5 @@ module org.eclipse.jetty.http2.http.client.transport
|
|||
requires transitive org.eclipse.jetty.client;
|
||||
requires transitive org.eclipse.jetty.http2.client;
|
||||
|
||||
exports org.eclipse.jetty.http2.client.http;
|
||||
exports org.eclipse.jetty.http2.client.transport;
|
||||
}
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.http2.client.http;
|
||||
package org.eclipse.jetty.http2.client.transport;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
|
@ -25,8 +25,8 @@ import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic;
|
|||
import org.eclipse.jetty.client.http.HttpClientConnectionFactory;
|
||||
import org.eclipse.jetty.http2.client.HTTP2Client;
|
||||
import org.eclipse.jetty.http2.client.HTTP2ClientConnectionFactory;
|
||||
import org.eclipse.jetty.http2.client.http.internal.HTTPSessionListenerPromise;
|
||||
import org.eclipse.jetty.http2.client.http.internal.HttpConnectionOverHTTP2;
|
||||
import org.eclipse.jetty.http2.client.transport.internal.HTTPSessionListenerPromise;
|
||||
import org.eclipse.jetty.http2.client.transport.internal.HttpConnectionOverHTTP2;
|
||||
import org.eclipse.jetty.io.ClientConnectionFactory;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.io.ssl.SslClientConnectionFactory;
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.http2.client.http;
|
||||
package org.eclipse.jetty.http2.client.transport;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
|
@ -26,15 +26,14 @@ import org.eclipse.jetty.client.HttpConnection;
|
|||
import org.eclipse.jetty.client.HttpDestination;
|
||||
import org.eclipse.jetty.client.HttpRequest;
|
||||
import org.eclipse.jetty.client.MultiplexConnectionPool;
|
||||
import org.eclipse.jetty.client.MultiplexHttpDestination;
|
||||
import org.eclipse.jetty.client.Origin;
|
||||
import org.eclipse.jetty.client.ProxyConfiguration;
|
||||
import org.eclipse.jetty.http.HttpScheme;
|
||||
import org.eclipse.jetty.http2.api.Session;
|
||||
import org.eclipse.jetty.http2.client.HTTP2Client;
|
||||
import org.eclipse.jetty.http2.client.HTTP2ClientConnectionFactory;
|
||||
import org.eclipse.jetty.http2.client.http.internal.HTTPSessionListenerPromise;
|
||||
import org.eclipse.jetty.http2.client.http.internal.HttpConnectionOverHTTP2;
|
||||
import org.eclipse.jetty.http2.client.transport.internal.HTTPSessionListenerPromise;
|
||||
import org.eclipse.jetty.http2.client.transport.internal.HttpConnectionOverHTTP2;
|
||||
import org.eclipse.jetty.http2.frames.GoAwayFrame;
|
||||
import org.eclipse.jetty.io.ClientConnectionFactory;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
|
@ -56,7 +55,7 @@ public class HttpClientTransportOverHTTP2 extends AbstractHttpClientTransport
|
|||
setConnectionPoolFactory(destination ->
|
||||
{
|
||||
HttpClient httpClient = getHttpClient();
|
||||
return new MultiplexConnectionPool(destination, httpClient.getMaxConnectionsPerDestination(), destination, httpClient.getMaxRequestsQueuedPerDestination());
|
||||
return new MultiplexConnectionPool(destination, httpClient.getMaxConnectionsPerDestination(), destination, 1);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -121,7 +120,7 @@ public class HttpClientTransportOverHTTP2 extends AbstractHttpClientTransport
|
|||
public HttpDestination newHttpDestination(Origin origin)
|
||||
{
|
||||
SocketAddress address = origin.getAddress().getSocketAddress();
|
||||
return new MultiplexHttpDestination(getHttpClient(), origin, getHTTP2Client().getClientConnector().isIntrinsicallySecure(address));
|
||||
return new HttpDestination(getHttpClient(), origin, getHTTP2Client().getClientConnector().isIntrinsicallySecure(address));
|
||||
}
|
||||
|
||||
@Override
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.http2.client.http.internal;
|
||||
package org.eclipse.jetty.http2.client.transport.internal;
|
||||
|
||||
import org.eclipse.jetty.http2.internal.HTTP2Channel;
|
||||
import org.eclipse.jetty.http2.internal.HTTP2Stream;
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.http2.client.http.internal;
|
||||
package org.eclipse.jetty.http2.client.transport.internal;
|
||||
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.util.Map;
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.http2.client.http.internal;
|
||||
package org.eclipse.jetty.http2.client.transport.internal;
|
||||
|
||||
import org.eclipse.jetty.client.HttpChannel;
|
||||
import org.eclipse.jetty.client.HttpDestination;
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.http2.client.http.internal;
|
||||
package org.eclipse.jetty.http2.client.transport.internal;
|
||||
|
||||
import java.nio.channels.AsynchronousCloseException;
|
||||
import java.util.Iterator;
|
||||
|
@ -46,7 +46,7 @@ import org.eclipse.jetty.util.thread.Sweeper;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class HttpConnectionOverHTTP2 extends HttpConnection implements Sweeper.Sweepable, ConnectionPool.Multiplexable
|
||||
public class HttpConnectionOverHTTP2 extends HttpConnection implements Sweeper.Sweepable, ConnectionPool.MaxMultiplexable
|
||||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(HttpConnectionOverHTTP2.class);
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.http2.client.http.internal;
|
||||
package org.eclipse.jetty.http2.client.transport.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.http2.client.http.internal;
|
||||
package org.eclipse.jetty.http2.client.transport.internal;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.function.Supplier;
|
|
@ -2,12 +2,12 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2</artifactId>
|
||||
<artifactId>jetty-http2</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>http2-client</artifactId>
|
||||
<artifactId>jetty-http2-client</artifactId>
|
||||
<name>Jetty Core :: HTTP2 :: Client</name>
|
||||
|
||||
<properties>
|
||||
|
@ -31,7 +31,7 @@
|
|||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-common</artifactId>
|
||||
<artifactId>jetty-http2-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
|
@ -2,12 +2,12 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2</artifactId>
|
||||
<artifactId>jetty-http2</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>http2-common</artifactId>
|
||||
<artifactId>jetty-http2-common</artifactId>
|
||||
<name>Jetty Core :: HTTP2 :: Common</name>
|
||||
|
||||
<properties>
|
||||
|
@ -17,7 +17,7 @@
|
|||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-hpack</artifactId>
|
||||
<artifactId>jetty-http2-hpack</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue