Merge branch 'jetty-9.4.x' into jetty-9.4.x-1027-Multipart
This commit is contained in:
commit
8312f4567b
|
@ -41,8 +41,9 @@ def getFullBuild(jdk, os) {
|
||||||
maven: 'maven3',
|
maven: 'maven3',
|
||||||
jdk: "$jdk",
|
jdk: "$jdk",
|
||||||
publisherStrategy: 'EXPLICIT',
|
publisherStrategy: 'EXPLICIT',
|
||||||
|
globalMavenSettingsConfig: 'oss-settings.xml',
|
||||||
mavenLocalRepo: "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}") {
|
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',
|
maven: 'maven3',
|
||||||
jdk: "$jdk",
|
jdk: "$jdk",
|
||||||
publisherStrategy: 'EXPLICIT',
|
publisherStrategy: 'EXPLICIT',
|
||||||
|
globalMavenSettingsConfig: 'oss-settings.xml',
|
||||||
mavenLocalRepo: "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}") {
|
mavenLocalRepo: "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}") {
|
||||||
sh "mvn -V -B javadoc:javadoc -T5"
|
sh "mvn -V -B javadoc:javadoc -T5"
|
||||||
}
|
}
|
||||||
|
@ -83,6 +85,7 @@ def getFullBuild(jdk, os) {
|
||||||
maven: 'maven3',
|
maven: 'maven3',
|
||||||
jdk: "$jdk",
|
jdk: "$jdk",
|
||||||
publisherStrategy: 'EXPLICIT',
|
publisherStrategy: 'EXPLICIT',
|
||||||
|
globalMavenSettingsConfig: 'oss-settings.xml',
|
||||||
mavenLocalRepo: "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}") {
|
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}"
|
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',
|
maven: 'maven3',
|
||||||
jdk: "$jdk",
|
jdk: "$jdk",
|
||||||
publisherStrategy: 'EXPLICIT',
|
publisherStrategy: 'EXPLICIT',
|
||||||
|
globalMavenSettingsConfig: 'oss-settings.xml',
|
||||||
mavenLocalRepo: "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}") {
|
mavenLocalRepo: "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}") {
|
||||||
sh "mvn -V -B -Pcompact3 clean install -T5"
|
sh "mvn -V -B -Pcompact3 clean install -T5"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables use of the apache implementation of JSP
|
Enables use of the apache implementation of JSP
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables the apache version of JSTL
|
Enables the apache version of JSTL
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Selects an ALPN (Application Layer Protocol Negotiation) implementation by java version.
|
Selects an ALPN (Application Layer Protocol Negotiation) implementation by java version.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[files]
|
||||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[files]
|
||||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[files]
|
||||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[files]
|
||||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[files]
|
||||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.2.v20141202|lib/alpn/alpn-boot-8.1.2.v20141202.jar
|
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.2.v20141202|lib/alpn/alpn-boot-8.1.2.v20141202.jar
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[files]
|
||||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.3.v20150130|lib/alpn/alpn-boot-8.1.3.v20150130.jar
|
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.3.v20150130|lib/alpn/alpn-boot-8.1.3.v20150130.jar
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[files]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
|
[depend]
|
||||||
|
alpn-impl/alpn-9
|
|
@ -0,0 +1,4 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
|
[depend]
|
||||||
|
alpn-impl/alpn-9
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Provides ALPN support for JDK 8, modifying the sun.security.ssl
|
Provides ALPN support for JDK 8, modifying the sun.security.ssl
|
||||||
classes and adding them to the JVM boot classpath.
|
classes and adding them to the JVM boot classpath.
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Provides support for ALPN based on JDK 9 APIs.
|
Provides support for ALPN based on JDK 9+ APIs.
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
lib/jetty-alpn-java-server-${jetty.version}.jar
|
lib/jetty-alpn-java-server-${jetty.version}.jar
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables the ALPN (Application Layer Protocol Negotiation) TLS extension.
|
Enables the ALPN (Application Layer Protocol Negotiation) TLS extension.
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables Annotation scanning for deployed webapplications.
|
Enables Annotation scanning for deployed webapplications.
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
<version>3.0.0-M1</version>
|
<version>3.0.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<skip>true</skip>
|
<skip>true</skip>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Jetty setup to support Weld/CDI2 with WELD inside the webapp
|
Jetty setup to support Weld/CDI2 with WELD inside the webapp
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Experimental CDI/Weld integration
|
Experimental CDI/Weld integration
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Experimental CDI/Weld integration
|
Experimental CDI/Weld integration
|
||||||
Deprecated in favour of cdi2 module.
|
Deprecated in favour of cdi2 module.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Adds the Jetty HTTP client to the server classpath.
|
Adds the Jetty HTTP client to the server classpath.
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
package org.eclipse.jetty.client;
|
package org.eclipse.jetty.client;
|
||||||
|
|
||||||
import java.nio.channels.Selector;
|
import java.nio.channels.Selector;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
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.Server;
|
||||||
import org.eclipse.jetty.server.ServerConnector;
|
import org.eclipse.jetty.server.ServerConnector;
|
||||||
import org.eclipse.jetty.util.SocketAddressResolver;
|
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.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
@RunWith(Parameterized.class)
|
||||||
public class LivelockTest
|
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 Server server;
|
||||||
private ServerConnector connector;
|
private ServerConnector connector;
|
||||||
private HttpClient client;
|
private HttpClient client;
|
||||||
|
@ -73,7 +98,7 @@ public class LivelockTest
|
||||||
// ManagedSelectors that submit themselves in an attempt to cause a live lock
|
// ManagedSelectors that submit themselves in an attempt to cause a live lock
|
||||||
// as there will always be an action available to run.
|
// as there will always be an action available to run.
|
||||||
|
|
||||||
int count = 25;
|
int count = 5;
|
||||||
HttpClientTransport transport = new HttpClientTransportOverHTTP(1);
|
HttpClientTransport transport = new HttpClientTransportOverHTTP(1);
|
||||||
client = new HttpClient(transport, null);
|
client = new HttpClient(transport, null);
|
||||||
client.setMaxConnectionsPerDestination(2 * count);
|
client.setMaxConnectionsPerDestination(2 * count);
|
||||||
|
@ -88,34 +113,21 @@ public class LivelockTest
|
||||||
|
|
||||||
AtomicBoolean busy = new AtomicBoolean(true);
|
AtomicBoolean busy = new AtomicBoolean(true);
|
||||||
|
|
||||||
|
if (clientLiveLock)
|
||||||
|
{
|
||||||
ManagedSelector clientSelector = client.getContainedBeans(ManagedSelector.class).stream().findAny().get();
|
ManagedSelector clientSelector = client.getContainedBeans(ManagedSelector.class).stream().findAny().get();
|
||||||
ManagedSelector.SelectorUpdate clientLivelock = new ManagedSelector.SelectorUpdate()
|
busyLiveLock(busy, clientSelector);
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void update(Selector selector)
|
|
||||||
{
|
|
||||||
sleep(10);
|
|
||||||
if (busy.get())
|
|
||||||
clientSelector.submit(this);
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
clientSelector.submit(clientLivelock);
|
|
||||||
|
|
||||||
|
if (serverLiveLock)
|
||||||
|
{
|
||||||
ManagedSelector serverSelector = connector.getContainedBeans(ManagedSelector.class).stream().findAny().get();
|
ManagedSelector serverSelector = connector.getContainedBeans(ManagedSelector.class).stream().findAny().get();
|
||||||
ManagedSelector.SelectorUpdate serverLivelock = new ManagedSelector.SelectorUpdate()
|
busyLiveLock(busy, serverSelector);
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void update(Selector selector)
|
|
||||||
{
|
|
||||||
sleep(10);
|
|
||||||
if (busy.get())
|
|
||||||
serverSelector.submit(this);
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
serverSelector.submit(serverLivelock);
|
|
||||||
|
|
||||||
int requestRate = 5;
|
int requestRate = 5;
|
||||||
long pause = 1000 / requestRate;
|
long pause = 1000 / requestRate;
|
||||||
|
Logger clientLog = Log.getLogger("TESTClient");
|
||||||
CountDownLatch latch = new CountDownLatch(count);
|
CountDownLatch latch = new CountDownLatch(count);
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
|
@ -125,6 +137,13 @@ public class LivelockTest
|
||||||
{
|
{
|
||||||
if (result.isSucceeded() && result.getResponse().getStatus() == HttpStatus.OK_200)
|
if (result.isSucceeded() && result.getResponse().getStatus() == HttpStatus.OK_200)
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(result.getRequestFailure() != null)
|
||||||
|
clientLog.warn(result.getRequestFailure());
|
||||||
|
if(result.getResponseFailure() != null)
|
||||||
|
clientLog.warn(result.getResponseFailure());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
sleep(pause);
|
sleep(pause);
|
||||||
}
|
}
|
||||||
|
@ -134,11 +153,26 @@ public class LivelockTest
|
||||||
busy.set(false);
|
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
|
try
|
||||||
{
|
{
|
||||||
Thread.sleep(time);
|
TimeUnit.MILLISECONDS.sleep(millis);
|
||||||
}
|
}
|
||||||
catch (InterruptedException x)
|
catch (InterruptedException x)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
class=org.eclipse.jetty.util.log.StdErrLog
|
||||||
#org.eclipse.jetty.LEVEL=DEBUG
|
#org.eclipse.jetty.LEVEL=INFO
|
||||||
#org.eclipse.jetty.client.LEVEL=DEBUG
|
#org.eclipse.jetty.client.LEVEL=DEBUG
|
||||||
#org.eclipse.jetty.io.ChannelEndPoint.LEVEL=DEBUG
|
#org.eclipse.jetty.io.ChannelEndPoint.LEVEL=DEBUG
|
||||||
#org.eclipse.jetty.http.LEVEL=DEBUG
|
#org.eclipse.jetty.http.LEVEL=DEBUG
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables webapplication deployment from the webapps directory.
|
Enables webapplication deployment from the webapps directory.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables Deployer to apply common configuration to all webapp deployments
|
Enables Deployer to apply common configuration to all webapp deployments
|
||||||
|
|
||||||
|
|
|
@ -398,29 +398,37 @@
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<dependencies>
|
<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>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-home</artifactId>
|
<artifactId>jetty-home</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>test-jetty-webapp</artifactId>
|
<artifactId>test-jetty-webapp</artifactId>
|
||||||
<type>war</type>
|
<type>war</type>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>test-proxy-webapp</artifactId>
|
<artifactId>test-proxy-webapp</artifactId>
|
||||||
<type>war</type>
|
<type>war</type>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty.example-async-rest</groupId>
|
<groupId>org.eclipse.jetty.example-async-rest</groupId>
|
||||||
<artifactId>example-async-rest-webapp</artifactId>
|
<artifactId>example-async-rest-webapp</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<type>war</type>
|
<type>war</type>
|
||||||
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
@ -428,6 +436,7 @@
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<classifier>html</classifier>
|
<classifier>html</classifier>
|
||||||
<type>zip</type>
|
<type>zip</type>
|
||||||
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -59,10 +59,6 @@ System Properties:
|
||||||
Properties:
|
Properties:
|
||||||
-----------
|
-----------
|
||||||
java.version = 1.8.0_92
|
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:
|
Jetty Server Classpath:
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
|
@ -59,10 +59,6 @@ System Properties:
|
||||||
Properties:
|
Properties:
|
||||||
-----------
|
-----------
|
||||||
java.version = 1.8.0_92
|
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:
|
Jetty Server Classpath:
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
|
@ -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 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.
|
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.
|
When a module is activated, a number of properties are set by default.
|
||||||
To view these defaults, open up the associated ini file.
|
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.
|
Listed in the ini file is the associated module file and any properties that can be set.
|
||||||
|
|
|
@ -719,10 +719,10 @@ This is _not_ a recommended usage.
|
||||||
____
|
____
|
||||||
|
|
||||||
[[conscrypt]]
|
[[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].
|
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 is very straightforward process - simply instantiate an instance of Conscrypt's `OpenSSLProvider` and set `Conscrypt` as a provider for Jetty's `SslContextFactory`:
|
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}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
|
|
@ -75,6 +75,17 @@ URI uri = URI.create("http://domain.com/secure");
|
||||||
auth.addAuthenticationResult(new BasicAuthentication.BasicResult(uri, "username", "password"));
|
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.
|
See also the link:#http-client-proxy-authentication[proxy authentication section] for further information about how authentication works with HTTP proxies.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Adds the FastCGI implementation to the classpath.
|
Adds the FastCGI implementation to the classpath.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables GCloud Datastore API and implementation
|
Enables GCloud Datastore API and implementation
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Control GCloud API classpath
|
Control GCloud API classpath
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables GCloudDatastore session management.
|
Enables GCloudDatastore session management.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables session data store in an embedded Hazelcast Map
|
Enables session data store in an embedded Hazelcast Map
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables session data store in a remote Hazelcast Map
|
Enables session data store in a remote Hazelcast Map
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Installs the Conscrypt JSSE provider
|
Installs the Conscrypt JSSE provider
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Deploys the Hawtio console as a webapplication.
|
Deploys the Hawtio console as a webapplication.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Deploys the JAMon webapplication
|
Deploys the JAMon webapplication
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Deploys the Jminix JMX Console within the server
|
Deploys the Jminix JMX Console within the server
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Deploys the Jolokia console as a web application.
|
Deploys the Jolokia console as a web application.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables JSP for all webapplications deployed on the server.
|
Enables JSP for all webapplications deployed on the server.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables JSTL for all webapplications deployed on the server
|
Enables JSTL for all webapplications deployed on the server
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables the unix setUID configuration so that the server
|
Enables the unix setUID configuration so that the server
|
||||||
may be started as root to open privileged ports/files before
|
may be started as root to open privileged ports/files before
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
This module causes jetty to stop immediately after starting. This is good for testing configuration and/or precompiling quickstart webapps
|
This module causes jetty to stop immediately after starting. This is good for testing configuration and/or precompiling quickstart webapps
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
|
||||||
import static org.eclipse.jetty.http.HttpTokens.CARRIAGE_RETURN;
|
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.LINE_FEED;
|
||||||
import static org.eclipse.jetty.http.HttpTokens.SPACE;
|
import static org.eclipse.jetty.http.HttpTokens.SPACE;
|
||||||
import static org.eclipse.jetty.http.HttpTokens.TAB;
|
import static org.eclipse.jetty.http.HttpTokens.TAB;
|
||||||
|
@ -1074,7 +1075,7 @@ public class HttpParser
|
||||||
throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Header Folding");
|
throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Header Folding");
|
||||||
|
|
||||||
// header value without name - continuation?
|
// header value without name - continuation?
|
||||||
if (_valueString==null)
|
if (_valueString==null || _valueString.isEmpty())
|
||||||
{
|
{
|
||||||
_string.setLength(0);
|
_string.setLength(0);
|
||||||
_length=0;
|
_length=0;
|
||||||
|
@ -1166,10 +1167,6 @@ public class HttpParser
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
// now handle the ch
|
|
||||||
if (b<HttpTokens.SPACE)
|
|
||||||
throw new BadMessageException();
|
|
||||||
|
|
||||||
// process previous header
|
// process previous header
|
||||||
if (_state==State.HEADER)
|
if (_state==State.HEADER)
|
||||||
parsedHeader();
|
parsedHeader();
|
||||||
|
@ -1266,43 +1263,31 @@ public class HttpParser
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IN_NAME:
|
case IN_NAME:
|
||||||
if (b>HttpTokens.SPACE && b!=HttpTokens.COLON)
|
switch(b)
|
||||||
{
|
{
|
||||||
if (_header!=null)
|
case SPACE:
|
||||||
{
|
case TAB:
|
||||||
setString(_header.asString());
|
//Ignore trailing whitespaces ?
|
||||||
_header=null;
|
if (!complianceViolation(HttpComplianceSection.NO_WS_AFTER_FIELD_NAME,null))
|
||||||
_headerString=null;
|
|
||||||
}
|
|
||||||
|
|
||||||
_string.append((char)b);
|
|
||||||
_length=_string.length();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallthrough
|
|
||||||
|
|
||||||
case WS_AFTER_NAME:
|
|
||||||
if (b==HttpTokens.COLON)
|
|
||||||
{
|
|
||||||
if (_headerString==null)
|
|
||||||
{
|
{
|
||||||
_headerString=takeString();
|
_headerString=takeString();
|
||||||
_header=HttpHeader.CACHE.get(_headerString);
|
_header=HttpHeader.CACHE.get(_headerString);
|
||||||
}
|
|
||||||
_length=-1;
|
_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);
|
setState(FieldState.VALUE);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
if (b==HttpTokens.LINE_FEED)
|
case LINE_FEED:
|
||||||
{
|
|
||||||
if (_headerString==null)
|
|
||||||
{
|
|
||||||
_headerString=takeString();
|
_headerString=takeString();
|
||||||
_header=HttpHeader.CACHE.get(_headerString);
|
_header=HttpHeader.CACHE.get(_headerString);
|
||||||
}
|
|
||||||
_string.setLength(0);
|
_string.setLength(0);
|
||||||
_valueString="";
|
_valueString="";
|
||||||
_length=-1;
|
_length=-1;
|
||||||
|
@ -1312,57 +1297,70 @@ public class HttpParser
|
||||||
setState(FieldState.FIELD);
|
setState(FieldState.FIELD);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//Ignore trailing whitespaces
|
|
||||||
if (b==HttpTokens.SPACE && !complianceViolation(HttpComplianceSection.NO_WS_AFTER_FIELD_NAME,null))
|
|
||||||
{
|
|
||||||
setState(FieldState.WS_AFTER_NAME);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalCharacterException(_state,b,buffer);
|
throw new IllegalCharacterException(_state,b,buffer);
|
||||||
|
|
||||||
case VALUE:
|
default:
|
||||||
if (b>HttpTokens.SPACE || b<0)
|
if (b<0)
|
||||||
{
|
throw new IllegalCharacterException(_state,b,buffer);
|
||||||
_string.append((char)(0xff&b));
|
|
||||||
|
_string.append((char)b);
|
||||||
_length=_string.length();
|
_length=_string.length();
|
||||||
setState(FieldState.IN_VALUE);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b==HttpTokens.SPACE || b==HttpTokens.TAB)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (b==HttpTokens.LINE_FEED)
|
case WS_AFTER_NAME:
|
||||||
|
|
||||||
|
switch(b)
|
||||||
{
|
{
|
||||||
|
case SPACE:
|
||||||
|
case TAB:
|
||||||
|
break;
|
||||||
|
|
||||||
|
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:
|
||||||
|
switch(b)
|
||||||
|
{
|
||||||
|
case LINE_FEED:
|
||||||
_string.setLength(0);
|
_string.setLength(0);
|
||||||
_valueString="";
|
_valueString="";
|
||||||
_length=-1;
|
_length=-1;
|
||||||
|
|
||||||
setState(FieldState.FIELD);
|
setState(FieldState.FIELD);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
throw new IllegalCharacterException(_state,b,buffer);
|
|
||||||
|
|
||||||
case IN_VALUE:
|
case SPACE:
|
||||||
if (b>=HttpTokens.SPACE || b<0 || b==HttpTokens.TAB)
|
case TAB:
|
||||||
{
|
break;
|
||||||
if (_valueString!=null)
|
|
||||||
{
|
default:
|
||||||
setString(_valueString);
|
|
||||||
_valueString=null;
|
|
||||||
_field=null;
|
|
||||||
}
|
|
||||||
_string.append((char)(0xff&b));
|
_string.append((char)(0xff&b));
|
||||||
if (b>HttpTokens.SPACE || b<0)
|
|
||||||
_length=_string.length();
|
_length=_string.length();
|
||||||
|
setState(FieldState.IN_VALUE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
if (b==HttpTokens.LINE_FEED)
|
case IN_VALUE:
|
||||||
|
switch(b)
|
||||||
{
|
{
|
||||||
|
case LINE_FEED:
|
||||||
if (_length > 0)
|
if (_length > 0)
|
||||||
{
|
{
|
||||||
_valueString=takeString();
|
_valueString=takeString();
|
||||||
|
@ -1370,9 +1368,18 @@ public class HttpParser
|
||||||
}
|
}
|
||||||
setState(FieldState.FIELD);
|
setState(FieldState.FIELD);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalCharacterException(_state,b,buffer);
|
case SPACE:
|
||||||
|
case TAB:
|
||||||
|
_string.append((char)(0xff&b));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
_string.append((char)(0xff&b));
|
||||||
|
_length=_string.length();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException(_state.toString());
|
throw new IllegalStateException(_state.toString());
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.http;
|
package org.eclipse.jetty.http;
|
||||||
|
|
||||||
|
import static org.eclipse.jetty.http.HttpComplianceSection.NO_FIELD_FOLDING;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -261,6 +262,8 @@ public class HttpParserTest
|
||||||
"Host: localhost\r\n" +
|
"Host: localhost\r\n" +
|
||||||
"Name: value\r\n" +
|
"Name: value\r\n" +
|
||||||
" extra\r\n" +
|
" extra\r\n" +
|
||||||
|
"Name2: \r\n" +
|
||||||
|
"\tvalue2\r\n" +
|
||||||
"\r\n");
|
"\r\n");
|
||||||
|
|
||||||
HttpParser.RequestHandler handler = new Handler();
|
HttpParser.RequestHandler handler = new Handler();
|
||||||
|
@ -270,10 +273,12 @@ public class HttpParserTest
|
||||||
Assert.assertThat(_bad, Matchers.nullValue());
|
Assert.assertThat(_bad, Matchers.nullValue());
|
||||||
Assert.assertEquals("Host", _hdr[0]);
|
Assert.assertEquals("Host", _hdr[0]);
|
||||||
Assert.assertEquals("localhost", _val[0]);
|
Assert.assertEquals("localhost", _val[0]);
|
||||||
|
Assert.assertEquals(2, _headers);
|
||||||
Assert.assertEquals("Name", _hdr[1]);
|
Assert.assertEquals("Name", _hdr[1]);
|
||||||
Assert.assertEquals("value extra", _val[1]);
|
Assert.assertEquals("value extra", _val[1]);
|
||||||
Assert.assertEquals(1, _headers);
|
Assert.assertEquals("Name2", _hdr[2]);
|
||||||
Assert.assertThat(_complianceViolation, contains(HttpComplianceSection.NO_FIELD_FOLDING));
|
Assert.assertEquals("value2", _val[2]);
|
||||||
|
Assert.assertThat(_complianceViolation, contains(NO_FIELD_FOLDING,NO_FIELD_FOLDING));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -399,7 +404,7 @@ public class HttpParserTest
|
||||||
ByteBuffer buffer = BufferUtil.toBuffer(
|
ByteBuffer buffer = BufferUtil.toBuffer(
|
||||||
"HTTP/1.1 204 No Content\r\n" +
|
"HTTP/1.1 204 No Content\r\n" +
|
||||||
"Access-Control-Allow-Headers : Origin\r\n" +
|
"Access-Control-Allow-Headers : Origin\r\n" +
|
||||||
"Other: value\r\n" +
|
"Other\t : value\r\n" +
|
||||||
"\r\n");
|
"\r\n");
|
||||||
|
|
||||||
HttpParser.ResponseHandler handler = new Handler();
|
HttpParser.ResponseHandler handler = new Handler();
|
||||||
|
@ -422,7 +427,7 @@ public class HttpParserTest
|
||||||
Assert.assertEquals("Other", _hdr[1]);
|
Assert.assertEquals("Other", _hdr[1]);
|
||||||
Assert.assertEquals("value", _val[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
|
@Test
|
||||||
|
@ -709,7 +714,9 @@ public class HttpParserTest
|
||||||
public void testBadHeaderEncoding() throws Exception
|
public void testBadHeaderEncoding() throws Exception
|
||||||
{
|
{
|
||||||
ByteBuffer buffer = BufferUtil.toBuffer(
|
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.RequestHandler handler = new Handler();
|
||||||
HttpParser parser = new HttpParser(handler);
|
HttpParser parser = new HttpParser(handler);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
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.hpack.LEVEL=INFO
|
||||||
#org.eclipse.jetty.http2.LEVEL=DEBUG
|
#org.eclipse.jetty.http2.LEVEL=DEBUG
|
||||||
#org.eclipse.jetty.io.ssl.LEVEL=DEBUG
|
#org.eclipse.jetty.io.ssl.LEVEL=DEBUG
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables HTTP2 protocol support on the TLS(SSL) Connector,
|
Enables HTTP2 protocol support on the TLS(SSL) Connector,
|
||||||
using the ALPN extension to select which protocol to use.
|
using the ALPN extension to select which protocol to use.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables the HTTP2C protocol on the HTTP Connector
|
Enables the HTTP2C protocol on the HTTP Connector
|
||||||
The connector will accept both HTTP/1 and HTTP/2 connections.
|
The connector will accept both HTTP/1 and HTTP/2 connections.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables session data store in a local Infinispan cache
|
Enables session data store in a local Infinispan cache
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables session data store in a local Infinispan cache
|
Enables session data store in a local Infinispan cache
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables session data store in a remote Infinispan cache
|
Enables session data store in a remote Infinispan cache
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables session data store in a remote Infinispan cache
|
Enables session data store in a remote Infinispan cache
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,8 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint
|
||||||
|
|
||||||
protected final void shutdownInput()
|
protected final void shutdownInput()
|
||||||
{
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("shutdownInput {}",this);
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
State s = _state.get();
|
State s = _state.get();
|
||||||
|
@ -114,6 +116,8 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint
|
||||||
@Override
|
@Override
|
||||||
public final void shutdownOutput()
|
public final void shutdownOutput()
|
||||||
{
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("shutdownOutput {}",this);
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
State s = _state.get();
|
State s = _state.get();
|
||||||
|
@ -166,11 +170,15 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint
|
||||||
@Override
|
@Override
|
||||||
public final void close()
|
public final void close()
|
||||||
{
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("close {}",this);
|
||||||
close(null);
|
close(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final void close(Throwable failure)
|
protected final void close(Throwable failure)
|
||||||
{
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("close({}) {}",failure,this);
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
State s = _state.get();
|
State s = _state.get();
|
||||||
|
|
|
@ -42,7 +42,6 @@ import java.util.concurrent.RejectedExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
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.ContainerLifeCycle;
|
||||||
import org.eclipse.jetty.util.component.Dumpable;
|
import org.eclipse.jetty.util.component.Dumpable;
|
||||||
import org.eclipse.jetty.util.component.DumpableCollection;
|
import org.eclipse.jetty.util.component.DumpableCollection;
|
||||||
|
@ -246,16 +245,15 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable
|
||||||
@Override
|
@Override
|
||||||
public void dump(Appendable out, String indent) throws IOException
|
public void dump(Appendable out, String indent) throws IOException
|
||||||
{
|
{
|
||||||
|
List<String> keys;
|
||||||
|
List<SelectorUpdate> updates;
|
||||||
Selector selector = _selector;
|
Selector selector = _selector;
|
||||||
List<String> keys = null;
|
|
||||||
List<SelectorUpdate> updates = null;
|
|
||||||
if (selector != null && selector.isOpen())
|
if (selector != null && selector.isOpen())
|
||||||
{
|
{
|
||||||
DumpKeys dump = new DumpKeys();
|
DumpKeys dump = new DumpKeys();
|
||||||
String updatesAt;
|
String updatesAt = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now());
|
||||||
synchronized(ManagedSelector.this)
|
synchronized(ManagedSelector.this)
|
||||||
{
|
{
|
||||||
updatesAt = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now());
|
|
||||||
updates = new ArrayList<>(_updates);
|
updates = new ArrayList<>(_updates);
|
||||||
_updates.addFirst(dump);
|
_updates.addFirst(dump);
|
||||||
_selecting = false;
|
_selecting = false;
|
||||||
|
@ -385,6 +383,8 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Selector {} waiting on select", selector);
|
LOG.debug("Selector {} waiting on select", selector);
|
||||||
int selected = selector.select();
|
int selected = selector.select();
|
||||||
|
if (selected == 0)
|
||||||
|
selected = selector.selectNow();
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Selector {} woken up from select, {}/{} selected", selector, selected, selector.keys().size());
|
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();
|
_keys = selector.selectedKeys();
|
||||||
_cursor = _keys.iterator();
|
_cursor = _keys.isEmpty() ? Collections.emptyIterator() : _keys.iterator();
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Selector {} processing {} keys, {} updates", selector, _keys.size(), updates);
|
LOG.debug("Selector {} processing {} keys, {} updates", selector, _keys.size(), updates);
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,7 @@ import org.eclipse.jetty.util.thread.Invocable;
|
||||||
public class SslConnection extends AbstractConnection
|
public class SslConnection extends AbstractConnection
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(SslConnection.class);
|
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 List<SslHandshakeListener> handshakeListeners = new ArrayList<>();
|
||||||
private final ByteBufferPool _bufferPool;
|
private final ByteBufferPool _bufferPool;
|
||||||
|
@ -506,11 +507,12 @@ public class SslConnection extends AbstractConnection
|
||||||
}
|
}
|
||||||
else
|
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
|
// We can get here because the WriteFlusher might not see progress
|
||||||
// when it has just flushed the encrypted data, but not consumed anymore
|
// when it has just flushed the encrypted data, but not consumed anymore
|
||||||
// of the application buffers. This is mostly avoided by another iteration
|
// of the application buffers. This is mostly avoided by another iteration
|
||||||
// within DecryptedEndPoint flush(), but I cannot convince myself that
|
// within DecryptedEndPoint flush(), but this still occurs sometime on some
|
||||||
// this is never ever the case.
|
// tests on some systems??? More investigation is needed!
|
||||||
try_again = true;
|
try_again = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -526,12 +528,35 @@ public class SslConnection extends AbstractConnection
|
||||||
{
|
{
|
||||||
// don't bother writing, just notify of close
|
// don't bother writing, just notify of close
|
||||||
getWriteFlusher().onClose();
|
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
|
else
|
||||||
{
|
{
|
||||||
// Try again
|
// Don't recurse but get top caller to iterate
|
||||||
_runCompleteWrite.run();
|
__tryWriteAgain.set(Boolean.TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -293,9 +293,9 @@ public class ByteArrayEndPointTest
|
||||||
assertEquals("test", BufferUtil.toString(buffer));
|
assertEquals("test", BufferUtil.toString(buffer));
|
||||||
|
|
||||||
// Wait for a read timeout.
|
// Wait for a read timeout.
|
||||||
|
long start = System.nanoTime();
|
||||||
fcb = new FutureCallback();
|
fcb = new FutureCallback();
|
||||||
endp.fillInterested(fcb);
|
endp.fillInterested(fcb);
|
||||||
long start = System.nanoTime();
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
fcb.get();
|
fcb.get();
|
||||||
|
@ -308,40 +308,5 @@ public class ByteArrayEndPointTest
|
||||||
assertThat(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start), greaterThan(halfIdleTimeout));
|
assertThat(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start), greaterThan(halfIdleTimeout));
|
||||||
assertThat("Endpoint open", endp.isOpen(), is(true));
|
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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -43,7 +43,7 @@ import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class SelectChannelEndPointInterestsTest
|
public class SocketChannelEndPointInterestsTest
|
||||||
{
|
{
|
||||||
private QueuedThreadPool threadPool;
|
private QueuedThreadPool threadPool;
|
||||||
private Scheduler scheduler;
|
private Scheduler scheduler;
|
|
@ -23,25 +23,51 @@ import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.ServerSocketChannel;
|
||||||
|
import java.nio.channels.SocketChannel;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
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 SocketChannelEndPoint client;
|
||||||
public T server;
|
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
|
@Test
|
||||||
public void testClientServerExchange() throws Exception
|
public void testClientServerExchange() throws Exception
|
||||||
{
|
{
|
||||||
EndPointPair<T> c = newConnection();
|
EndPointPair c = newConnection();
|
||||||
ByteBuffer buffer = BufferUtil.allocate(4096);
|
ByteBuffer buffer = BufferUtil.allocate(4096);
|
||||||
|
|
||||||
// Client sends a request
|
// Client sends a request
|
||||||
|
@ -110,15 +136,12 @@ public abstract class EndPointTest<T extends EndPoint>
|
||||||
assertTrue(c.client.isOutputShutdown());
|
assertTrue(c.client.isOutputShutdown());
|
||||||
assertFalse(c.server.isOpen());
|
assertFalse(c.server.isOpen());
|
||||||
assertTrue(c.server.isOutputShutdown());
|
assertTrue(c.server.isOutputShutdown());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testClientClose() throws Exception
|
public void testClientClose() throws Exception
|
||||||
{
|
{
|
||||||
EndPointPair<T> c = newConnection();
|
EndPointPair c = newConnection();
|
||||||
ByteBuffer buffer = BufferUtil.allocate(4096);
|
ByteBuffer buffer = BufferUtil.allocate(4096);
|
||||||
|
|
||||||
c.client.flush(BufferUtil.toBuffer("request"));
|
c.client.flush(BufferUtil.toBuffer("request"));
|
|
@ -18,49 +18,832 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.io;
|
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.ServerSocketChannel;
|
||||||
import java.nio.channels.SocketChannel;
|
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 javax.net.ssl.SSLEngine;
|
||||||
import org.junit.BeforeClass;
|
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 interface Scenario
|
||||||
public static void open() throws Exception
|
|
||||||
{
|
{
|
||||||
connector = ServerSocketChannel.open();
|
Socket newClient(ServerSocketChannel connector) throws IOException;
|
||||||
connector.socket().bind(null);
|
|
||||||
|
Connection newConnection(SelectableChannel channel, EndPoint endPoint, Executor executor, AtomicInteger blockAt, AtomicInteger writeCount);
|
||||||
|
|
||||||
|
boolean supportsHalfCloses();
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@Parameterized.Parameters(name = "{0}")
|
||||||
public static void close() throws Exception
|
public static List<Object[]> data() throws Exception
|
||||||
{
|
{
|
||||||
connector.close();
|
List<Object[]> ret = new ArrayList<>();
|
||||||
connector=null;
|
|
||||||
|
NormalScenario normalScenario = new NormalScenario();
|
||||||
|
ret.add(new Object[]{normalScenario});
|
||||||
|
ret.add(new Object[]{new SslScenario(normalScenario)});
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public TestTracker tracker = new TestTracker();
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void stopManager() throws Exception
|
||||||
|
{
|
||||||
|
_scheduler.stop();
|
||||||
|
_manager.stop();
|
||||||
|
_threadPool.stop();
|
||||||
|
_connector.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEcho() throws Exception
|
||||||
|
{
|
||||||
|
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
|
@Override
|
||||||
protected EndPointPair<SocketChannelEndPoint> newConnection() throws Exception
|
public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Object attachment) throws IOException
|
||||||
{
|
{
|
||||||
EndPointPair<SocketChannelEndPoint> c = new EndPointPair<>();
|
return new TestConnection(endpoint, latch, getExecutor(), _blockAt, _writeCount);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
c.client=new SocketChannelEndPoint(SocketChannel.open(connector.socket().getLocalSocketAddress()),null,null,null);
|
_threadPool.start();
|
||||||
c.server=new SocketChannelEndPoint(connector.accept(),null,null,null);
|
_manager.start();
|
||||||
return c;
|
|
||||||
|
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
|
@Override
|
||||||
public void testClientClose() throws Exception
|
public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Object attachment) throws IOException
|
||||||
{
|
{
|
||||||
super.testClientClose();
|
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
|
@Override
|
||||||
public void testClientServerExchange() throws Exception
|
public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Executor executor, AtomicInteger blockAt, AtomicInteger writeCount)
|
||||||
{
|
{
|
||||||
super.testClientServerExchange();
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,110 +18,46 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.io;
|
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.hamcrest.Matchers.greaterThan;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertThat;
|
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 SslContextFactory sslCtxFactory;
|
||||||
private static ByteBufferPool __byteBufferPool = new MappedByteBufferPool();
|
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void initSslEngine() throws Exception
|
public static void startSsl() throws Exception
|
||||||
{
|
{
|
||||||
|
sslCtxFactory = new SslContextFactory();
|
||||||
File keystore = MavenTestingUtils.getTestResourceFile("keystore");
|
File keystore = MavenTestingUtils.getTestResourceFile("keystore");
|
||||||
__sslCtxFactory.setKeyStorePath(keystore.getAbsolutePath());
|
sslCtxFactory.setKeyStorePath(keystore.getAbsolutePath());
|
||||||
__sslCtxFactory.setKeyStorePassword("storepwd");
|
sslCtxFactory.setKeyStorePassword("storepwd");
|
||||||
__sslCtxFactory.setKeyManagerPassword("keypwd");
|
sslCtxFactory.setKeyManagerPassword("keypwd");
|
||||||
__sslCtxFactory.setEndpointIdentificationAlgorithm("");
|
sslCtxFactory.setEndpointIdentificationAlgorithm("");
|
||||||
__sslCtxFactory.start();
|
sslCtxFactory.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@AfterClass
|
||||||
protected Socket newClient() throws IOException
|
public static void stopSsl() throws Exception
|
||||||
{
|
{
|
||||||
SSLSocket socket = __sslCtxFactory.newSslSocket();
|
sslCtxFactory.stop();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -129,8 +65,8 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
|
||||||
{
|
{
|
||||||
Assume.assumeFalse(JDK.IS_9);
|
Assume.assumeFalse(JDK.IS_9);
|
||||||
|
|
||||||
SSLEngine server = __sslCtxFactory.newSSLEngine();
|
SSLEngine server = sslCtxFactory.newSSLEngine();
|
||||||
SSLEngine client = __sslCtxFactory.newSSLEngine();
|
SSLEngine client = sslCtxFactory.newSSLEngine();
|
||||||
|
|
||||||
ByteBuffer netC2S = ByteBuffer.allocate(server.getSession().getPacketBufferSize());
|
ByteBuffer netC2S = ByteBuffer.allocate(server.getSession().getPacketBufferSize());
|
||||||
ByteBuffer netS2C = ByteBuffer.allocate(server.getSession().getPacketBufferSize());
|
ByteBuffer netS2C = ByteBuffer.allocate(server.getSession().getPacketBufferSize());
|
||||||
|
@ -143,7 +79,7 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
|
||||||
// start the client
|
// start the client
|
||||||
client.setUseClientMode(true);
|
client.setUseClientMode(true);
|
||||||
client.beginHandshake();
|
client.beginHandshake();
|
||||||
Assert.assertEquals(HandshakeStatus.NEED_WRAP,client.getHandshakeStatus());
|
Assert.assertEquals(SSLEngineResult.HandshakeStatus.NEED_WRAP,client.getHandshakeStatus());
|
||||||
|
|
||||||
// what if we try an unwrap?
|
// what if we try an unwrap?
|
||||||
netS2C.flip();
|
netS2C.flip();
|
||||||
|
@ -152,7 +88,7 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
|
||||||
assertEquals(SSLEngineResult.Status.OK,result.getStatus());
|
assertEquals(SSLEngineResult.Status.OK,result.getStatus());
|
||||||
assertEquals(0,result.bytesConsumed());
|
assertEquals(0,result.bytesConsumed());
|
||||||
assertEquals(0,result.bytesProduced());
|
assertEquals(0,result.bytesProduced());
|
||||||
assertEquals(HandshakeStatus.NEED_WRAP,result.getHandshakeStatus());
|
assertEquals(SSLEngineResult.HandshakeStatus.NEED_WRAP,result.getHandshakeStatus());
|
||||||
netS2C.clear();
|
netS2C.clear();
|
||||||
|
|
||||||
// do the needed WRAP of empty buffer
|
// do the needed WRAP of empty buffer
|
||||||
|
@ -161,14 +97,14 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
|
||||||
assertEquals(SSLEngineResult.Status.OK,result.getStatus());
|
assertEquals(SSLEngineResult.Status.OK,result.getStatus());
|
||||||
assertEquals(0,result.bytesConsumed());
|
assertEquals(0,result.bytesConsumed());
|
||||||
assertThat(result.bytesProduced(),greaterThan(0));
|
assertThat(result.bytesProduced(),greaterThan(0));
|
||||||
assertEquals(HandshakeStatus.NEED_UNWRAP,result.getHandshakeStatus());
|
assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP,result.getHandshakeStatus());
|
||||||
netC2S.flip();
|
netC2S.flip();
|
||||||
assertEquals(netC2S.remaining(),result.bytesProduced());
|
assertEquals(netC2S.remaining(),result.bytesProduced());
|
||||||
|
|
||||||
// start the server
|
// start the server
|
||||||
server.setUseClientMode(false);
|
server.setUseClientMode(false);
|
||||||
server.beginHandshake();
|
server.beginHandshake();
|
||||||
Assert.assertEquals(HandshakeStatus.NEED_UNWRAP,server.getHandshakeStatus());
|
Assert.assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP,server.getHandshakeStatus());
|
||||||
|
|
||||||
// what if we try a needless wrap?
|
// what if we try a needless wrap?
|
||||||
serverOut.put(BufferUtil.toBuffer("Hello World"));
|
serverOut.put(BufferUtil.toBuffer("Hello World"));
|
||||||
|
@ -178,14 +114,14 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
|
||||||
assertEquals(SSLEngineResult.Status.OK,result.getStatus());
|
assertEquals(SSLEngineResult.Status.OK,result.getStatus());
|
||||||
assertEquals(0,result.bytesConsumed());
|
assertEquals(0,result.bytesConsumed());
|
||||||
assertEquals(0,result.bytesProduced());
|
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
|
// Do the needed unwrap, to an empty buffer
|
||||||
result=server.unwrap(netC2S,BufferUtil.EMPTY_BUFFER);
|
result=server.unwrap(netC2S,BufferUtil.EMPTY_BUFFER);
|
||||||
assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW,result.getStatus());
|
assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW,result.getStatus());
|
||||||
assertEquals(0,result.bytesConsumed());
|
assertEquals(0,result.bytesConsumed());
|
||||||
assertEquals(0,result.bytesProduced());
|
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
|
// Do the needed unwrap, to a full buffer
|
||||||
serverIn.position(serverIn.limit());
|
serverIn.position(serverIn.limit());
|
||||||
|
@ -193,7 +129,7 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
|
||||||
assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW,result.getStatus());
|
assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW,result.getStatus());
|
||||||
assertEquals(0,result.bytesConsumed());
|
assertEquals(0,result.bytesConsumed());
|
||||||
assertEquals(0,result.bytesProduced());
|
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
|
// Do the needed unwrap, to an empty buffer
|
||||||
serverIn.clear();
|
serverIn.clear();
|
||||||
|
@ -201,10 +137,10 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
|
||||||
assertEquals(SSLEngineResult.Status.OK,result.getStatus());
|
assertEquals(SSLEngineResult.Status.OK,result.getStatus());
|
||||||
assertThat(result.bytesConsumed(),greaterThan(0));
|
assertThat(result.bytesConsumed(),greaterThan(0));
|
||||||
assertEquals(0,result.bytesProduced());
|
assertEquals(0,result.bytesProduced());
|
||||||
assertEquals(HandshakeStatus.NEED_TASK,result.getHandshakeStatus());
|
assertEquals(SSLEngineResult.HandshakeStatus.NEED_TASK,result.getHandshakeStatus());
|
||||||
|
|
||||||
server.getDelegatedTask().run();
|
server.getDelegatedTask().run();
|
||||||
|
|
||||||
assertEquals(HandshakeStatus.NEED_WRAP,server.getHandshakeStatus());
|
assertEquals(SSLEngineResult.HandshakeStatus.NEED_WRAP,server.getHandshakeStatus());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enable JAAS for deployed webapplications.
|
Enable JAAS for deployed webapplications.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enable JASPI authentication for deployed webapplications.
|
Enable JASPI authentication for deployed webapplications.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables remote RMI access to JMX
|
Enables remote RMI access to JMX
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables JMX instrumentation for server beans and
|
Enables JMX instrumentation for server beans and
|
||||||
enables JMX agent.
|
enables JMX agent.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Adds the Jetty JNDI implementation to the classpath.
|
Adds the Jetty JNDI implementation to the classpath.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Adds the javax.mail implementation to the classpath.
|
Adds the javax.mail implementation to the classpath.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables test setup
|
Enables test setup
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables an unassembled maven webapp to run in a jetty distro
|
Enables an unassembled maven webapp to run in a jetty distro
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Memcache cache for SessionData
|
Memcache cache for SessionData
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables NoSql session management with a MongoDB driver.
|
Enables NoSql session management with a MongoDB driver.
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue