Merge branch 'jetty-9.4.x' into jetty-9.4.x-1027-Multipart

This commit is contained in:
Greg Wilkins 2018-03-21 16:50:29 +11:00
commit 8312f4567b
199 changed files with 1932 additions and 2076 deletions

6
Jenkinsfile vendored
View File

@ -41,8 +41,9 @@ def getFullBuild(jdk, os) {
maven: 'maven3',
jdk: "$jdk",
publisherStrategy: 'EXPLICIT',
globalMavenSettingsConfig: 'oss-settings.xml',
mavenLocalRepo: "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}") {
sh "mvn -V -B clean install -Dtest=None -T6"
sh "mvn -V -B clean install -DskipTests -T6"
}
}
@ -62,6 +63,7 @@ def getFullBuild(jdk, os) {
maven: 'maven3',
jdk: "$jdk",
publisherStrategy: 'EXPLICIT',
globalMavenSettingsConfig: 'oss-settings.xml',
mavenLocalRepo: "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}") {
sh "mvn -V -B javadoc:javadoc -T5"
}
@ -83,6 +85,7 @@ def getFullBuild(jdk, os) {
maven: 'maven3',
jdk: "$jdk",
publisherStrategy: 'EXPLICIT',
globalMavenSettingsConfig: 'oss-settings.xml',
mavenLocalRepo: "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}") {
//
sh "mvn -V -B install -Dmaven.test.failure.ignore=true -Prun-its -T3 -e -Dmaven.repo.local=${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}"
@ -137,6 +140,7 @@ def getFullBuild(jdk, os) {
maven: 'maven3',
jdk: "$jdk",
publisherStrategy: 'EXPLICIT',
globalMavenSettingsConfig: 'oss-settings.xml',
mavenLocalRepo: "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}") {
sh "mvn -V -B -Pcompact3 clean install -T5"
}

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables use of the apache implementation of JSP

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables the apache version of JSTL

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Selects an ALPN (Application Layer Protocol Negotiation) implementation by java version.

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.9.v20160720/alpn-boot-8.1.9.v20160720.jar|lib/alpn/alpn-boot-8.1.9.v20160720.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.9.v20160720/alpn-boot-8.1.9.v20160720.jar|lib/alpn/alpn-boot-8.1.9.v20160720.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.9.v20160720/alpn-boot-8.1.9.v20160720.jar|lib/alpn/alpn-boot-8.1.9.v20160720.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.10.v20161026/alpn-boot-8.1.10.v20161026.jar|lib/alpn/alpn-boot-8.1.10.v20161026.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.12.v20180117/alpn-boot-8.1.12.v20180117.jar|lib/alpn/alpn-boot-8.1.12.v20180117.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.12.v20180117/alpn-boot-8.1.12.v20180117.jar|lib/alpn/alpn-boot-8.1.12.v20180117.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.2.v20141202|lib/alpn/alpn-boot-8.1.2.v20141202.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.3.v20150130|lib/alpn/alpn-boot-8.1.3.v20150130.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.3.v20150130/alpn-boot-8.1.3.v20150130.jar|lib/alpn/alpn-boot-8.1.3.v20150130.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.3.v20150130/alpn-boot-8.1.3.v20150130.jar|lib/alpn/alpn-boot-8.1.3.v20150130.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.4.v20150727/alpn-boot-8.1.4.v20150727.jar|lib/alpn/alpn-boot-8.1.4.v20150727.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.5.v20150921/alpn-boot-8.1.5.v20150921.jar|lib/alpn/alpn-boot-8.1.5.v20150921.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.6.v20151105/alpn-boot-8.1.6.v20151105.jar|lib/alpn/alpn-boot-8.1.6.v20151105.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.6.v20151105/alpn-boot-8.1.6.v20151105.jar|lib/alpn/alpn-boot-8.1.6.v20151105.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.8.v20160420/alpn-boot-8.1.8.v20160420.jar|lib/alpn/alpn-boot-8.1.8.v20160420.jar

View File

@ -0,0 +1,4 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[depend]
alpn-impl/alpn-9

View File

@ -0,0 +1,4 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[depend]
alpn-impl/alpn-9

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Provides ALPN support for JDK 8, modifying the sun.security.ssl
classes and adding them to the JVM boot classpath.

View File

@ -1,5 +1,7 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Provides support for ALPN based on JDK 9 APIs.
Provides support for ALPN based on JDK 9+ APIs.
[lib]
lib/jetty-alpn-java-server-${jetty.version}.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables the ALPN (Application Layer Protocol Negotiation) TLS extension.

View File

@ -1,8 +0,0 @@
[name]
protonego-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables Annotation scanning for deployed webapplications.

View File

@ -80,7 +80,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.0-M1</version>
<version>3.0.0</version>
<configuration>
<skip>true</skip>
</configuration>

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Jetty setup to support Weld/CDI2 with WELD inside the webapp

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Experimental CDI/Weld integration

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Experimental CDI/Weld integration
Deprecated in favour of cdi2 module.

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Adds the Jetty HTTP client to the server classpath.

View File

@ -19,6 +19,8 @@
package org.eclipse.jetty.client;
import java.nio.channels.Selector;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@ -30,14 +32,37 @@ import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.util.SocketAddressResolver;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class LivelockTest
{
@Parameterized.Parameters(name = "server={0}, client={1}")
public static List<Object[]> data()
{
List<Object[]> data = new ArrayList<>();
// Server-live-lock, Client-live-lock
data.add(new Object[] { true, true });
data.add(new Object[] { true, false });
data.add(new Object[] { false, true });
data.add(new Object[] { false, false });
return data;
}
@Parameterized.Parameter(0)
public boolean serverLiveLock;
@Parameterized.Parameter(1)
public boolean clientLiveLock;
private Server server;
private ServerConnector connector;
private HttpClient client;
@ -73,7 +98,7 @@ public class LivelockTest
// ManagedSelectors that submit themselves in an attempt to cause a live lock
// as there will always be an action available to run.
int count = 25;
int count = 5;
HttpClientTransport transport = new HttpClientTransportOverHTTP(1);
client = new HttpClient(transport, null);
client.setMaxConnectionsPerDestination(2 * count);
@ -88,34 +113,21 @@ public class LivelockTest
AtomicBoolean busy = new AtomicBoolean(true);
ManagedSelector clientSelector = client.getContainedBeans(ManagedSelector.class).stream().findAny().get();
ManagedSelector.SelectorUpdate clientLivelock = new ManagedSelector.SelectorUpdate()
if (clientLiveLock)
{
@Override
public void update(Selector selector)
{
sleep(10);
if (busy.get())
clientSelector.submit(this);
}
};
clientSelector.submit(clientLivelock);
ManagedSelector serverSelector = connector.getContainedBeans(ManagedSelector.class).stream().findAny().get();
ManagedSelector.SelectorUpdate serverLivelock = new ManagedSelector.SelectorUpdate()
ManagedSelector clientSelector = client.getContainedBeans(ManagedSelector.class).stream().findAny().get();
busyLiveLock(busy, clientSelector);
}
if (serverLiveLock)
{
@Override
public void update(Selector selector)
{
sleep(10);
if (busy.get())
serverSelector.submit(this);
}
};
serverSelector.submit(serverLivelock);
ManagedSelector serverSelector = connector.getContainedBeans(ManagedSelector.class).stream().findAny().get();
busyLiveLock(busy, serverSelector);
}
int requestRate = 5;
long pause = 1000 / requestRate;
Logger clientLog = Log.getLogger("TESTClient");
CountDownLatch latch = new CountDownLatch(count);
for (int i = 0; i < count; ++i)
{
@ -125,6 +137,13 @@ public class LivelockTest
{
if (result.isSucceeded() && result.getResponse().getStatus() == HttpStatus.OK_200)
latch.countDown();
else
{
if(result.getRequestFailure() != null)
clientLog.warn(result.getRequestFailure());
if(result.getResponseFailure() != null)
clientLog.warn(result.getResponseFailure());
}
});
sleep(pause);
}
@ -134,11 +153,26 @@ public class LivelockTest
busy.set(false);
}
private void sleep(long time)
private void busyLiveLock(AtomicBoolean busy, ManagedSelector managedSelector)
{
ManagedSelector.SelectorUpdate liveLock = new ManagedSelector.SelectorUpdate()
{
@Override
public void update(Selector selector)
{
sleep(10);
if (busy.get())
managedSelector.submit(this);
}
};
managedSelector.submit(liveLock);
}
private void sleep(long millis)
{
try
{
Thread.sleep(time);
TimeUnit.MILLISECONDS.sleep(millis);
}
catch (InterruptedException x)
{

View File

@ -1,5 +1,5 @@
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
#org.eclipse.jetty.LEVEL=DEBUG
class=org.eclipse.jetty.util.log.StdErrLog
#org.eclipse.jetty.LEVEL=INFO
#org.eclipse.jetty.client.LEVEL=DEBUG
#org.eclipse.jetty.io.ChannelEndPoint.LEVEL=DEBUG
#org.eclipse.jetty.http.LEVEL=DEBUG

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables webapplication deployment from the webapps directory.

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables Deployer to apply common configuration to all webapp deployments

View File

@ -398,29 +398,37 @@
</build>
<dependencies>
<!-- For users of jetty-distribution via maven, none of the following
dependencies should be mandatory to function.
These only exist to make the reactor sane during the build
of jetty-distribution itself -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-home</artifactId>
<version>${project.version}</version>
<type>pom</type>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>test-jetty-webapp</artifactId>
<type>war</type>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>test-proxy-webapp</artifactId>
<type>war</type>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.example-async-rest</groupId>
<artifactId>example-async-rest-webapp</artifactId>
<version>${project.version}</version>
<type>war</type>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
@ -428,6 +436,7 @@
<version>${project.version}</version>
<classifier>html</classifier>
<type>zip</type>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@ -59,10 +59,6 @@ System Properties:
Properties:
-----------
java.version = 1.8.0_92
java.version.major = 1
java.version.minor = 8
java.version.revision = 0
java.version.update = 92
Jetty Server Classpath:
-----------------------

View File

@ -59,10 +59,6 @@ System Properties:
Properties:
-----------
java.version = 1.8.0_92
java.version.major = 1
java.version.minor = 8
java.version.revision = 0
java.version.update = 92
Jetty Server Classpath:
-----------------------

View File

@ -148,6 +148,14 @@ This is done by editing the associated ini file for the module.
If your server setup is using a centralized ini configuration, you will edit the `${jetty.base}/server.ini` file.
If you have elected to manage each module within it's own ini file, you can find these files in the `${jetty.base}/start.d` directory.
____
[IMPORTANT]
It is important that you *do not* modify the module files in the `$JETTY_HOME/modules` directory.
$JETTY_HOME should always remain a standard of truth.
If you want to make a change to an actual module file (not the values in its `ini-template`), either edit its associated `ini` file in the `$JETTY_BASE/start.d` directory or make a copy of the desired module file and copy it to the `$JETTY_BASE` directory and edit it there.
The start.jar reads local `$JETTY_BASE/modules` files (if they exist) before scanning `$JETTY_HOME`.
____
When a module is activated, a number of properties are set by default.
To view these defaults, open up the associated ini file.
Listed in the ini file is the associated module file and any properties that can be set.

View File

@ -719,10 +719,10 @@ This is _not_ a recommended usage.
____
[[conscrypt]]
===== Conscrypt SSL
==== Conscrypt SSL
Jetty also includes support for Google's https://github.com/google/conscrypt/[Conscrypt SSL], which is built on their fork of https://www.openssl.org/[OpenSSL], https://boringssl.googlesource.com/boringssl/[BoringSSL].
Implementing Conscrypt is very straightforward process - simply instantiate an instance of Conscrypt's `OpenSSLProvider` and set `Conscrypt` as a provider for Jetty's `SslContextFactory`:
Jetty includes support for Google's https://github.com/google/conscrypt/[Conscrypt SSL], which is built on their fork of https://www.openssl.org/[OpenSSL], https://boringssl.googlesource.com/boringssl/[BoringSSL].
Implementing Conscrypt for the link:{GITBROWSEURL}/jetty-alpn/jetty-alpn-conscrypt-server/src/test/java/org/eclipse/jetty/alpn/conscrypt/server/ConscryptHTTP2Server.java[server] or link:{GITBROWSEURL}/jetty-alpn/jetty-alpn-conscrypt-client/src/test/java/org/eclipse/jetty/alpn/java/client/ConscryptHTTP2Client.java[client] is very straightforward process - simply instantiate an instance of Conscrypt's `OpenSSLProvider` and set `Conscrypt` as a provider for Jetty's `SslContextFactory`:
[source, java, subs="{sub-order}"]
----

View File

@ -75,6 +75,17 @@ URI uri = URI.create("http://domain.com/secure");
auth.addAuthenticationResult(new BasicAuthentication.BasicResult(uri, "username", "password"));
----
In this way, the original request is enriched by `HttpClient` immediately with the `Authorization` header, and the server should respond with a 200 and the resource content rather than with the 401 and the challenge.
In this way, requests for the given URI are enriched by `HttpClient` immediately with the `Authorization` header, and the server should respond with a 200 and the resource content rather than with the 401 and the challenge.
It is also possible to preempt the authentication for a single request only, in this way:
[source, java, subs="{sub-order}"]
----
URI uri = URI.create("http://domain.com/secure");
Authentication.Result authn = new BasicAuthentication.BasicResult(uri, "username", "password")
Request request = httpClient.newRequest(uri);
authn.apply(request);
request.send();
----
See also the link:#http-client-proxy-authentication[proxy authentication section] for further information about how authentication works with HTTP proxies.

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Adds the FastCGI implementation to the classpath.

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables GCloud Datastore API and implementation

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Control GCloud API classpath

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables GCloudDatastore session management.

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables session data store in an embedded Hazelcast Map

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables session data store in a remote Hazelcast Map

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Installs the Conscrypt JSSE provider

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Deploys the Hawtio console as a webapplication.

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Deploys the JAMon webapplication

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Deploys the Jminix JMX Console within the server

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Deploys the Jolokia console as a web application.

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables JSP for all webapplications deployed on the server.

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables JSTL for all webapplications deployed on the server

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables the unix setUID configuration so that the server
may be started as root to open privileged ports/files before

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
This module causes jetty to stop immediately after starting. This is good for testing configuration and/or precompiling quickstart webapps

View File

@ -36,6 +36,7 @@ import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import static org.eclipse.jetty.http.HttpTokens.CARRIAGE_RETURN;
import static org.eclipse.jetty.http.HttpTokens.COLON;
import static org.eclipse.jetty.http.HttpTokens.LINE_FEED;
import static org.eclipse.jetty.http.HttpTokens.SPACE;
import static org.eclipse.jetty.http.HttpTokens.TAB;
@ -1074,7 +1075,7 @@ public class HttpParser
throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Header Folding");
// header value without name - continuation?
if (_valueString==null)
if (_valueString==null || _valueString.isEmpty())
{
_string.setLength(0);
_length=0;
@ -1166,10 +1167,6 @@ public class HttpParser
default:
{
// now handle the ch
if (b<HttpTokens.SPACE)
throw new BadMessageException();
// process previous header
if (_state==State.HEADER)
parsedHeader();
@ -1266,114 +1263,124 @@ public class HttpParser
break;
case IN_NAME:
if (b>HttpTokens.SPACE && b!=HttpTokens.COLON)
switch(b)
{
if (_header!=null)
{
setString(_header.asString());
_header=null;
_headerString=null;
}
_string.append((char)b);
_length=_string.length();
break;
}
// Fallthrough
case WS_AFTER_NAME:
if (b==HttpTokens.COLON)
{
if (_headerString==null)
{
case SPACE:
case TAB:
//Ignore trailing whitespaces ?
if (!complianceViolation(HttpComplianceSection.NO_WS_AFTER_FIELD_NAME,null))
{
_headerString=takeString();
_header=HttpHeader.CACHE.get(_headerString);
_length=-1;
setState(FieldState.WS_AFTER_NAME);
break;
}
throw new IllegalCharacterException(_state,b,buffer);
case COLON:
_headerString=takeString();
_header=HttpHeader.CACHE.get(_headerString);
}
_length=-1;
setState(FieldState.VALUE);
break;
}
if (b==HttpTokens.LINE_FEED)
{
if (_headerString==null)
{
_headerString=takeString();
_header=HttpHeader.CACHE.get(_headerString);
}
_string.setLength(0);
_valueString="";
_length=-1;
if (!complianceViolation(HttpComplianceSection.FIELD_COLON,_headerString))
{
setState(FieldState.FIELD);
_length=-1;
setState(FieldState.VALUE);
break;
}
}
case LINE_FEED:
_headerString=takeString();
_header=HttpHeader.CACHE.get(_headerString);
_string.setLength(0);
_valueString="";
_length=-1;
//Ignore trailing whitespaces
if (b==HttpTokens.SPACE && !complianceViolation(HttpComplianceSection.NO_WS_AFTER_FIELD_NAME,null))
if (!complianceViolation(HttpComplianceSection.FIELD_COLON,_headerString))
{
setState(FieldState.FIELD);
break;
}
throw new IllegalCharacterException(_state,b,buffer);
default:
if (b<0)
throw new IllegalCharacterException(_state,b,buffer);
_string.append((char)b);
_length=_string.length();
break;
}
break;
case WS_AFTER_NAME:
switch(b)
{
setState(FieldState.WS_AFTER_NAME);
break;
}
case SPACE:
case TAB:
break;
throw new IllegalCharacterException(_state,b,buffer);
case COLON:
setState(FieldState.VALUE);
break;
case LINE_FEED:
if (!complianceViolation(HttpComplianceSection.FIELD_COLON,_headerString))
{
setState(FieldState.FIELD);
break;
}
throw new IllegalCharacterException(_state,b,buffer);
default:
throw new IllegalCharacterException(_state,b,buffer);
}
break;
case VALUE:
if (b>HttpTokens.SPACE || b<0)
switch(b)
{
_string.append((char)(0xff&b));
_length=_string.length();
setState(FieldState.IN_VALUE);
break;
}
if (b==HttpTokens.SPACE || b==HttpTokens.TAB)
break;
if (b==HttpTokens.LINE_FEED)
{
_string.setLength(0);
_valueString="";
_length=-1;
setState(FieldState.FIELD);
break;
}
throw new IllegalCharacterException(_state,b,buffer);
case IN_VALUE:
if (b>=HttpTokens.SPACE || b<0 || b==HttpTokens.TAB)
{
if (_valueString!=null)
{
setString(_valueString);
_valueString=null;
_field=null;
}
_string.append((char)(0xff&b));
if (b>HttpTokens.SPACE || b<0)
_length=_string.length();
break;
}
if (b==HttpTokens.LINE_FEED)
{
if (_length > 0)
{
_valueString=takeString();
case LINE_FEED:
_string.setLength(0);
_valueString="";
_length=-1;
}
setState(FieldState.FIELD);
setState(FieldState.FIELD);
break;
case SPACE:
case TAB:
break;
default:
_string.append((char)(0xff&b));
_length=_string.length();
setState(FieldState.IN_VALUE);
break;
}
throw new IllegalCharacterException(_state,b,buffer);
break;
case IN_VALUE:
switch(b)
{
case LINE_FEED:
if (_length > 0)
{
_valueString=takeString();
_length=-1;
}
setState(FieldState.FIELD);
break;
case SPACE:
case TAB:
_string.append((char)(0xff&b));
break;
default:
_string.append((char)(0xff&b));
_length=_string.length();
break;
}
break;
default:
throw new IllegalStateException(_state.toString());

View File

@ -18,6 +18,7 @@
package org.eclipse.jetty.http;
import static org.eclipse.jetty.http.HttpComplianceSection.NO_FIELD_FOLDING;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@ -261,6 +262,8 @@ public class HttpParserTest
"Host: localhost\r\n" +
"Name: value\r\n" +
" extra\r\n" +
"Name2: \r\n" +
"\tvalue2\r\n" +
"\r\n");
HttpParser.RequestHandler handler = new Handler();
@ -270,10 +273,12 @@ public class HttpParserTest
Assert.assertThat(_bad, Matchers.nullValue());
Assert.assertEquals("Host", _hdr[0]);
Assert.assertEquals("localhost", _val[0]);
Assert.assertEquals(2, _headers);
Assert.assertEquals("Name", _hdr[1]);
Assert.assertEquals("value extra", _val[1]);
Assert.assertEquals(1, _headers);
Assert.assertThat(_complianceViolation, contains(HttpComplianceSection.NO_FIELD_FOLDING));
Assert.assertEquals("Name2", _hdr[2]);
Assert.assertEquals("value2", _val[2]);
Assert.assertThat(_complianceViolation, contains(NO_FIELD_FOLDING,NO_FIELD_FOLDING));
}
@Test
@ -399,7 +404,7 @@ public class HttpParserTest
ByteBuffer buffer = BufferUtil.toBuffer(
"HTTP/1.1 204 No Content\r\n" +
"Access-Control-Allow-Headers : Origin\r\n" +
"Other: value\r\n" +
"Other\t : value\r\n" +
"\r\n");
HttpParser.ResponseHandler handler = new Handler();
@ -422,7 +427,7 @@ public class HttpParserTest
Assert.assertEquals("Other", _hdr[1]);
Assert.assertEquals("value", _val[1]);
Assert.assertThat(_complianceViolation, contains(HttpComplianceSection.NO_WS_AFTER_FIELD_NAME));
Assert.assertThat(_complianceViolation, contains(HttpComplianceSection.NO_WS_AFTER_FIELD_NAME,HttpComplianceSection.NO_WS_AFTER_FIELD_NAME));
}
@Test
@ -709,7 +714,9 @@ public class HttpParserTest
public void testBadHeaderEncoding() throws Exception
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET / HTTP/1.0\r\nH\u00e6der0: value0\r\n\n\n");
"GET / HTTP/1.0\r\n"
+ "H\u00e6der0: value0\r\n"
+ "\n\n");
HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler);

View File

@ -1,5 +1,5 @@
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
org.eclipse.jetty.client.LEVEL=DEBUG
#org.eclipse.jetty.client.LEVEL=DEBUG
org.eclipse.jetty.http2.hpack.LEVEL=INFO
#org.eclipse.jetty.http2.LEVEL=DEBUG
#org.eclipse.jetty.io.ssl.LEVEL=DEBUG

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables HTTP2 protocol support on the TLS(SSL) Connector,
using the ALPN extension to select which protocol to use.

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables the HTTP2C protocol on the HTTP Connector
The connector will accept both HTTP/1 and HTTP/2 connections.

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables session data store in a local Infinispan cache

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables session data store in a local Infinispan cache

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables session data store in a remote Infinispan cache

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables session data store in a remote Infinispan cache

View File

@ -62,6 +62,8 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint
protected final void shutdownInput()
{
if (LOG.isDebugEnabled())
LOG.debug("shutdownInput {}",this);
while(true)
{
State s = _state.get();
@ -114,6 +116,8 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint
@Override
public final void shutdownOutput()
{
if (LOG.isDebugEnabled())
LOG.debug("shutdownOutput {}",this);
while(true)
{
State s = _state.get();
@ -166,11 +170,15 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint
@Override
public final void close()
{
if (LOG.isDebugEnabled())
LOG.debug("close {}",this);
close(null);
}
protected final void close(Throwable failure)
{
if (LOG.isDebugEnabled())
LOG.debug("close({}) {}",failure,this);
while(true)
{
State s = _state.get();

View File

@ -42,7 +42,6 @@ import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.jetty.io.ManagedSelector.Connect;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.component.DumpableCollection;
@ -246,16 +245,15 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable
@Override
public void dump(Appendable out, String indent) throws IOException
{
List<String> keys;
List<SelectorUpdate> updates;
Selector selector = _selector;
List<String> keys = null;
List<SelectorUpdate> updates = null;
if (selector != null && selector.isOpen())
{
DumpKeys dump = new DumpKeys();
String updatesAt;
String updatesAt = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now());
synchronized(ManagedSelector.this)
{
updatesAt = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now());
updates = new ArrayList<>(_updates);
_updates.addFirst(dump);
_selecting = false;
@ -322,7 +320,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable
return task;
processUpdates();
updateKeys();
if (!select())
@ -372,7 +370,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable
LOG.debug("updates {}",updates);
if (selector != null)
selector.wakeup();
selector.wakeup();
}
private boolean select()
@ -385,6 +383,8 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable
if (LOG.isDebugEnabled())
LOG.debug("Selector {} waiting on select", selector);
int selected = selector.select();
if (selected == 0)
selected = selector.selectNow();
if (LOG.isDebugEnabled())
LOG.debug("Selector {} woken up from select, {}/{} selected", selector, selected, selector.keys().size());
@ -397,7 +397,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable
}
_keys = selector.selectedKeys();
_cursor = _keys.iterator();
_cursor = _keys.isEmpty() ? Collections.emptyIterator() : _keys.iterator();
if (LOG.isDebugEnabled())
LOG.debug("Selector {} processing {} keys, {} updates", selector, _keys.size(), updates);

View File

@ -81,7 +81,8 @@ import org.eclipse.jetty.util.thread.Invocable;
public class SslConnection extends AbstractConnection
{
private static final Logger LOG = Log.getLogger(SslConnection.class);
private static final ThreadLocal<Boolean> __tryWriteAgain = new ThreadLocal<>();
private final List<SslHandshakeListener> handshakeListeners = new ArrayList<>();
private final ByteBufferPool _bufferPool;
private final SSLEngine _sslEngine;
@ -95,7 +96,7 @@ public class SslConnection extends AbstractConnection
private int _renegotiationLimit = -1;
private boolean _closedOutbound;
private boolean _allowMissingCloseMessage = true;
private abstract class RunnableTask implements Runnable, Invocable
{
private final String _operation;
@ -506,11 +507,12 @@ public class SslConnection extends AbstractConnection
}
else
{
// TODO This should not be required and we should be able to do all retries within flush
// We can get here because the WriteFlusher might not see progress
// when it has just flushed the encrypted data, but not consumed anymore
// of the application buffers. This is mostly avoided by another iteration
// within DecryptedEndPoint flush(), but I cannot convince myself that
// this is never ever the case.
// within DecryptedEndPoint flush(), but this still occurs sometime on some
// tests on some systems??? More investigation is needed!
try_again = true;
}
}
@ -526,12 +528,35 @@ public class SslConnection extends AbstractConnection
{
// don't bother writing, just notify of close
getWriteFlusher().onClose();
return;
}
// TODO this ugly recursion protection is only needed until we remove the try again
// logic from this method and make flush do the try again.
Boolean tryWriteAgain = __tryWriteAgain.get();
if (tryWriteAgain==null)
{
try
{
// Keep running complete write until
__tryWriteAgain.set(Boolean.FALSE);
do
{
_runCompleteWrite.run();
}
while (Boolean.TRUE.equals(__tryWriteAgain.get()));
}
finally
{
__tryWriteAgain.remove();
}
}
else
{
// Try again
_runCompleteWrite.run();
// Don't recurse but get top caller to iterate
__tryWriteAgain.set(Boolean.TRUE);
}
}
}

View File

@ -293,9 +293,9 @@ public class ByteArrayEndPointTest
assertEquals("test", BufferUtil.toString(buffer));
// Wait for a read timeout.
long start = System.nanoTime();
fcb = new FutureCallback();
endp.fillInterested(fcb);
long start = System.nanoTime();
try
{
fcb.get();
@ -308,40 +308,5 @@ public class ByteArrayEndPointTest
assertThat(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start), greaterThan(halfIdleTimeout));
assertThat("Endpoint open", endp.isOpen(), is(true));
// We need to delay the write timeout test below from the read timeout test above.
// The reason is that the scheduler thread that fails the endPoint WriteFlusher
// because of the read timeout above runs concurrently with the write below, and
// if it runs just after the write below, the test fails because the write callback
// below fails immediately rather than after the idle timeout.
Thread.sleep(halfIdleTimeout);
// Write more than the output capacity, then wait for idle timeout.
fcb = new FutureCallback();
start = System.nanoTime();
endp.write(fcb, BufferUtil.toBuffer("This is too long"));
try
{
fcb.get();
fail();
}
catch (ExecutionException t)
{
assertThat(t.getCause(), instanceOf(TimeoutException.class));
}
assertThat(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start), greaterThan(halfIdleTimeout));
// Still open because it has not been oshut or closed explicitly.
assertThat("Endpoint open", endp.isOpen(), is(true));
// Make sure the endPoint is closed when the callback fails.
endp.fillInterested(new Closer(endp));
Thread.sleep(halfIdleTimeout);
// Still open because it has not been oshut or closed explicitly.
assertThat("Endpoint open", endp.isOpen(), is(true));
// Shutdown output.
endp.shutdownOutput();
Thread.sleep(idleTimeout);
assertThat("Endpoint closed", endp.isOpen(), is(false));
}
}

View File

@ -1,833 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.io;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.lessThan;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FutureCallback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.Scheduler;
import org.eclipse.jetty.util.thread.TimerScheduler;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
public class SelectChannelEndPointTest
{
private static final Logger LOG = Log.getLogger(SelectChannelEndPointTest.class);
protected CountDownLatch _lastEndPointLatch;
protected volatile EndPoint _lastEndPoint;
protected ServerSocketChannel _connector;
protected QueuedThreadPool _threadPool = new QueuedThreadPool();
protected Scheduler _scheduler = new TimerScheduler();
protected SelectorManager _manager = new SelectorManager(_threadPool, _scheduler)
{
@Override
public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Object attachment)
{
return SelectChannelEndPointTest.this.newConnection(channel, endpoint);
}
@Override
protected EndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey key) throws IOException
{
SocketChannelEndPoint endp = new SocketChannelEndPoint(channel, selector, key, getScheduler());
endp.setIdleTimeout(60000);
_lastEndPoint = endp;
_lastEndPointLatch.countDown();
return endp;
}
};
// Must be volatile or the test may fail spuriously
protected volatile int _blockAt = 0;
private volatile int _writeCount = 1;
@Before
public void startManager() throws Exception
{
System.gc();
_writeCount = 1;
_lastEndPoint = null;
_lastEndPointLatch = new CountDownLatch(1);
_connector = ServerSocketChannel.open();
_connector.socket().bind(null);
_scheduler.start();
_threadPool.start();
_manager.start();
}
@After
public void stopManager() throws Exception
{
_scheduler.stop();
_manager.stop();
_threadPool.stop();
_connector.close();
}
protected Socket newClient() throws IOException
{
return new Socket(_connector.socket().getInetAddress(), _connector.socket().getLocalPort());
}
protected Connection newConnection(SelectableChannel channel, EndPoint endpoint)
{
return new TestConnection(endpoint);
}
public class TestConnection extends AbstractConnection
{
volatile FutureCallback _blockingRead;
ByteBuffer _in = BufferUtil.allocate(32 * 1024);
ByteBuffer _out = BufferUtil.allocate(32 * 1024);
long _last = -1;
final CountDownLatch _latch;
public TestConnection(EndPoint endp)
{
super(endp, _threadPool);
_latch=null;
}
public TestConnection(EndPoint endp,CountDownLatch latch)
{
super(endp, _threadPool);
_latch=latch;
}
@Override
public void onOpen()
{
super.onOpen();
fillInterested();
}
@Override
public void onFillInterestedFailed(Throwable cause)
{
Callback blocking = _blockingRead;
if (blocking!=null)
{
_blockingRead=null;
blocking.failed(cause);
return;
}
super.onFillInterestedFailed(cause);
}
@Override
public void onFillable()
{
if (_latch!=null)
{
try
{
_latch.await();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
Callback blocking = _blockingRead;
if (blocking!=null)
{
_blockingRead=null;
blocking.succeeded();
return;
}
EndPoint _endp = getEndPoint();
try
{
_last = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
boolean progress = true;
while (progress)
{
progress = false;
// Fill the input buffer with everything available
BufferUtil.compact(_in);
if (BufferUtil.isFull(_in))
throw new IllegalStateException("FULL " + BufferUtil.toDetailString(_in));
int filled = _endp.fill(_in);
if (filled > 0)
progress = true;
// If the tests wants to block, then block
while (_blockAt > 0 && _endp.isOpen() && _in.remaining() < _blockAt)
{
FutureCallback future = _blockingRead = new FutureCallback();
fillInterested();
future.get();
filled = _endp.fill(_in);
progress |= filled > 0;
}
// Copy to the out buffer
if (BufferUtil.hasContent(_in) && BufferUtil.append(_out, _in) > 0)
progress = true;
// Blocking writes
if (BufferUtil.hasContent(_out))
{
ByteBuffer out = _out.duplicate();
BufferUtil.clear(_out);
for (int i = 0; i < _writeCount; i++)
{
FutureCallback blockingWrite = new FutureCallback();
_endp.write(blockingWrite, out.asReadOnlyBuffer());
blockingWrite.get();
}
progress = true;
}
// are we done?
if (_endp.isInputShutdown())
_endp.shutdownOutput();
}
if (_endp.isOpen())
fillInterested();
}
catch (ExecutionException e)
{
// Timeout does not close, so echo exception then shutdown
try
{
FutureCallback blockingWrite = new FutureCallback();
_endp.write(blockingWrite, BufferUtil.toBuffer("EE: " + BufferUtil.toString(_in)));
blockingWrite.get();
_endp.shutdownOutput();
}
catch (Exception e2)
{
// e2.printStackTrace();
}
}
catch (InterruptedException | EofException e)
{
Log.getRootLogger().ignore(e);
}
catch (Exception e)
{
Log.getRootLogger().warn(e);
}
finally
{
}
}
}
@Test
public void testEcho() throws Exception
{
Socket client = newClient();
client.setSoTimeout(60000);
SocketChannel server = _connector.accept();
server.configureBlocking(false);
_manager.accept(server);
// Write client to server
client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8));
// Verify echo server to client
for (char c : "HelloWorld".toCharArray())
{
int b = client.getInputStream().read();
assertTrue(b > 0);
assertEquals(c, (char)b);
}
// wait for read timeout
client.setSoTimeout(500);
long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
try
{
client.getInputStream().read();
Assert.fail();
}
catch (SocketTimeoutException e)
{
long duration = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start;
Assert.assertThat("timeout duration", duration, greaterThanOrEqualTo(400L));
}
// write then shutdown
client.getOutputStream().write("Goodbye Cruel TLS".getBytes(StandardCharsets.UTF_8));
// Verify echo server to client
for (char c : "Goodbye Cruel TLS".toCharArray())
{
int b = client.getInputStream().read();
Assert.assertThat("expect valid char integer", b, greaterThan(0));
assertEquals("expect characters to be same", c, (char)b);
}
client.close();
for (int i = 0; i < 10; ++i)
{
if (server.isOpen())
Thread.sleep(10);
else
break;
}
assertFalse(server.isOpen());
}
@Test
public void testShutdown() throws Exception
{
Socket client = newClient();
client.setSoTimeout(500);
SocketChannel server = _connector.accept();
server.configureBlocking(false);
_manager.accept(server);
// Write client to server
client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8));
// Verify echo server to client
for (char c : "HelloWorld".toCharArray())
{
int b = client.getInputStream().read();
assertTrue(b > 0);
assertEquals(c, (char)b);
}
// wait for read timeout
long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
try
{
client.getInputStream().read();
Assert.fail();
}
catch (SocketTimeoutException e)
{
assertTrue(TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start >= 400);
}
// write then shutdown
client.getOutputStream().write("Goodbye Cruel TLS".getBytes(StandardCharsets.UTF_8));
client.shutdownOutput();
// Verify echo server to client
for (char c : "Goodbye Cruel TLS".toCharArray())
{
int b = client.getInputStream().read();
assertTrue(b > 0);
assertEquals(c, (char)b);
}
// Read close
assertEquals(-1, client.getInputStream().read());
}
@Test
public void testReadBlocked() throws Exception
{
Socket client = newClient();
SocketChannel server = _connector.accept();
server.configureBlocking(false);
_manager.accept(server);
OutputStream clientOutputStream = client.getOutputStream();
InputStream clientInputStream = client.getInputStream();
int specifiedTimeout = 1000;
client.setSoTimeout(specifiedTimeout);
// Write 8 and cause block waiting for 10
_blockAt = 10;
clientOutputStream.write("12345678".getBytes(StandardCharsets.UTF_8));
clientOutputStream.flush();
Assert.assertTrue(_lastEndPointLatch.await(1, TimeUnit.SECONDS));
_lastEndPoint.setIdleTimeout(10 * specifiedTimeout);
Thread.sleep((11 * specifiedTimeout) / 10);
long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
try
{
int b = clientInputStream.read();
Assert.fail("Should have timed out waiting for a response, but read " + b);
}
catch (SocketTimeoutException e)
{
int elapsed = Long.valueOf(TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start).intValue();
Assert.assertThat("Expected timeout", elapsed, greaterThanOrEqualTo(3 * specifiedTimeout / 4));
}
// write remaining characters
clientOutputStream.write("90ABCDEF".getBytes(StandardCharsets.UTF_8));
clientOutputStream.flush();
// Verify echo server to client
for (char c : "1234567890ABCDEF".toCharArray())
{
int b = clientInputStream.read();
assertTrue(b > 0);
assertEquals(c, (char)b);
}
}
@Test
public void testIdle() throws Exception
{
int idleTimeout = 2000;
Socket client = newClient();
client.setSoTimeout(idleTimeout*10);
SocketChannel server = _connector.accept();
server.configureBlocking(false);
_manager.accept(server);
// Write client to server
long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8));
// Verify echo server to client
for (char c : "HelloWorld".toCharArray())
{
int b = client.getInputStream().read();
assertTrue(b > 0);
assertEquals(c, (char)b);
}
Assert.assertTrue(_lastEndPointLatch.await(1, TimeUnit.SECONDS));
_lastEndPoint.setIdleTimeout(idleTimeout);
// read until idle shutdown received
int b = client.getInputStream().read();
assertEquals(-1, b);
long idle = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start;
assertThat(idle, greaterThan(idleTimeout / 2L));
assertThat(idle, lessThan(idleTimeout * 2L));
// But endpoint may still be open for a little bit.
for (int i = 0; i < 20; ++i)
{
if (_lastEndPoint.isOpen())
Thread.sleep(2 * idleTimeout / 10);
else
break;
}
assertFalse(_lastEndPoint.isOpen());
}
@Test
public void testBlockedReadIdle() throws Exception
{
Socket client = newClient();
InputStream clientInputStream = client.getInputStream();
OutputStream clientOutputStream = client.getOutputStream();
client.setSoTimeout(5000);
SocketChannel server = _connector.accept();
server.configureBlocking(false);
_manager.accept(server);
// Write client to server
clientOutputStream.write("HelloWorld".getBytes(StandardCharsets.UTF_8));
// Verify echo server to client
for (char c : "HelloWorld".toCharArray())
{
int b = clientInputStream.read();
assertTrue(b > 0);
assertEquals(c, (char)b);
}
Assert.assertTrue(_lastEndPointLatch.await(1, TimeUnit.SECONDS));
int idleTimeout = 500;
_lastEndPoint.setIdleTimeout(idleTimeout);
// Write 8 and cause block waiting for 10
_blockAt = 10;
clientOutputStream.write("12345678".getBytes(StandardCharsets.UTF_8));
clientOutputStream.flush();
// read until idle shutdown received
long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
int b = clientInputStream.read();
assertEquals('E', b);
long idle = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start;
assertTrue(idle > idleTimeout / 2);
assertTrue(idle < idleTimeout * 2);
for (char c : "E: 12345678".toCharArray())
{
b = clientInputStream.read();
assertTrue(b > 0);
assertEquals(c, (char)b);
}
b = clientInputStream.read();
assertEquals(-1,b);
// But endpoint is still open.
if(_lastEndPoint.isOpen())
// Wait for another idle callback
Thread.sleep(idleTimeout * 2);
// endpoint is closed.
assertFalse(_lastEndPoint.isOpen());
}
@Test
public void testStress() throws Exception
{
Socket client = newClient();
client.setSoTimeout(30000);
SocketChannel server = _connector.accept();
server.configureBlocking(false);
_manager.accept(server);
final int writes = 200000;
final byte[] bytes = "HelloWorld-".getBytes(StandardCharsets.UTF_8);
byte[] count = "0\n".getBytes(StandardCharsets.UTF_8);
BufferedOutputStream out = new BufferedOutputStream(client.getOutputStream());
final CountDownLatch latch = new CountDownLatch(writes);
final InputStream in = new BufferedInputStream(client.getInputStream());
final long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
out.write(bytes);
out.write(count);
out.flush();
Assert.assertTrue(_lastEndPointLatch.await(1, TimeUnit.SECONDS));
_lastEndPoint.setIdleTimeout(5000);
new Thread()
{
@Override
public void run()
{
Thread.currentThread().setPriority(MAX_PRIORITY);
long last = -1;
int count = -1;
try
{
while (latch.getCount() > 0)
{
// Verify echo server to client
for (byte b0 : bytes)
{
int b = in.read();
Assert.assertThat(b, greaterThan(0));
assertEquals(0xff & b0, b);
}
count = 0;
int b = in.read();
while (b > 0 && b != '\n')
{
count = count * 10 + (b - '0');
b = in.read();
}
last = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
//if (latch.getCount()%1000==0)
// System.out.println(writes-latch.getCount());
latch.countDown();
}
}
catch (Throwable e)
{
long now = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
System.err.println("count=" + count);
System.err.println("latch=" + latch.getCount());
System.err.println("time=" + (now - start));
System.err.println("last=" + (now - last));
System.err.println("endp=" + _lastEndPoint);
System.err.println("conn=" + _lastEndPoint.getConnection());
e.printStackTrace();
}
}
}.start();
// Write client to server
for (int i = 1; i < writes; i++)
{
out.write(bytes);
out.write(Integer.toString(i).getBytes(StandardCharsets.ISO_8859_1));
out.write('\n');
if (i % 1000 == 0)
{
//System.err.println(i+"/"+writes);
out.flush();
}
Thread.yield();
}
out.flush();
long last = latch.getCount();
while (!latch.await(5, TimeUnit.SECONDS))
{
//System.err.println(latch.getCount());
if (latch.getCount() == last)
Assert.fail();
last = latch.getCount();
}
assertEquals(0, latch.getCount());
}
@Test
public void testWriteBlocked() throws Exception
{
Socket client = newClient();
client.setSoTimeout(10000);
SocketChannel server = _connector.accept();
server.configureBlocking(false);
_manager.accept(server);
// Write client to server
_writeCount = 10000;
String data = "Now is the time for all good men to come to the aid of the party";
client.getOutputStream().write(data.getBytes(StandardCharsets.UTF_8));
BufferedInputStream in = new BufferedInputStream(client.getInputStream());
int byteNum = 0;
try
{
for (int i = 0; i < _writeCount; i++)
{
if (i % 1000 == 0)
TimeUnit.MILLISECONDS.sleep(200);
// Verify echo server to client
for (int j = 0; j < data.length(); j++)
{
char c = data.charAt(j);
int b = in.read();
byteNum++;
assertTrue(b > 0);
assertEquals("test-" + i + "/" + j,c,(char)b);
}
if (i == 0)
_lastEndPoint.setIdleTimeout(60000);
}
}
catch (SocketTimeoutException e)
{
System.err.println("SelectorManager.dump() = " + _manager.dump());
LOG.warn("Server: " + server);
LOG.warn("Error reading byte #" + byteNum,e);
throw e;
}
client.close();
for (int i = 0; i < 10; ++i)
{
if (server.isOpen())
Thread.sleep(10);
else
break;
}
assertFalse(server.isOpen());
}
// TODO make this test reliable
@Test
@Ignore
public void testRejectedExecution() throws Exception
{
_manager.stop();
_threadPool.stop();
final CountDownLatch latch = new CountDownLatch(1);
BlockingQueue<Runnable> q = new ArrayBlockingQueue<>(4);
_threadPool = new QueuedThreadPool(4,4,60000,q);
_manager = new SelectorManager(_threadPool, _scheduler, 1)
{
@Override
protected EndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey selectionKey) throws IOException
{
SocketChannelEndPoint endp = new SocketChannelEndPoint(channel,selector,selectionKey,getScheduler());
_lastEndPoint = endp;
_lastEndPointLatch.countDown();
return endp;
}
@Override
public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Object attachment) throws IOException
{
return new TestConnection(endpoint,latch);
}
};
_threadPool.start();
_manager.start();
AtomicInteger timeout = new AtomicInteger();
AtomicInteger rejections = new AtomicInteger();
AtomicInteger echoed = new AtomicInteger();
CountDownLatch closed = new CountDownLatch(20);
for (int i=0;i<20;i++)
{
new Thread()
{
@Override
public void run()
{
try(Socket client = newClient();)
{
client.setSoTimeout(5000);
SocketChannel server = _connector.accept();
server.configureBlocking(false);
_manager.accept(server);
// Write client to server
client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8));
client.getOutputStream().flush();
client.shutdownOutput();
// Verify echo server to client
for (char c : "HelloWorld".toCharArray())
{
int b = client.getInputStream().read();
assertTrue(b > 0);
assertEquals(c, (char)b);
}
assertEquals(-1,client.getInputStream().read());
echoed.incrementAndGet();
}
catch(SocketTimeoutException x)
{
x.printStackTrace();
timeout.incrementAndGet();
}
catch(Throwable x)
{
rejections.incrementAndGet();
}
finally
{
closed.countDown();
}
}
}.start();
}
// unblock the handling
latch.countDown();
// wait for all clients to complete or fail
closed.await();
// assert some clients must have been rejected
Assert.assertThat(rejections.get(),Matchers.greaterThan(0));
// but not all of them
Assert.assertThat(rejections.get(),Matchers.lessThan(20));
// none should have timed out
Assert.assertThat(timeout.get(),Matchers.equalTo(0));
// and the rest should have worked
Assert.assertThat(echoed.get(),Matchers.equalTo(20-rejections.get()));
// and the selector is still working for new requests
try(Socket client = newClient();)
{
client.setSoTimeout(5000);
SocketChannel server = _connector.accept();
server.configureBlocking(false);
_manager.accept(server);
// Write client to server
client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8));
client.getOutputStream().flush();
client.shutdownOutput();
// Verify echo server to client
for (char c : "HelloWorld".toCharArray())
{
int b = client.getInputStream().read();
assertTrue(b > 0);
assertEquals(c, (char)b);
}
assertEquals(-1,client.getInputStream().read());
}
}
}

View File

@ -43,7 +43,7 @@ import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
public class SelectChannelEndPointInterestsTest
public class SocketChannelEndPointInterestsTest
{
private QueuedThreadPool threadPool;
private Scheduler scheduler;

View File

@ -23,25 +23,51 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import org.eclipse.jetty.util.BufferUtil;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public abstract class EndPointTest<T extends EndPoint>
public class SocketChannelEndPointOpenCloseTest
{
public static class EndPointPair<T>
public static class EndPointPair
{
public T client;
public T server;
public SocketChannelEndPoint client;
public SocketChannelEndPoint server;
}
protected abstract EndPointPair<T> newConnection() throws Exception;
static ServerSocketChannel connector;
@BeforeClass
public static void open() throws Exception
{
connector = ServerSocketChannel.open();
connector.socket().bind(null);
}
@AfterClass
public static void close() throws Exception
{
connector.close();
connector=null;
}
private EndPointPair newConnection() throws Exception
{
EndPointPair c = new EndPointPair();
c.client=new SocketChannelEndPoint(SocketChannel.open(connector.socket().getLocalSocketAddress()),null,null,null);
c.server=new SocketChannelEndPoint(connector.accept(),null,null,null);
return c;
}
@Test
public void testClientServerExchange() throws Exception
{
EndPointPair<T> c = newConnection();
EndPointPair c = newConnection();
ByteBuffer buffer = BufferUtil.allocate(4096);
// Client sends a request
@ -110,15 +136,12 @@ public abstract class EndPointTest<T extends EndPoint>
assertTrue(c.client.isOutputShutdown());
assertFalse(c.server.isOpen());
assertTrue(c.server.isOutputShutdown());
}
@Test
public void testClientClose() throws Exception
{
EndPointPair<T> c = newConnection();
EndPointPair c = newConnection();
ByteBuffer buffer = BufferUtil.allocate(4096);
c.client.flush(BufferUtil.toBuffer("request"));

View File

@ -18,49 +18,832 @@
package org.eclipse.jetty.io;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSocket;
public class SocketChannelEndPointTest extends EndPointTest<SocketChannelEndPoint>
import org.eclipse.jetty.io.ssl.SslConnection;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.toolchain.test.TestTracker;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FutureCallback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.Scheduler;
import org.eclipse.jetty.util.thread.TimerScheduler;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@SuppressWarnings("Duplicates")
@RunWith(Parameterized.class)
public class SocketChannelEndPointTest
{
static ServerSocketChannel connector;
private static final Logger LOG = Log.getLogger(SocketChannelEndPoint.class);
@BeforeClass
public static void open() throws Exception
public interface Scenario
{
connector = ServerSocketChannel.open();
connector.socket().bind(null);
Socket newClient(ServerSocketChannel connector) throws IOException;
Connection newConnection(SelectableChannel channel, EndPoint endPoint, Executor executor, AtomicInteger blockAt, AtomicInteger writeCount);
boolean supportsHalfCloses();
}
@AfterClass
public static void close() throws Exception
@Parameterized.Parameters(name = "{0}")
public static List<Object[]> data() throws Exception
{
connector.close();
connector=null;
List<Object[]> ret = new ArrayList<>();
NormalScenario normalScenario = new NormalScenario();
ret.add(new Object[]{normalScenario});
ret.add(new Object[]{new SslScenario(normalScenario)});
return ret;
}
@Override
protected EndPointPair<SocketChannelEndPoint> newConnection() throws Exception
{
EndPointPair<SocketChannelEndPoint> c = new EndPointPair<>();
@Rule
public TestTracker tracker = new TestTracker();
c.client=new SocketChannelEndPoint(SocketChannel.open(connector.socket().getLocalSocketAddress()),null,null,null);
c.server=new SocketChannelEndPoint(connector.accept(),null,null,null);
return c;
private final Scenario _scenario;
private ServerSocketChannel _connector;
private QueuedThreadPool _threadPool;
private Scheduler _scheduler;
private SelectorManager _manager;
private volatile EndPoint _lastEndPoint;
private CountDownLatch _lastEndPointLatch;
// Must be volatile or the test may fail spuriously
private AtomicInteger _blockAt = new AtomicInteger(0);
private AtomicInteger _writeCount = new AtomicInteger(1);
public SocketChannelEndPointTest(Scenario scenario) throws Exception
{
_scenario = scenario;
_threadPool = new QueuedThreadPool();
_scheduler = new TimerScheduler();
_manager = new ScenarioSelectorManager(_threadPool, _scheduler);
_lastEndPointLatch = new CountDownLatch(1);
_connector = ServerSocketChannel.open();
_connector.socket().bind(null);
_scheduler.start();
_threadPool.start();
_manager.start();
}
@Override
public void testClientClose() throws Exception
@After
public void stopManager() throws Exception
{
super.testClientClose();
_scheduler.stop();
_manager.stop();
_threadPool.stop();
_connector.close();
}
@Override
public void testClientServerExchange() throws Exception
@Test
public void testEcho() throws Exception
{
super.testClientServerExchange();
Socket client = _scenario.newClient(_connector);
client.setSoTimeout(60000);
SocketChannel server = _connector.accept();
server.configureBlocking(false);
_manager.accept(server);
// Write client to server
client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8));
// Verify echo server to client
for (char c : "HelloWorld".toCharArray())
{
int b = client.getInputStream().read();
assertTrue(b > 0);
assertEquals(c, (char) b);
}
// wait for read timeout
client.setSoTimeout(500);
long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
try
{
client.getInputStream().read();
Assert.fail();
}
catch (SocketTimeoutException e)
{
long duration = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start;
Assert.assertThat("timeout duration", duration, greaterThanOrEqualTo(400L));
}
// write then shutdown
client.getOutputStream().write("Goodbye Cruel TLS".getBytes(StandardCharsets.UTF_8));
// Verify echo server to client
for (char c : "Goodbye Cruel TLS".toCharArray())
{
int b = client.getInputStream().read();
Assert.assertThat("expect valid char integer", b, greaterThan(0));
assertEquals("expect characters to be same", c, (char) b);
}
client.close();
for (int i = 0; i < 10; ++i)
{
if (server.isOpen())
Thread.sleep(10);
else
break;
}
assertFalse(server.isOpen());
}
@Test
public void testShutdown() throws Exception
{
assumeTrue("Scenario supports half-close", _scenario.supportsHalfCloses());
Socket client = _scenario.newClient(_connector);
client.setSoTimeout(500);
SocketChannel server = _connector.accept();
server.configureBlocking(false);
_manager.accept(server);
// Write client to server
client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8));
// Verify echo server to client
for (char c : "HelloWorld".toCharArray())
{
int b = client.getInputStream().read();
assertTrue(b > 0);
assertEquals(c, (char) b);
}
// wait for read timeout
long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
try
{
client.getInputStream().read();
Assert.fail();
}
catch (SocketTimeoutException e)
{
assertTrue(TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start >= 400);
}
// write then shutdown
client.getOutputStream().write("Goodbye Cruel TLS".getBytes(StandardCharsets.UTF_8));
client.shutdownOutput();
// Verify echo server to client
for (char c : "Goodbye Cruel TLS".toCharArray())
{
int b = client.getInputStream().read();
assertTrue(b > 0);
assertEquals(c, (char) b);
}
// Read close
assertEquals(-1, client.getInputStream().read());
}
@Test
public void testReadBlocked() throws Exception
{
Socket client = _scenario.newClient(_connector);
SocketChannel server = _connector.accept();
server.configureBlocking(false);
_manager.accept(server);
OutputStream clientOutputStream = client.getOutputStream();
InputStream clientInputStream = client.getInputStream();
int specifiedTimeout = 1000;
client.setSoTimeout(specifiedTimeout);
// Write 8 and cause block waiting for 10
_blockAt.set(10);
clientOutputStream.write("12345678".getBytes(StandardCharsets.UTF_8));
clientOutputStream.flush();
Assert.assertTrue(_lastEndPointLatch.await(1, TimeUnit.SECONDS));
_lastEndPoint.setIdleTimeout(10 * specifiedTimeout);
Thread.sleep((11 * specifiedTimeout) / 10);
long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
try
{
int b = clientInputStream.read();
Assert.fail("Should have timed out waiting for a response, but read " + b);
}
catch (SocketTimeoutException e)
{
int elapsed = Long.valueOf(TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start).intValue();
Assert.assertThat("Expected timeout", elapsed, greaterThanOrEqualTo(3 * specifiedTimeout / 4));
}
// write remaining characters
clientOutputStream.write("90ABCDEF".getBytes(StandardCharsets.UTF_8));
clientOutputStream.flush();
// Verify echo server to client
for (char c : "1234567890ABCDEF".toCharArray())
{
int b = clientInputStream.read();
assertTrue(b > 0);
assertEquals(c, (char) b);
}
}
@Test
public void testStress() throws Exception
{
Socket client = _scenario.newClient(_connector);
client.setSoTimeout(30000);
SocketChannel server = _connector.accept();
server.configureBlocking(false);
_manager.accept(server);
final int writes = 200000;
final byte[] bytes = "HelloWorld-".getBytes(StandardCharsets.UTF_8);
byte[] count = "0\n".getBytes(StandardCharsets.UTF_8);
BufferedOutputStream out = new BufferedOutputStream(client.getOutputStream());
final CountDownLatch latch = new CountDownLatch(writes);
final InputStream in = new BufferedInputStream(client.getInputStream());
final long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
out.write(bytes);
out.write(count);
out.flush();
Assert.assertTrue(_lastEndPointLatch.await(1, TimeUnit.SECONDS));
_lastEndPoint.setIdleTimeout(5000);
new Thread()
{
@Override
public void run()
{
Thread.currentThread().setPriority(MAX_PRIORITY);
long last = -1;
int count = -1;
try
{
while (latch.getCount() > 0)
{
// Verify echo server to client
for (byte b0 : bytes)
{
int b = in.read();
Assert.assertThat(b, greaterThan(0));
assertEquals(0xff & b0, b);
}
count = 0;
int b = in.read();
while (b > 0 && b != '\n')
{
count = count * 10 + (b - '0');
b = in.read();
}
last = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
//if (latch.getCount()%1000==0)
// System.out.println(writes-latch.getCount());
latch.countDown();
}
}
catch (Throwable e)
{
long now = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
System.err.println("count=" + count);
System.err.println("latch=" + latch.getCount());
System.err.println("time=" + (now - start));
System.err.println("last=" + (now - last));
System.err.println("endp=" + _lastEndPoint);
System.err.println("conn=" + _lastEndPoint.getConnection());
e.printStackTrace();
}
}
}.start();
// Write client to server
for (int i = 1; i < writes; i++)
{
out.write(bytes);
out.write(Integer.toString(i).getBytes(StandardCharsets.ISO_8859_1));
out.write('\n');
if (i % 1000 == 0)
{
//System.err.println(i+"/"+writes);
out.flush();
}
Thread.yield();
}
out.flush();
long last = latch.getCount();
while (!latch.await(5, TimeUnit.SECONDS))
{
//System.err.println(latch.getCount());
if (latch.getCount() == last)
Assert.fail();
last = latch.getCount();
}
assertEquals(0, latch.getCount());
}
@Test
public void testWriteBlocked() throws Exception
{
Socket client = _scenario.newClient(_connector);
client.setSoTimeout(10000);
SocketChannel server = _connector.accept();
server.configureBlocking(false);
_manager.accept(server);
// Write client to server
_writeCount.set(10000);
String data = "Now is the time for all good men to come to the aid of the party";
client.getOutputStream().write(data.getBytes(StandardCharsets.UTF_8));
BufferedInputStream in = new BufferedInputStream(client.getInputStream());
int byteNum = 0;
try
{
for (int i = 0; i < _writeCount.get(); i++)
{
if (i % 1000 == 0)
TimeUnit.MILLISECONDS.sleep(200);
// Verify echo server to client
for (int j = 0; j < data.length(); j++)
{
char c = data.charAt(j);
int b = in.read();
byteNum++;
assertTrue(b > 0);
assertEquals("test-" + i + "/" + j, c, (char) b);
}
if (i == 0)
_lastEndPoint.setIdleTimeout(60000);
}
}
catch (SocketTimeoutException e)
{
System.err.println("SelectorManager.dump() = " + _manager.dump());
LOG.warn("Server: " + server);
LOG.warn("Error reading byte #" + byteNum, e);
throw e;
}
client.close();
for (int i = 0; i < 10; ++i)
{
if (server.isOpen())
Thread.sleep(10);
else
break;
}
assertFalse(server.isOpen());
}
// TODO make this test reliable
@Test
@Ignore
public void testRejectedExecution() throws Exception
{
_manager.stop();
_threadPool.stop();
final CountDownLatch latch = new CountDownLatch(1);
BlockingQueue<Runnable> q = new ArrayBlockingQueue<>(4);
_threadPool = new QueuedThreadPool(4, 4, 60000, q);
_manager = new SelectorManager(_threadPool, _scheduler, 1)
{
@Override
protected EndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey selectionKey) throws IOException
{
SocketChannelEndPoint endp = new SocketChannelEndPoint(channel, selector, selectionKey, getScheduler());
_lastEndPoint = endp;
_lastEndPointLatch.countDown();
return endp;
}
@Override
public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Object attachment) throws IOException
{
return new TestConnection(endpoint, latch, getExecutor(), _blockAt, _writeCount);
}
};
_threadPool.start();
_manager.start();
AtomicInteger timeout = new AtomicInteger();
AtomicInteger rejections = new AtomicInteger();
AtomicInteger echoed = new AtomicInteger();
CountDownLatch closed = new CountDownLatch(20);
for (int i = 0; i < 20; i++)
{
new Thread()
{
@Override
public void run()
{
try (Socket client = _scenario.newClient(_connector);)
{
client.setSoTimeout(5000);
SocketChannel server = _connector.accept();
server.configureBlocking(false);
_manager.accept(server);
// Write client to server
client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8));
client.getOutputStream().flush();
client.shutdownOutput();
// Verify echo server to client
for (char c : "HelloWorld".toCharArray())
{
int b = client.getInputStream().read();
assertTrue(b > 0);
assertEquals(c, (char) b);
}
assertEquals(-1, client.getInputStream().read());
echoed.incrementAndGet();
}
catch (SocketTimeoutException x)
{
x.printStackTrace();
timeout.incrementAndGet();
}
catch (Throwable x)
{
rejections.incrementAndGet();
}
finally
{
closed.countDown();
}
}
}.start();
}
// unblock the handling
latch.countDown();
// wait for all clients to complete or fail
closed.await();
// assert some clients must have been rejected
Assert.assertThat(rejections.get(), Matchers.greaterThan(0));
// but not all of them
Assert.assertThat(rejections.get(), Matchers.lessThan(20));
// none should have timed out
Assert.assertThat(timeout.get(), Matchers.equalTo(0));
// and the rest should have worked
Assert.assertThat(echoed.get(), Matchers.equalTo(20 - rejections.get()));
// and the selector is still working for new requests
try (Socket client = _scenario.newClient(_connector))
{
client.setSoTimeout(5000);
SocketChannel server = _connector.accept();
server.configureBlocking(false);
_manager.accept(server);
// Write client to server
client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8));
client.getOutputStream().flush();
client.shutdownOutput();
// Verify echo server to client
for (char c : "HelloWorld".toCharArray())
{
int b = client.getInputStream().read();
assertTrue(b > 0);
assertEquals(c, (char) b);
}
assertEquals(-1, client.getInputStream().read());
}
}
public class ScenarioSelectorManager extends SelectorManager
{
protected ScenarioSelectorManager(Executor executor, Scheduler scheduler)
{
super(executor, scheduler);
}
protected EndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey key) throws IOException
{
SocketChannelEndPoint endp = new SocketChannelEndPoint(channel, selector, key, getScheduler());
endp.setIdleTimeout(60000);
_lastEndPoint = endp;
_lastEndPointLatch.countDown();
return endp;
}
@Override
public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Object attachment) throws IOException
{
return _scenario.newConnection(channel, endpoint, getExecutor(), _blockAt, _writeCount);
}
}
public static class NormalScenario implements Scenario
{
@Override
public Socket newClient(ServerSocketChannel connector) throws IOException
{
return new Socket(connector.socket().getInetAddress(), connector.socket().getLocalPort());
}
@Override
public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Executor executor, AtomicInteger blockAt, AtomicInteger writeCount)
{
return new TestConnection(endpoint, executor, blockAt, writeCount);
}
@Override
public boolean supportsHalfCloses()
{
return true;
}
@Override
public String toString()
{
return "normal";
}
}
public static class SslScenario implements Scenario
{
private final NormalScenario _normalScenario;
private final SslContextFactory __sslCtxFactory = new SslContextFactory();
private final ByteBufferPool __byteBufferPool = new MappedByteBufferPool();
public SslScenario(NormalScenario normalScenario) throws Exception
{
_normalScenario = normalScenario;
File keystore = MavenTestingUtils.getTestResourceFile("keystore");
__sslCtxFactory.setKeyStorePath(keystore.getAbsolutePath());
__sslCtxFactory.setKeyStorePassword("storepwd");
__sslCtxFactory.setKeyManagerPassword("keypwd");
__sslCtxFactory.setEndpointIdentificationAlgorithm("");
__sslCtxFactory.start();
}
@Override
public Socket newClient(ServerSocketChannel connector) throws IOException
{
SSLSocket socket = __sslCtxFactory.newSslSocket();
socket.connect(connector.socket().getLocalSocketAddress());
return socket;
}
@Override
public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Executor executor, AtomicInteger blockAt, AtomicInteger writeCount)
{
SSLEngine engine = __sslCtxFactory.newSSLEngine();
engine.setUseClientMode(false);
SslConnection sslConnection = new SslConnection(__byteBufferPool, executor, endpoint, engine);
sslConnection.setRenegotiationAllowed(__sslCtxFactory.isRenegotiationAllowed());
sslConnection.setRenegotiationLimit(__sslCtxFactory.getRenegotiationLimit());
Connection appConnection = _normalScenario.newConnection(channel, sslConnection.getDecryptedEndPoint(), executor, blockAt, writeCount);
sslConnection.getDecryptedEndPoint().setConnection(appConnection);
return sslConnection;
}
@Override
public boolean supportsHalfCloses()
{
return false;
}
@Override
public String toString()
{
return "ssl";
}
}
@SuppressWarnings("Duplicates")
public static class TestConnection extends AbstractConnection
{
private static final Logger LOG = Log.getLogger(TestConnection.class);
volatile FutureCallback _blockingRead;
final AtomicInteger _blockAt;
final AtomicInteger _writeCount;
// volatile int _blockAt = 0;
ByteBuffer _in = BufferUtil.allocate(32 * 1024);
ByteBuffer _out = BufferUtil.allocate(32 * 1024);
long _last = -1;
final CountDownLatch _latch;
public TestConnection(EndPoint endp, Executor executor, AtomicInteger blockAt, AtomicInteger writeCount)
{
super(endp, executor);
_latch = null;
this._blockAt = blockAt;
this._writeCount = writeCount;
}
public TestConnection(EndPoint endp, CountDownLatch latch, Executor executor, AtomicInteger blockAt, AtomicInteger writeCount)
{
super(endp, executor);
_latch = latch;
this._blockAt = blockAt;
this._writeCount = writeCount;
}
@Override
public void onOpen()
{
super.onOpen();
fillInterested();
}
@Override
public void onFillInterestedFailed(Throwable cause)
{
Callback blocking = _blockingRead;
if (blocking != null)
{
_blockingRead = null;
blocking.failed(cause);
return;
}
super.onFillInterestedFailed(cause);
}
@Override
public void onFillable()
{
if (_latch != null)
{
try
{
_latch.await();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
Callback blocking = _blockingRead;
if (blocking != null)
{
_blockingRead = null;
blocking.succeeded();
return;
}
EndPoint _endp = getEndPoint();
try
{
_last = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
boolean progress = true;
while (progress)
{
progress = false;
// Fill the input buffer with everything available
BufferUtil.compact(_in);
if (BufferUtil.isFull(_in))
throw new IllegalStateException("FULL " + BufferUtil.toDetailString(_in));
int filled = _endp.fill(_in);
if (filled > 0)
progress = true;
// If the tests wants to block, then block
while (_blockAt.get() > 0 && _endp.isOpen() && _in.remaining() < _blockAt.get())
{
FutureCallback future = _blockingRead = new FutureCallback();
fillInterested();
future.get();
filled = _endp.fill(_in);
progress |= filled > 0;
}
// Copy to the out buffer
if (BufferUtil.hasContent(_in) && BufferUtil.append(_out, _in) > 0)
progress = true;
// Blocking writes
if (BufferUtil.hasContent(_out))
{
ByteBuffer out = _out.duplicate();
BufferUtil.clear(_out);
for (int i = 0; i < _writeCount.get(); i++)
{
FutureCallback blockingWrite = new FutureCallback();
_endp.write(blockingWrite, out.asReadOnlyBuffer());
blockingWrite.get();
}
progress = true;
}
// are we done?
if (_endp.isInputShutdown())
_endp.shutdownOutput();
}
if (_endp.isOpen())
fillInterested();
}
catch (ExecutionException e)
{
// Timeout does not close, so echo exception then shutdown
try
{
FutureCallback blockingWrite = new FutureCallback();
_endp.write(blockingWrite, BufferUtil.toBuffer("EE: " + BufferUtil.toString(_in)));
blockingWrite.get();
_endp.shutdownOutput();
}
catch (Exception e2)
{
// e2.printStackTrace();
}
}
catch (InterruptedException | EofException e)
{
LOG.info(e);
}
catch (Exception e)
{
LOG.warn(e);
}
}
}
}

View File

@ -18,110 +18,46 @@
package org.eclipse.jetty.io;
import java.io.File;
import java.io.IOException;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SocketChannel;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
import javax.net.ssl.SSLSocket;
import org.eclipse.jetty.io.ssl.SslConnection;
import org.eclipse.jetty.toolchain.test.JDK;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.toolchain.test.annotation.Stress;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import static org.hamcrest.Matchers.greaterThan;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import java.io.File;
import java.nio.ByteBuffer;
public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
import org.eclipse.jetty.toolchain.test.JDK;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.Test;
public class SslEngineBehaviorTest
{
private static SslContextFactory __sslCtxFactory=new SslContextFactory();
private static ByteBufferPool __byteBufferPool = new MappedByteBufferPool();
private static SslContextFactory sslCtxFactory;
@BeforeClass
public static void initSslEngine() throws Exception
public static void startSsl() throws Exception
{
sslCtxFactory = new SslContextFactory();
File keystore = MavenTestingUtils.getTestResourceFile("keystore");
__sslCtxFactory.setKeyStorePath(keystore.getAbsolutePath());
__sslCtxFactory.setKeyStorePassword("storepwd");
__sslCtxFactory.setKeyManagerPassword("keypwd");
__sslCtxFactory.setEndpointIdentificationAlgorithm("");
__sslCtxFactory.start();
sslCtxFactory.setKeyStorePath(keystore.getAbsolutePath());
sslCtxFactory.setKeyStorePassword("storepwd");
sslCtxFactory.setKeyManagerPassword("keypwd");
sslCtxFactory.setEndpointIdentificationAlgorithm("");
sslCtxFactory.start();
}
@Override
protected Socket newClient() throws IOException
@AfterClass
public static void stopSsl() throws Exception
{
SSLSocket socket = __sslCtxFactory.newSslSocket();
socket.connect(_connector.socket().getLocalSocketAddress());
return socket;
}
@Override
protected Connection newConnection(SelectableChannel channel, EndPoint endpoint)
{
SSLEngine engine = __sslCtxFactory.newSSLEngine();
engine.setUseClientMode(false);
SslConnection sslConnection = new SslConnection(__byteBufferPool, _threadPool, endpoint, engine);
sslConnection.setRenegotiationAllowed(__sslCtxFactory.isRenegotiationAllowed());
sslConnection.setRenegotiationLimit(__sslCtxFactory.getRenegotiationLimit());
Connection appConnection = super.newConnection(channel,sslConnection.getDecryptedEndPoint());
sslConnection.getDecryptedEndPoint().setConnection(appConnection);
return sslConnection;
}
@Test
@Override
public void testEcho() throws Exception
{
super.testEcho();
}
@Ignore // SSL does not do half closes
@Override
public void testShutdown() throws Exception
{
}
@Test
@Override
public void testWriteBlocked() throws Exception
{
super.testWriteBlocked();
}
@Override
public void testReadBlocked() throws Exception
{
super.testReadBlocked();
}
@Override
public void testIdle() throws Exception
{
super.testIdle();
}
@Test
@Override
@Stress("Requires a relatively idle (network wise) environment")
public void testStress() throws Exception
{
super.testStress();
sslCtxFactory.stop();
}
@Test
@ -129,8 +65,8 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
{
Assume.assumeFalse(JDK.IS_9);
SSLEngine server = __sslCtxFactory.newSSLEngine();
SSLEngine client = __sslCtxFactory.newSSLEngine();
SSLEngine server = sslCtxFactory.newSSLEngine();
SSLEngine client = sslCtxFactory.newSSLEngine();
ByteBuffer netC2S = ByteBuffer.allocate(server.getSession().getPacketBufferSize());
ByteBuffer netS2C = ByteBuffer.allocate(server.getSession().getPacketBufferSize());
@ -143,7 +79,7 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
// start the client
client.setUseClientMode(true);
client.beginHandshake();
Assert.assertEquals(HandshakeStatus.NEED_WRAP,client.getHandshakeStatus());
Assert.assertEquals(SSLEngineResult.HandshakeStatus.NEED_WRAP,client.getHandshakeStatus());
// what if we try an unwrap?
netS2C.flip();
@ -152,7 +88,7 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
assertEquals(SSLEngineResult.Status.OK,result.getStatus());
assertEquals(0,result.bytesConsumed());
assertEquals(0,result.bytesProduced());
assertEquals(HandshakeStatus.NEED_WRAP,result.getHandshakeStatus());
assertEquals(SSLEngineResult.HandshakeStatus.NEED_WRAP,result.getHandshakeStatus());
netS2C.clear();
// do the needed WRAP of empty buffer
@ -161,14 +97,14 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
assertEquals(SSLEngineResult.Status.OK,result.getStatus());
assertEquals(0,result.bytesConsumed());
assertThat(result.bytesProduced(),greaterThan(0));
assertEquals(HandshakeStatus.NEED_UNWRAP,result.getHandshakeStatus());
assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP,result.getHandshakeStatus());
netC2S.flip();
assertEquals(netC2S.remaining(),result.bytesProduced());
// start the server
server.setUseClientMode(false);
server.beginHandshake();
Assert.assertEquals(HandshakeStatus.NEED_UNWRAP,server.getHandshakeStatus());
Assert.assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP,server.getHandshakeStatus());
// what if we try a needless wrap?
serverOut.put(BufferUtil.toBuffer("Hello World"));
@ -178,14 +114,14 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
assertEquals(SSLEngineResult.Status.OK,result.getStatus());
assertEquals(0,result.bytesConsumed());
assertEquals(0,result.bytesProduced());
assertEquals(HandshakeStatus.NEED_UNWRAP,result.getHandshakeStatus());
assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP,result.getHandshakeStatus());
// Do the needed unwrap, to an empty buffer
result=server.unwrap(netC2S,BufferUtil.EMPTY_BUFFER);
assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW,result.getStatus());
assertEquals(0,result.bytesConsumed());
assertEquals(0,result.bytesProduced());
assertEquals(HandshakeStatus.NEED_UNWRAP,result.getHandshakeStatus());
assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP,result.getHandshakeStatus());
// Do the needed unwrap, to a full buffer
serverIn.position(serverIn.limit());
@ -193,7 +129,7 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW,result.getStatus());
assertEquals(0,result.bytesConsumed());
assertEquals(0,result.bytesProduced());
assertEquals(HandshakeStatus.NEED_UNWRAP,result.getHandshakeStatus());
assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP,result.getHandshakeStatus());
// Do the needed unwrap, to an empty buffer
serverIn.clear();
@ -201,10 +137,10 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
assertEquals(SSLEngineResult.Status.OK,result.getStatus());
assertThat(result.bytesConsumed(),greaterThan(0));
assertEquals(0,result.bytesProduced());
assertEquals(HandshakeStatus.NEED_TASK,result.getHandshakeStatus());
assertEquals(SSLEngineResult.HandshakeStatus.NEED_TASK,result.getHandshakeStatus());
server.getDelegatedTask().run();
assertEquals(HandshakeStatus.NEED_WRAP,server.getHandshakeStatus());
assertEquals(SSLEngineResult.HandshakeStatus.NEED_WRAP,server.getHandshakeStatus());
}
}

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enable JAAS for deployed webapplications.

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enable JASPI authentication for deployed webapplications.

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables remote RMI access to JMX

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables JMX instrumentation for server beans and
enables JMX agent.

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Adds the Jetty JNDI implementation to the classpath.

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Adds the javax.mail implementation to the classpath.

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables test setup

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables an unassembled maven webapp to run in a jetty distro

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Memcache cache for SessionData

View File

@ -1,3 +1,5 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables NoSql session management with a MongoDB driver.

Some files were not shown because too many files have changed in this diff Show More