Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Bartel2013-04-11 05:55:04 +0000
committerJan Bartel2013-04-11 05:55:04 +0000
commit07b844bf854f80febb7a2160ce10a32de10c8338 (patch)
tree34c3800a4f0154c1f7061120208680d6cfeb72e6
parent7523c5234ca9d4a6faa03df23458f7f2f80ce07c (diff)
parent8a0ba267c16f3f1fc7f90dadb2d6d2898b2f8fa8 (diff)
downloadorg.eclipse.jetty.project-07b844bf854f80febb7a2160ce10a32de10c8338.tar.gz
org.eclipse.jetty.project-07b844bf854f80febb7a2160ce10a32de10c8338.tar.xz
org.eclipse.jetty.project-07b844bf854f80febb7a2160ce10a32de10c8338.zip
Merge remote-tracking branch 'origin/master' into servlet-3.1-api
-rw-r--r--VERSION.txt88
-rw-r--r--aggregates/jetty-all/pom.xml2
-rw-r--r--examples/async-rest/async-rest-jar/pom.xml2
-rw-r--r--examples/async-rest/async-rest-webapp/pom.xml2
-rw-r--r--examples/async-rest/pom.xml2
-rw-r--r--examples/embedded/pom.xml2
-rw-r--r--examples/pom.xml2
-rw-r--r--jetty-annotations/pom.xml2
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotation.java2
-rwxr-xr-xjetty-ant/pom.xml2
-rw-r--r--jetty-client/pom.xml2
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java1
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/HttpConnection.java28
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java32
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesClientTest.java369
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesServerTest.java (renamed from jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslBytesServerTest.java)103
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesTest.java (renamed from jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslBytesTest.java)6
-rw-r--r--jetty-client/src/test/resources/keystorebin2201 -> 0 bytes
-rw-r--r--jetty-continuation/pom.xml2
-rw-r--r--jetty-deploy/pom.xml2
-rw-r--r--jetty-distribution/pom.xml2
-rw-r--r--jetty-http/pom.xml2
-rw-r--r--jetty-io/pom.xml2
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java13
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java24
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java93
-rw-r--r--jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointSslTest.java3
-rw-r--r--jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java4
-rw-r--r--jetty-jaas/pom.xml2
-rw-r--r--jetty-jaspi/pom.xml2
-rw-r--r--jetty-jmx/pom.xml2
-rw-r--r--jetty-jndi/pom.xml2
-rw-r--r--jetty-jsp/pom.xml2
-rw-r--r--jetty-jspc-maven-plugin/pom.xml2
-rw-r--r--jetty-maven-plugin/pom.xml2
-rw-r--r--jetty-monitor/pom.xml2
-rw-r--r--jetty-nosql/pom.xml2
-rw-r--r--jetty-npn/pom.xml73
-rw-r--r--jetty-npn/src/main/java/org/eclipse/jetty/npn/NextProtoNego.java248
-rw-r--r--jetty-osgi/jetty-osgi-boot-jsp/pom.xml2
-rw-r--r--jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/ContainerTldBundleDiscoverer.java (renamed from jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/PluggableWebAppRegistrationCustomizerImpl.java)100
-rw-r--r--jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/JSTLBundleDiscoverer.java (renamed from jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/WebappRegistrationCustomizerImpl.java)17
-rw-r--r--jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/FragmentActivator.java47
-rw-r--r--jetty-osgi/jetty-osgi-boot-warurl/pom.xml2
-rw-r--r--jetty-osgi/jetty-osgi-boot/pom.xml2
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractContextProvider.java14
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractOSGiApp.java5
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractWebAppProvider.java17
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleContextProvider.java8
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleProvider.java5
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleWebAppProvider.java1
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java177
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiDeployer.java4
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiMetaInfConfiguration.java8
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiServerConstants.java2
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiUndeployer.java4
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebInfConfiguration.java9
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java7
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceContextProvider.java4
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceProvider.java5
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceWebAppProvider.java1
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/jsp/TldLocatableURLClassloaderWithInsertedJettyClassloader.java69
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java22
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java7
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java113
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/BundleWatcher.java (renamed from jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleTrackerCustomizer.java)191
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/IWebBundleDeployerHelper.java88
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java51
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java53
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/ServiceWatcher.java (renamed from jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyContextHandlerServiceTracker.java)19
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleClassLoaderHelper.java4
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleClassLoaderHelperFactory.java4
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java3
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/EventSender.java39
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/FakeURLClassLoader.java (renamed from jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/jsp/TldLocatableURLClassloader.java)46
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/OSGiClassLoader.java3
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/TldBundleDiscoverer.java43
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/WebappRegistrationCustomizer.java61
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java3
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java5
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/PackageAdminServiceTracker.java8
-rw-r--r--jetty-osgi/jetty-osgi-httpservice/pom.xml2
-rw-r--r--jetty-osgi/jetty-osgi-npn/pom.xml5
-rw-r--r--jetty-osgi/pom.xml2
-rw-r--r--jetty-osgi/test-jetty-osgi-context/pom.xml2
-rw-r--r--jetty-osgi/test-jetty-osgi-webapp/pom.xml2
-rw-r--r--jetty-osgi/test-jetty-osgi/pom.xml2
-rw-r--r--jetty-plus/pom.xml2
-rw-r--r--jetty-proxy/pom.xml2
-rw-r--r--jetty-rewrite/pom.xml2
-rw-r--r--jetty-runner/pom.xml2
-rw-r--r--jetty-security/pom.xml2
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java9
-rw-r--r--jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java60
-rw-r--r--jetty-server/pom.xml2
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java30
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/AsyncNCSARequestLog.java2
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java12
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java8
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/SslConnectionFactory.java1
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java31
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/LowResourcesMonitorTest.java4
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerTest.java73
-rw-r--r--jetty-servlet/pom.xml2
-rw-r--r--jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java2
-rw-r--r--jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java5
-rw-r--r--jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletContextHandlerTest.java4
-rw-r--r--jetty-servlets/pom.xml2
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java37
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/AbstractCompressedStream.java9
-rw-r--r--jetty-spdy/pom.xml2
-rw-r--r--jetty-spdy/spdy-client/pom.xml2
-rw-r--r--jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java1
-rw-r--r--jetty-spdy/spdy-core/pom.xml2
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardSession.java49
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/StandardSessionTest.java43
-rw-r--r--jetty-spdy/spdy-example-webapp/pom.xml2
-rw-r--r--jetty-spdy/spdy-http-server/pom.xml2
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ReferrerPushStrategyTest.java42
-rw-r--r--jetty-spdy/spdy-server/pom.xml2
-rw-r--r--jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/AbstractTest.java6
-rw-r--r--jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/MaxConcurrentStreamTest.java120
-rw-r--r--jetty-spring/pom.xml2
-rw-r--r--jetty-start/pom.xml2
-rw-r--r--jetty-util-ajax/pom.xml2
-rw-r--r--jetty-util/pom.xml2
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/AbstractTrie.java19
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/ArrayTernaryTrie.java129
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java5
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java65
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java3
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/QueueBenchmarkTest.java226
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java37
-rw-r--r--jetty-webapp/pom.xml2
-rw-r--r--jetty-websocket/pom.xml2
-rw-r--r--jetty-websocket/websocket-api/pom.xml2
-rw-r--r--jetty-websocket/websocket-client/pom.xml2
-rw-r--r--jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/WebSocketClientSelectorManager.java2
-rw-r--r--jetty-websocket/websocket-common/pom.xml2
-rw-r--r--jetty-websocket/websocket-server/pom.xml2
-rw-r--r--jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java6
-rw-r--r--jetty-websocket/websocket-servlet/pom.xml2
-rw-r--r--jetty-xml/pom.xml2
-rw-r--r--pom.xml6
-rw-r--r--tests/pom.xml2
-rw-r--r--tests/test-continuation/pom.xml2
-rw-r--r--tests/test-loginservice/pom.xml2
-rw-r--r--tests/test-sessions/pom.xml2
-rw-r--r--tests/test-sessions/test-hash-sessions/pom.xml2
-rw-r--r--tests/test-sessions/test-jdbc-sessions/pom.xml2
-rw-r--r--tests/test-sessions/test-sessions-common/pom.xml2
-rw-r--r--tests/test-webapps/pom.xml2
-rw-r--r--tests/test-webapps/test-jaas-webapp/pom.xml2
-rw-r--r--tests/test-webapps/test-jetty-webapp/pom.xml2
-rw-r--r--tests/test-webapps/test-jndi-webapp/pom.xml2
-rw-r--r--tests/test-webapps/test-mock-resources/pom.xml2
-rw-r--r--tests/test-webapps/test-proxy-webapp/pom.xml2
-rw-r--r--tests/test-webapps/test-servlet-spec/pom.xml2
-rw-r--r--tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml2
-rw-r--r--tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml2
-rw-r--r--tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml2
-rw-r--r--tests/test-webapps/test-webapp-rfc2616/pom.xml2
162 files changed, 2239 insertions, 1316 deletions
diff --git a/VERSION.txt b/VERSION.txt
index a6c48bbedc..4da151fb45 100644
--- a/VERSION.txt
+++ b/VERSION.txt
@@ -1,3 +1,83 @@
+jetty-9.0.2-SNAPSHOT
+
+
+jetty-9.0.1.v20130408 - 08 April 2013
+ + 384552 add comment to jetty-https.xml describing keymanager password
+ + 385488 non existing resources in collection are just warnings
+ + 392129 fixed merged of handling of timeouts after startAsync
+ + 393971 Improve setParentLoaderPriorty javadoc
+ + 393972 Improve WebAppContext classloading javadoc
+ + 395620 do not managed inherited life cycle listeners
+ + 396562 Add an implementation of RequestLog that supports Slf4j
+ + 399967 Destroyables destroyed on undeploy and shutdown hook
+ + 400142 ConcurrentModificationException in JDBC SessionManger
+ + 400144 When loading a session fails the JDBCSessionManger produces duplicate
+ session IDs
+ + 400689 Add support for Proxy authentication.
+ + 401150 close input stream used from cached resource
+ + 401806 spdy push properly pass through request and response headers for
+ pushed resources
+ + 402397 InputStreamResponseListener early close inputStream cause hold lock.
+ + 402485 reseed secure random
+ + 402626 Do not required endpoint host checking by default in server and
+ configure in client
+ + 402666 Improve handling of TLS exceptions due to raw socket close.
+ + 402694 setuid as LifeCycle listener
+ + 402706 HttpSession.setMaxInactiveInterval(int) does not change JDBCSession
+ expiry
+ + 402726 WebAppContext references old WebSocket packages in system and server
+ classes
+ + 402735 jetty.sh to support status which is == check
+ + 402757 WebSocket client module can't be used with WebSocket server module in
+ the same WAR.
+ + 402833 Test harness for global error page and hide exception message from
+ reason string
+ + 402844 STOP.PORT & STOP.KEY behaviour has changed
+ + 402982 Premature initialization of Servlets
+ + 402984 WebSocket Upgrade must honor case insensitive header fields in
+ upgrade request
+ + 403122 Session replication fails with ClassNotFoundException when session
+ attribute is Java dynamic proxy
+ + 403280 Update to javax.el 2.2.4
+ + 403281 jetty.sh waits for started or failure before returning
+ + 403360 Named connectors
+ + 403370 move frameBytes.fail() call in StandardSession.flush() outside the
+ synchronized block to avoid deadlock
+ + 403373 WebSocket change timeout log level from warn -> info
+ + 403380 Introduce WebSocketTimeoutException to differentiate between EOF on
+ write and Timeout
+ + 403451 Review synchronization in SslConnection.
+ + 403510 HttpSession maxInactiveInterval is not serialized in HashSession
+ + 403513 jetty:run goal cannot be executed twice during the maven build
+ + 403570 Asynchronous Request Logging
+ + 403591 do not use the ConcurrentArrayBlockingQueue for thread pool, selector
+ and async request log
+ + 403817 Use of WebSocket Session.close() results in invalid status code
+ + 404029 port jetty-monitor to jetty-9 and activate it
+ + 404036 JDBCSessionIdManager.doStart() method should not call
+ cleanExpiredSessions() because Listeners can't be notified
+ + 404067 If cannot connect to db fail startup of JDBCSessionIdManager
+ + 404128 Add Vary headers rather than set them
+ + 404176 Jetty's AnnotationConfiguration class does not scan non-jar resources
+ on the container classpath
+ + 404204 Exception from inputstream cause hang or timeout.
+ + 404283 org.eclipse.jetty.util.Scanner.scanFile() dies with an NPE if
+ listFiles() returns null
+ + 404323 Improved parameterization of https and SPDY
+ + 404325 data constraint redirection does send default port
+ + 404326 set status when Request.setHandled(true) is called
+ + 404511 Replaced all StringMap usage with Tries
+ + 404517 Close connection if request received after half close
+ + 404610 Reintroduce ability to disallow TLS renegotiation.
+ + 404757 SPDY can only be built with the latest JDK version.
+ + 404789 Support IPv6 addresses in DoSFilter white list.
+ + 404881 Allow regexs for SslContextFactory.setIncludeCipherSuites() and
+ .setExcludeCipherSuites()
+ + 404889 SelectorManager accepts attachments with sockets
+ + 404906 servlets with load-on-startup = 0 are not fired up on jetty 9 startup
+ + 404958 Fixed Resource.newSystemResource striped / handling
+ + 405044 Query parameters lost for non GET or POST.
+
jetty-9.0.0.v20130308 - 08 March 2013
+ 399070 add updated version of npn-boot jar to start.ini
+ 399799 do not hold lock while calling invalidation listeners
@@ -34,10 +114,10 @@ jetty-9.0.0.v20130308 - 08 March 2013
upstream server. Fix several other small proxy issues
+ 402316 HttpReceiver and null pointer exception.
+ 402341 Host with default port causes redirects loop.
- + 402726 WebAppContext references old WebSocket packages in system and
- server classes
- + 402757 WebSocket client module can't be used with WebSocket server
- module in the same WAR
+ + 402726 WebAppContext references old WebSocket packages in system and server
+ classes
+ + 402757 WebSocket client module can't be used with WebSocket server module in
+ the same WAR
jetty-8.1.10.v20130312 - 12 March 2013
+ 376273 Early EOF because of SSL Protocol Error on
diff --git a/aggregates/jetty-all/pom.xml b/aggregates/jetty-all/pom.xml
index 43e01770c0..6ad817d92f 100644
--- a/aggregates/jetty-all/pom.xml
+++ b/aggregates/jetty-all/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/examples/async-rest/async-rest-jar/pom.xml b/examples/async-rest/async-rest-jar/pom.xml
index 56f14d3348..79618bb947 100644
--- a/examples/async-rest/async-rest-jar/pom.xml
+++ b/examples/async-rest/async-rest-jar/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>example-async-rest</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.eclipse.jetty.example-async-rest</groupId>
diff --git a/examples/async-rest/async-rest-webapp/pom.xml b/examples/async-rest/async-rest-webapp/pom.xml
index d2e1815889..866339d96f 100644
--- a/examples/async-rest/async-rest-webapp/pom.xml
+++ b/examples/async-rest/async-rest-webapp/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>example-async-rest</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.eclipse.jetty.example-async-rest</groupId>
diff --git a/examples/async-rest/pom.xml b/examples/async-rest/pom.xml
index 7118c514f4..082de5c490 100644
--- a/examples/async-rest/pom.xml
+++ b/examples/async-rest/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.examples</groupId>
<artifactId>examples-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/examples/embedded/pom.xml b/examples/embedded/pom.xml
index 02b939bc8a..498e11d16b 100644
--- a/examples/embedded/pom.xml
+++ b/examples/embedded/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.examples</groupId>
<artifactId>examples-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/examples/pom.xml b/examples/pom.xml
index f93d56691b..a5d95ba7bb 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.eclipse.jetty.examples</groupId>
diff --git a/jetty-annotations/pom.xml b/jetty-annotations/pom.xml
index ad08f181ee..32bb8c6ce1 100644
--- a/jetty-annotations/pom.xml
+++ b/jetty-annotations/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-annotations</artifactId>
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotation.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotation.java
index f8c4e2be27..f76eadf22a 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotation.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotation.java
@@ -167,7 +167,7 @@ public class WebServletAnnotation extends DiscoveredAnnotation
//if not, add it
for (WebInitParam ip:annotation.initParams())
{
- if (metaData.getOrigin(servletName+".servlet.init-param"+ip.name())==Origin.NotSet)
+ if (metaData.getOrigin(servletName+".servlet.init-param."+ip.name())==Origin.NotSet)
{
holder.setInitParameter(ip.name(), ip.value());
metaData.setOrigin(servletName+".servlet.init-param."+ip.name());
diff --git a/jetty-ant/pom.xml b/jetty-ant/pom.xml
index fb55b416ad..80f05c5573 100755
--- a/jetty-ant/pom.xml
+++ b/jetty-ant/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-ant</artifactId>
diff --git a/jetty-client/pom.xml b/jetty-client/pom.xml
index bac85514e3..c1236c389b 100644
--- a/jetty-client/pom.xml
+++ b/jetty-client/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
index 953855afc9..dd2c7bccdc 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
@@ -966,6 +966,7 @@ public class HttpClient extends ContainerLifeCycle
engine.setUseClientMode(true);
SslConnection sslConnection = newSslConnection(HttpClient.this, endPoint, engine);
+ sslConnection.setRenegotiationAllowed(sslContextFactory.isRenegotiationAllowed());
EndPoint appEndPoint = sslConnection.getDecryptedEndPoint();
HttpConnection connection = newHttpConnection(HttpClient.this, appEndPoint, destination);
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConnection.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConnection.java
index ad96efbad7..ca61d22413 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConnection.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConnection.java
@@ -191,25 +191,17 @@ public class HttpConnection extends AbstractConnection implements Connection
params.append("&");
}
- // Behave as a GET, adding the params to the path, if it's a POST with some content
- if (method == HttpMethod.POST && request.getContent() != null)
- method = HttpMethod.GET;
-
- switch (method)
+ // POST with no content, send parameters as body
+ if (method == HttpMethod.POST && request.getContent() == null)
{
- case GET:
- {
- path += "?";
- path += params.toString();
- request.path(path);
- break;
- }
- case POST:
- {
- request.header(HttpHeader.CONTENT_TYPE, MimeTypes.Type.FORM_ENCODED.asString());
- request.content(new StringContentProvider(params.toString()));
- break;
- }
+ request.header(HttpHeader.CONTENT_TYPE, MimeTypes.Type.FORM_ENCODED.asString());
+ request.content(new StringContentProvider(params.toString()));
+ }
+ else
+ {
+ path += "?";
+ path += params.toString();
+ request.path(path);
}
}
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java
index 225078050b..f01693dbf5 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java
@@ -255,6 +255,38 @@ public class HttpClientTest extends AbstractHttpClientServerTest
}
@Test
+ public void test_PUT_WithParameters() throws Exception
+ {
+ final String paramName = "a";
+ final String paramValue = "\u20AC";
+ start(new AbstractHandler()
+ {
+ @Override
+ public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ {
+ baseRequest.setHandled(true);
+ String value = request.getParameter(paramName);
+ if (paramValue.equals(value))
+ {
+ response.setCharacterEncoding("UTF-8");
+ response.setContentType("text/plain");
+ response.getOutputStream().print(value);
+ }
+ }
+ });
+
+ URI uri = URI.create(scheme + "://localhost:" + connector.getLocalPort() + "/path?" + paramName + "=" + paramValue);
+ ContentResponse response = client.newRequest(uri)
+ .method(HttpMethod.PUT)
+ .timeout(5, TimeUnit.SECONDS)
+ .send();
+
+ Assert.assertNotNull(response);
+ Assert.assertEquals(200, response.getStatus());
+ Assert.assertEquals(paramValue, new String(response.getContent(), "UTF-8"));
+ }
+
+ @Test
public void test_POST_WithParameters_WithContent() throws Exception
{
final byte[] content = {0, 1, 2, 3};
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesClientTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesClientTest.java
new file mode 100644
index 0000000000..67c99310cc
--- /dev/null
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesClientTest.java
@@ -0,0 +1,369 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2013 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.client.ssl;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.SocketTimeoutException;
+import java.util.Arrays;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLSocket;
+
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.api.ContentResponse;
+import org.eclipse.jetty.client.api.Request;
+import org.eclipse.jetty.client.util.FutureResponseListener;
+import org.eclipse.jetty.http.HttpScheme;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SslBytesClientTest extends SslBytesTest
+{
+ private ExecutorService threadPool;
+ private HttpClient client;
+ private SslContextFactory sslContextFactory;
+ private SSLServerSocket acceptor;
+ private SimpleProxy proxy;
+
+ @Before
+ public void init() throws Exception
+ {
+ threadPool = Executors.newCachedThreadPool();
+
+ client = new HttpClient(new SslContextFactory(true));
+ client.setMaxConnectionsPerDestination(1);
+ File keyStore = MavenTestingUtils.getTestResourceFile("keystore.jks");
+ sslContextFactory = client.getSslContextFactory();
+ sslContextFactory.setKeyStorePath(keyStore.getAbsolutePath());
+ sslContextFactory.setKeyStorePassword("storepwd");
+ client.start();
+
+ SSLContext sslContext = sslContextFactory.getSslContext();
+ acceptor = (SSLServerSocket)sslContext.getServerSocketFactory().createServerSocket(43191);
+
+ int serverPort = acceptor.getLocalPort();
+
+ proxy = new SimpleProxy(threadPool, "localhost", serverPort);
+ proxy.start();
+ logger.info(":{} <==> :{}", proxy.getPort(), serverPort);
+ }
+
+ @After
+ public void destroy() throws Exception
+ {
+ if (acceptor != null)
+ acceptor.close();
+ if (proxy != null)
+ proxy.stop();
+ if (client != null)
+ client.stop();
+ if (threadPool != null)
+ threadPool.shutdownNow();
+ }
+
+ @Test
+ public void testHandshake() throws Exception
+ {
+ Request request = client.newRequest("localhost", proxy.getPort());
+ FutureResponseListener listener = new FutureResponseListener(request);
+ request.scheme(HttpScheme.HTTPS.asString()).send(listener);
+
+ Assert.assertTrue(proxy.awaitClient(5, TimeUnit.SECONDS));
+
+ final SSLSocket server = (SSLSocket)acceptor.accept();
+ server.setUseClientMode(false);
+
+ Future<Object> handshake = threadPool.submit(new Callable<Object>()
+ {
+ public Object call() throws Exception
+ {
+ server.startHandshake();
+ return null;
+ }
+ });
+
+ // Client Hello
+ TLSRecord record = proxy.readFromClient();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
+ proxy.flushToServer(record);
+
+ // Server Hello + Certificate + Server Done
+ record = proxy.readFromServer();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
+ proxy.flushToClient(record);
+
+ // Client Key Exchange
+ record = proxy.readFromClient();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
+ proxy.flushToServer(record);
+
+ // Change Cipher Spec
+ record = proxy.readFromClient();
+ Assert.assertEquals(TLSRecord.Type.CHANGE_CIPHER_SPEC, record.getType());
+ proxy.flushToServer(record);
+
+ // Client Done
+ record = proxy.readFromClient();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
+ proxy.flushToServer(record);
+
+ // Change Cipher Spec
+ record = proxy.readFromServer();
+ Assert.assertEquals(TLSRecord.Type.CHANGE_CIPHER_SPEC, record.getType());
+ proxy.flushToClient(record);
+
+ // Server Done
+ record = proxy.readFromServer();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
+ proxy.flushToClient(record);
+
+ Assert.assertNull(handshake.get(5, TimeUnit.SECONDS));
+
+ SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
+ // Read request
+ BufferedReader reader = new BufferedReader(new InputStreamReader(server.getInputStream(), "UTF-8"));
+ String line = reader.readLine();
+ Assert.assertTrue(line.startsWith("GET"));
+ while (line.length() > 0)
+ line = reader.readLine();
+
+ // Write response
+ OutputStream output = server.getOutputStream();
+ output.write(("HTTP/1.1 200 OK\r\n" +
+ "Content-Length: 0\r\n" +
+ "\r\n").getBytes("UTF-8"));
+ output.flush();
+ Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
+
+ ContentResponse response = listener.get(5, TimeUnit.SECONDS);
+ Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
+
+ server.close();
+ }
+
+ @Test
+ public void testServerRenegotiation() throws Exception
+ {
+ Request request = client.newRequest("localhost", proxy.getPort());
+ FutureResponseListener listener = new FutureResponseListener(request);
+ request.scheme(HttpScheme.HTTPS.asString()).send(listener);
+
+ Assert.assertTrue(proxy.awaitClient(5, TimeUnit.SECONDS));
+
+ final SSLSocket server = (SSLSocket)acceptor.accept();
+ server.setUseClientMode(false);
+
+ Future<Object> handshake = threadPool.submit(new Callable<Object>()
+ {
+ public Object call() throws Exception
+ {
+ server.startHandshake();
+ return null;
+ }
+ });
+
+ SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
+ Assert.assertNull(handshake.get(5, TimeUnit.SECONDS));
+
+ // Read request
+ InputStream serverInput = server.getInputStream();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(serverInput, "UTF-8"));
+ String line = reader.readLine();
+ Assert.assertTrue(line.startsWith("GET"));
+ while (line.length() > 0)
+ line = reader.readLine();
+
+ OutputStream serverOutput = server.getOutputStream();
+ byte[] data1 = new byte[1024];
+ Arrays.fill(data1, (byte)'X');
+ String content1 = new String(data1, "UTF-8");
+ byte[] data2 = new byte[1024];
+ Arrays.fill(data2, (byte)'Y');
+ final String content2 = new String(data2, "UTF-8");
+ // Write first part of the response
+ serverOutput.write(("HTTP/1.1 200 OK\r\n" +
+ "Content-Type: text/plain\r\n" +
+ "Content-Length: " + (content1.length() + content2.length()) + "\r\n" +
+ "\r\n" +
+ content1).getBytes("UTF-8"));
+ serverOutput.flush();
+ Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
+
+ // Renegotiate
+ Future<Object> renegotiation = threadPool.submit(new Callable<Object>()
+ {
+ public Object call() throws Exception
+ {
+ server.startHandshake();
+ return null;
+ }
+ });
+
+ // Renegotiation Handshake
+ TLSRecord record = proxy.readFromServer();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
+ proxy.flushToClient(record);
+
+ // Renegotiation Handshake
+ record = proxy.readFromClient();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
+ proxy.flushToServer(record);
+
+ // Trigger a read to have the server write the final renegotiation steps
+ server.setSoTimeout(100);
+ try
+ {
+ serverInput.read();
+ Assert.fail();
+ }
+ catch (SocketTimeoutException x)
+ {
+ // Expected
+ }
+
+ // Renegotiation Handshake
+ record = proxy.readFromServer();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
+ proxy.flushToClient(record);
+
+ // Renegotiation Change Cipher
+ record = proxy.readFromServer();
+ Assert.assertEquals(TLSRecord.Type.CHANGE_CIPHER_SPEC, record.getType());
+ proxy.flushToClient(record);
+
+ // Renegotiation Handshake
+ record = proxy.readFromServer();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
+ proxy.flushToClient(record);
+
+ // Renegotiation Change Cipher
+ record = proxy.readFromClient();
+ Assert.assertEquals(TLSRecord.Type.CHANGE_CIPHER_SPEC, record.getType());
+ proxy.flushToServer(record);
+
+ // Renegotiation Handshake
+ record = proxy.readFromClient();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
+ proxy.flushToServer(record);
+
+ Assert.assertNull(renegotiation.get(5, TimeUnit.SECONDS));
+
+ // Complete the response
+ automaticProxyFlow = proxy.startAutomaticFlow();
+ serverOutput.write(data2);
+ serverOutput.flush();
+ Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
+
+ ContentResponse response = listener.get(5, TimeUnit.SECONDS);
+ Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
+ Assert.assertEquals(data1.length + data2.length, response.getContent().length);
+
+ server.close();
+ }
+
+ @Test
+ public void testServerRenegotiationWhenRenegotiationIsForbidden() throws Exception
+ {
+ sslContextFactory.setRenegotiationAllowed(false);
+
+ Request request = client.newRequest("localhost", proxy.getPort());
+ FutureResponseListener listener = new FutureResponseListener(request);
+ request.scheme(HttpScheme.HTTPS.asString()).send(listener);
+
+ Assert.assertTrue(proxy.awaitClient(5, TimeUnit.SECONDS));
+
+ final SSLSocket server = (SSLSocket)acceptor.accept();
+ server.setUseClientMode(false);
+
+ Future<Object> handshake = threadPool.submit(new Callable<Object>()
+ {
+ public Object call() throws Exception
+ {
+ server.startHandshake();
+ return null;
+ }
+ });
+
+ SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
+ Assert.assertNull(handshake.get(5, TimeUnit.SECONDS));
+
+ // Read request
+ InputStream serverInput = server.getInputStream();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(serverInput, "UTF-8"));
+ String line = reader.readLine();
+ Assert.assertTrue(line.startsWith("GET"));
+ while (line.length() > 0)
+ line = reader.readLine();
+
+ OutputStream serverOutput = server.getOutputStream();
+ byte[] data1 = new byte[1024];
+ Arrays.fill(data1, (byte)'X');
+ String content1 = new String(data1, "UTF-8");
+ byte[] data2 = new byte[1024];
+ Arrays.fill(data2, (byte)'Y');
+ final String content2 = new String(data2, "UTF-8");
+ // Write first part of the response
+ serverOutput.write(("HTTP/1.1 200 OK\r\n" +
+ "Content-Type: text/plain\r\n" +
+ "Content-Length: " + (content1.length() + content2.length()) + "\r\n" +
+ "\r\n" +
+ content1).getBytes("UTF-8"));
+ serverOutput.flush();
+ Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
+
+ // Renegotiate
+ threadPool.submit(new Callable<Object>()
+ {
+ public Object call() throws Exception
+ {
+ server.startHandshake();
+ return null;
+ }
+ });
+
+ // Renegotiation Handshake
+ TLSRecord record = proxy.readFromServer();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
+ proxy.flushToClient(record);
+
+ record = proxy.readFromClient();
+ Assert.assertEquals(TLSRecord.Type.ALERT, record.getType());
+ proxy.flushToServer(record);
+
+ record = proxy.readFromClient();
+ Assert.assertNull(record);
+ proxy.flushToServer(record);
+
+ server.close();
+ }
+}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslBytesServerTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesServerTest.java
index 4a8945673e..1faca02d88 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslBytesServerTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesServerTest.java
@@ -16,7 +16,7 @@
// ========================================================================
//
-package org.eclipse.jetty.server.ssl;
+package org.eclipse.jetty.client.ssl;
import java.io.BufferedReader;
import java.io.EOFException;
@@ -84,7 +84,7 @@ public class SslBytesServerTest extends SslBytesTest
private final int idleTimeout = 2000;
private ExecutorService threadPool;
private Server server;
- private int serverPort;
+ private SslContextFactory sslContextFactory;
private SSLContext sslContext;
private SimpleProxy proxy;
@@ -94,11 +94,10 @@ public class SslBytesServerTest extends SslBytesTest
threadPool = Executors.newCachedThreadPool();
server = new Server();
- File keyStore = MavenTestingUtils.getTestResourceFile("keystore");
- SslContextFactory sslContextFactory = new SslContextFactory();
+ File keyStore = MavenTestingUtils.getTestResourceFile("keystore.jks");
+ sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath(keyStore.getAbsolutePath());
sslContextFactory.setKeyStorePassword("storepwd");
- sslContextFactory.setKeyManagerPassword("keypwd");
HttpConnectionFactory httpFactory = new HttpConnectionFactory()
{
@@ -204,7 +203,7 @@ public class SslBytesServerTest extends SslBytesTest
}
});
server.start();
- serverPort = connector.getLocalPort();
+ int serverPort = connector.getLocalPort();
sslContext = sslContextFactory.getSslContext();
@@ -1278,6 +1277,98 @@ public class SslBytesServerTest extends SslBytesTest
}
@Test
+ public void testRequestWithContentWithRenegotiationInMiddleOfContentWhenRenegotiationIsForbidden() throws Exception
+ {
+ assumeJavaVersionSupportsTLSRenegotiations();
+
+ sslContextFactory.setRenegotiationAllowed(false);
+
+ final SSLSocket client = newClient();
+ final OutputStream clientOutput = client.getOutputStream();
+
+ SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
+ client.startHandshake();
+ Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
+
+ byte[] data1 = new byte[1024];
+ Arrays.fill(data1, (byte)'X');
+ String content1 = new String(data1, "UTF-8");
+ byte[] data2 = new byte[1024];
+ Arrays.fill(data2, (byte)'Y');
+ final String content2 = new String(data2, "UTF-8");
+
+ // Write only part of the body
+ automaticProxyFlow = proxy.startAutomaticFlow();
+ clientOutput.write(("" +
+ "POST / HTTP/1.1\r\n" +
+ "Host: localhost\r\n" +
+ "Content-Type: text/plain\r\n" +
+ "Content-Length: " + (content1.length() + content2.length()) + "\r\n" +
+ "\r\n" +
+ content1).getBytes("UTF-8"));
+ clientOutput.flush();
+ Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
+
+ // Renegotiate
+ threadPool.submit(new Callable<Object>()
+ {
+ @Override
+ public Object call() throws Exception
+ {
+ client.startHandshake();
+ return null;
+ }
+ });
+
+ // Renegotiation Handshake
+ TLSRecord record = proxy.readFromClient();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
+ proxy.flushToServer(record);
+
+ // Renegotiation now allowed, server has closed
+ record = proxy.readFromServer();
+ Assert.assertEquals(TLSRecord.Type.ALERT, record.getType());
+ proxy.flushToClient(record);
+
+ record = proxy.readFromServer();
+ Assert.assertNull(record);
+
+ // Write the rest of the request
+ threadPool.submit(new Callable<Object>()
+ {
+ @Override
+ public Object call() throws Exception
+ {
+ clientOutput.write(content2.getBytes("UTF-8"));
+ clientOutput.flush();
+ return null;
+ }
+ });
+
+ // Trying to write more application data results in an exception since the server closed
+ record = proxy.readFromClient();
+ proxy.flushToServer(record);
+ try
+ {
+ record = proxy.readFromClient();
+ Assert.assertNotNull(record);
+ proxy.flushToServer(record);
+ Assert.fail();
+ }
+ catch (IOException expected)
+ {
+ }
+
+ // Check that we did not spin
+ TimeUnit.MILLISECONDS.sleep(500);
+ Assert.assertThat(sslFills.get(), Matchers.lessThan(50));
+ Assert.assertThat(sslFlushes.get(), Matchers.lessThan(20));
+ Assert.assertThat(httpParses.get(), Matchers.lessThan(50));
+
+ client.close();
+ }
+
+ @Test
public void testRequestWithBigContentWithRenegotiationInMiddleOfContent() throws Exception
{
assumeJavaVersionSupportsTLSRenegotiations();
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslBytesTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesTest.java
index a3b4952fec..c7fe7447dd 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslBytesTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesTest.java
@@ -16,7 +16,7 @@
// ========================================================================
//
-package org.eclipse.jetty.server.ssl;
+package org.eclipse.jetty.client.ssl;
import java.io.EOFException;
import java.io.IOException;
@@ -115,8 +115,8 @@ public abstract class SslBytesTest
public void start() throws Exception
{
-// serverSocket = new ServerSocket(5871);
- serverSocket = new ServerSocket(0);
+ serverSocket = new ServerSocket(47009);
+// serverSocket = new ServerSocket(0);
Thread acceptor = new Thread(this);
acceptor.start();
server = new Socket(serverHost, serverPort);
diff --git a/jetty-client/src/test/resources/keystore b/jetty-client/src/test/resources/keystore
deleted file mode 100644
index 3a15d1b603..0000000000
--- a/jetty-client/src/test/resources/keystore
+++ /dev/null
Binary files differ
diff --git a/jetty-continuation/pom.xml b/jetty-continuation/pom.xml
index 0763a021b0..e146ba8bb6 100644
--- a/jetty-continuation/pom.xml
+++ b/jetty-continuation/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-continuation</artifactId>
diff --git a/jetty-deploy/pom.xml b/jetty-deploy/pom.xml
index cc8a10e956..55848f5ca2 100644
--- a/jetty-deploy/pom.xml
+++ b/jetty-deploy/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-deploy</artifactId>
diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml
index 3f9ba0a3a3..dfe828f73b 100644
--- a/jetty-distribution/pom.xml
+++ b/jetty-distribution/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<artifactId>jetty-distribution</artifactId>
<name>Jetty :: Distribution Assemblies</name>
diff --git a/jetty-http/pom.xml b/jetty-http/pom.xml
index 5b5585fbfc..1403df18ff 100644
--- a/jetty-http/pom.xml
+++ b/jetty-http/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>jetty-project</artifactId>
<groupId>org.eclipse.jetty</groupId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-http</artifactId>
diff --git a/jetty-io/pom.xml b/jetty-io/pom.xml
index 2c9377e3b3..24eedb6d31 100644
--- a/jetty-io/pom.xml
+++ b/jetty-io/pom.xml
@@ -2,7 +2,7 @@
<parent>
<artifactId>jetty-project</artifactId>
<groupId>org.eclipse.jetty</groupId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-io</artifactId>
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java
index 7549903af5..4ec1d84459 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java
@@ -142,14 +142,11 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint
@Override
protected void onIdleExpired(TimeoutException timeout)
{
- if (isOutputShutdown() || _fillInterest.isInterested() || _writeFlusher.isInProgress())
- {
- boolean output_shutdown=isOutputShutdown();
- _fillInterest.onFail(timeout);
- _writeFlusher.onFail(timeout);
- if (output_shutdown)
- close();
- }
+ boolean output_shutdown=isOutputShutdown();
+ _fillInterest.onFail(timeout);
+ _writeFlusher.onFail(timeout);
+ if (output_shutdown)
+ close();
}
@Override
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java
index 1a1f7f4221..317c55ef6d 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java
@@ -167,6 +167,20 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
selector.submit(selector.new Accept(channel));
}
+ /**
+ * <p>Registers a channel to perform non-blocking read/write operations.</p>
+ * <p>This method is called just after a channel has been accepted by {@link ServerSocketChannel#accept()},
+ * or just after having performed a blocking connect via {@link Socket#connect(SocketAddress, int)}.</p>
+ *
+ * @param channel the channel to register
+ * @param attachment An attachment to be passed via the selection key to the {@link SelectorManager#newConnection(SocketChannel, EndPoint, Object)} method.
+ */
+ public void accept(final SocketChannel channel, Object attachment)
+ {
+ final ManagedSelector selector = chooseSelector();
+ selector.submit(selector.new Accept(channel, attachment));
+ }
+
@Override
protected void doStart() throws Exception
{
@@ -685,10 +699,18 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
private class Accept implements Runnable
{
private final SocketChannel _channel;
+ private final Object _attachment;
public Accept(SocketChannel channel)
{
this._channel = channel;
+ this._attachment = null;
+ }
+
+ public Accept(SocketChannel channel, Object attachment)
+ {
+ this._channel = channel;
+ this._attachment = attachment;
}
@Override
@@ -696,7 +718,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
{
try
{
- SelectionKey key = _channel.register(_selector, 0, null);
+ SelectionKey key = _channel.register(_selector, 0, _attachment);
EndPoint endpoint = createEndPoint(_channel, key);
key.attach(endpoint);
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java
index 9d13a1a8d0..4fca18f3f1 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java
@@ -99,6 +99,7 @@ public class SslConnection extends AbstractConnection
_decryptedEndPoint.getWriteFlusher().completeWrite();
}
};
+ private boolean _renegotiationAllowed;
public SslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine sslEngine)
{
@@ -137,6 +138,16 @@ public class SslConnection extends AbstractConnection
return _decryptedEndPoint;
}
+ public boolean isRenegotiationAllowed()
+ {
+ return _renegotiationAllowed;
+ }
+
+ public void setRenegotiationAllowed(boolean renegotiationAllowed)
+ {
+ this._renegotiationAllowed = renegotiationAllowed;
+ }
+
@Override
public void onOpen()
{
@@ -242,6 +253,7 @@ public class SslConnection extends AbstractConnection
private boolean _fillRequiresFlushToProgress;
private boolean _flushRequiresFillToProgress;
private boolean _cannotAcceptMoreAppDataToFlush;
+ private boolean _handshaken;
private boolean _underFlown;
private final Callback _writeCallback = new Callback()
@@ -493,15 +505,19 @@ public class SslConnection extends AbstractConnection
if (DEBUG)
LOG.debug("{} unwrap {}", SslConnection.this, unwrapResult);
+ Status unwrapResultStatus = unwrapResult.getStatus();
+ HandshakeStatus unwrapHandshakeStatus = unwrapResult.getHandshakeStatus();
+ HandshakeStatus handshakeStatus = _sslEngine.getHandshakeStatus();
+
// and deal with the results
- switch (unwrapResult.getStatus())
+ switch (unwrapResultStatus)
{
case BUFFER_OVERFLOW:
throw new IllegalStateException();
case CLOSED:
// Dang! we have to care about the handshake state specially for close
- switch (_sslEngine.getHandshakeStatus())
+ switch (handshakeStatus)
{
case NOT_HANDSHAKING:
// We were not handshaking, so just tell the app we are closed
@@ -521,10 +537,28 @@ public class SslConnection extends AbstractConnection
throw new IllegalStateException();
default:
- if (unwrapResult.getStatus()==Status.BUFFER_UNDERFLOW)
- _underFlown=true;
+ if (unwrapHandshakeStatus == HandshakeStatus.FINISHED && !_handshaken)
+ {
+ _handshaken = true;
+ if (DEBUG)
+ LOG.debug("{} handshake completed client-side", SslConnection.this);
+ }
+
+ // Check whether renegotiation is allowed
+ if (_handshaken && handshakeStatus != HandshakeStatus.NOT_HANDSHAKING && !isRenegotiationAllowed())
+ {
+ if (DEBUG)
+ LOG.debug("{} renegotiation denied", SslConnection.this);
+ closeInbound();
+ return -1;
+ }
+
+ if (unwrapResultStatus == Status.BUFFER_UNDERFLOW)
+ _underFlown = true;
- // if we produced bytes, we don't care about the handshake state for now and it can be dealt with on another call to fill or flush
+ // If bytes were produced, don't bother with the handshake status;
+ // pass the decrypted data to the application, which will perform
+ // another call to fill() or flush().
if (unwrapResult.bytesProduced() > 0)
{
if (app_in == buffer)
@@ -533,7 +567,7 @@ public class SslConnection extends AbstractConnection
}
// Dang! we have to care about the handshake state
- switch (_sslEngine.getHandshakeStatus())
+ switch (handshakeStatus)
{
case NOT_HANDSHAKING:
// we just didn't read anything.
@@ -553,7 +587,7 @@ public class SslConnection extends AbstractConnection
// we need to send some handshake data
// if we are called from flush
- if (buffer==__FLUSH_CALLED_FILL)
+ if (buffer == __FLUSH_CALLED_FILL)
return 0; // let it do the wrapping
_fillRequiresFlushToProgress = true;
@@ -661,7 +695,6 @@ public class SslConnection extends AbstractConnection
while (true)
{
- // do the funky SSL thang!
// We call sslEngine.wrap to try to take bytes from appOut buffers and encrypt them into the _netOut buffer
BufferUtil.compact(_encryptedOutput);
int pos = BufferUtil.flipToFill(_encryptedOutput);
@@ -672,18 +705,20 @@ public class SslConnection extends AbstractConnection
if (wrapResult.bytesConsumed()>0)
consumed+=wrapResult.bytesConsumed();
- boolean all_consumed=true;
+ boolean allConsumed=true;
// clear empty buffers to prevent position creeping up the buffer
for (ByteBuffer b : appOuts)
{
if (BufferUtil.isEmpty(b))
BufferUtil.clear(b);
else
- all_consumed=false;
+ allConsumed=false;
}
+ Status wrapResultStatus = wrapResult.getStatus();
+
// and deal with the results returned from the sslEngineWrap
- switch (wrapResult.getStatus())
+ switch (wrapResultStatus)
{
case CLOSED:
// The SSL engine has close, but there may be close handshake that needs to be written
@@ -692,32 +727,51 @@ public class SslConnection extends AbstractConnection
_cannotAcceptMoreAppDataToFlush = true;
getEndPoint().flush(_encryptedOutput);
// If we failed to flush the close handshake then we will just pretend that
- // the write has progressed normally and let a subsequent call to flush (or WriteFlusher#onIncompleteFlushed)
- // to finish writing the close handshake. The caller will find out about the close on a subsequent flush or fill.
+ // the write has progressed normally and let a subsequent call to flush
+ // (or WriteFlusher#onIncompleteFlushed) to finish writing the close handshake.
+ // The caller will find out about the close on a subsequent flush or fill.
if (BufferUtil.hasContent(_encryptedOutput))
return false;
}
// otherwise we have written, and the caller will close the underlying connection
- return all_consumed;
+ return allConsumed;
case BUFFER_UNDERFLOW:
throw new IllegalStateException();
default:
if (DEBUG)
- LOG.debug("{} {} {}", this, wrapResult.getStatus(), BufferUtil.toDetailString(_encryptedOutput));
+ LOG.debug("{} {} {}", this, wrapResultStatus, BufferUtil.toDetailString(_encryptedOutput));
+
+ if (wrapResult.getHandshakeStatus() == HandshakeStatus.FINISHED && !_handshaken)
+ {
+ _handshaken = true;
+ if (DEBUG)
+ LOG.debug("{} handshake completed server-side", SslConnection.this);
+ }
+
+ HandshakeStatus handshakeStatus = _sslEngine.getHandshakeStatus();
+
+ // Check whether renegotiation is allowed
+ if (_handshaken && handshakeStatus != HandshakeStatus.NOT_HANDSHAKING && !isRenegotiationAllowed())
+ {
+ if (DEBUG)
+ LOG.debug("{} renegotiation denied", SslConnection.this);
+ shutdownOutput();
+ return allConsumed;
+ }
// if we have net bytes, let's try to flush them
if (BufferUtil.hasContent(_encryptedOutput))
getEndPoint().flush(_encryptedOutput);
// But we also might have more to do for the handshaking state.
- switch (_sslEngine.getHandshakeStatus())
+ switch (handshakeStatus)
{
case NOT_HANDSHAKING:
// Return with the number of bytes consumed (which may be 0)
- return all_consumed&&BufferUtil.isEmpty(_encryptedOutput);
+ return allConsumed && BufferUtil.isEmpty(_encryptedOutput);
case NEED_TASK:
// run the task and continue
@@ -737,14 +791,13 @@ public class SslConnection extends AbstractConnection
_flushRequiresFillToProgress = true;
fill(__FLUSH_CALLED_FILL);
// Check if after the fill() we need to wrap again
- if (_sslEngine.getHandshakeStatus() == HandshakeStatus.NEED_WRAP)
+ if (handshakeStatus == HandshakeStatus.NEED_WRAP)
continue;
}
- return all_consumed&&BufferUtil.isEmpty(_encryptedOutput);
+ return allConsumed&&BufferUtil.isEmpty(_encryptedOutput);
case FINISHED:
throw new IllegalStateException();
-
}
}
}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointSslTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointSslTest.java
index 6f956a18e4..77aea8b008 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointSslTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointSslTest.java
@@ -74,10 +74,9 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
SSLEngine engine = __sslCtxFactory.newSSLEngine();
engine.setUseClientMode(false);
SslConnection sslConnection = new SslConnection(__byteBufferPool, _threadPool, endpoint, engine);
-
+ sslConnection.setRenegotiationAllowed(__sslCtxFactory.isRenegotiationAllowed());
Connection appConnection = super.newConnection(channel,sslConnection.getDecryptedEndPoint());
sslConnection.getDecryptedEndPoint().setConnection(appConnection);
-
return sslConnection;
}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java
index 506d50bd5b..c02bd000ca 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java
@@ -30,7 +30,6 @@ import java.nio.channels.SocketChannel;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
-
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSocket;
@@ -80,10 +79,9 @@ public class SslConnectionTest
SSLEngine engine = __sslCtxFactory.newSSLEngine();
engine.setUseClientMode(false);
SslConnection sslConnection = new SslConnection(__byteBufferPool, getExecutor(), endpoint, engine);
-
+ sslConnection.setRenegotiationAllowed(__sslCtxFactory.isRenegotiationAllowed());
Connection appConnection = new TestConnection(sslConnection.getDecryptedEndPoint());
sslConnection.getDecryptedEndPoint().setConnection(appConnection);
-
return sslConnection;
}
diff --git a/jetty-jaas/pom.xml b/jetty-jaas/pom.xml
index c90b92f7f7..974d960b87 100644
--- a/jetty-jaas/pom.xml
+++ b/jetty-jaas/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-jaas</artifactId>
diff --git a/jetty-jaspi/pom.xml b/jetty-jaspi/pom.xml
index ab7f0bf98e..4ed1f95456 100644
--- a/jetty-jaspi/pom.xml
+++ b/jetty-jaspi/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-jaspi</artifactId>
diff --git a/jetty-jmx/pom.xml b/jetty-jmx/pom.xml
index 45ee56ccc5..dd2813f488 100644
--- a/jetty-jmx/pom.xml
+++ b/jetty-jmx/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-jmx</artifactId>
diff --git a/jetty-jndi/pom.xml b/jetty-jndi/pom.xml
index 29f8774ef9..e58d8f6257 100644
--- a/jetty-jndi/pom.xml
+++ b/jetty-jndi/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-jndi</artifactId>
diff --git a/jetty-jsp/pom.xml b/jetty-jsp/pom.xml
index aa406a55a6..5fc0eb2c31 100644
--- a/jetty-jsp/pom.xml
+++ b/jetty-jsp/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-jsp</artifactId>
diff --git a/jetty-jspc-maven-plugin/pom.xml b/jetty-jspc-maven-plugin/pom.xml
index 59b3671af5..2d2ae6bd18 100644
--- a/jetty-jspc-maven-plugin/pom.xml
+++ b/jetty-jspc-maven-plugin/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-jspc-maven-plugin</artifactId>
diff --git a/jetty-maven-plugin/pom.xml b/jetty-maven-plugin/pom.xml
index c19c48fd33..1cc716c0e8 100644
--- a/jetty-maven-plugin/pom.xml
+++ b/jetty-maven-plugin/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-maven-plugin</artifactId>
diff --git a/jetty-monitor/pom.xml b/jetty-monitor/pom.xml
index ee63fa2a0b..2704f7efaa 100644
--- a/jetty-monitor/pom.xml
+++ b/jetty-monitor/pom.xml
@@ -19,7 +19,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-monitor</artifactId>
diff --git a/jetty-nosql/pom.xml b/jetty-nosql/pom.xml
index f395758fef..cf8ca808f7 100644
--- a/jetty-nosql/pom.xml
+++ b/jetty-nosql/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-nosql</artifactId>
diff --git a/jetty-npn/pom.xml b/jetty-npn/pom.xml
deleted file mode 100644
index 28d3ad12ec..0000000000
--- a/jetty-npn/pom.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-project</artifactId>
- <version>9.0.0-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <groupId>org.eclipse.jetty.npn</groupId>
- <artifactId>npn-api</artifactId>
- <version>1.1.1-SNAPSHOT</version>
- <name>Jetty :: Next Protocol Negotiation :: API</name>
-
- <properties>
- <!-- for now we do make it an OSGi bundle...
- but it needs to be in the bootstrap classes at runtime. -->
- <bundle-symbolic-name>org.eclipse.jetty.npn</bundle-symbolic-name>
- </properties>
-
- <scm>
- <connection>scm:git:http://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project.git</connection>
- <developerConnection>scm:git:ssh://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project.git</developerConnection>
- <url>http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/jetty-npn</url>
- </scm>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <executions>
- <execution>
- <goals>
- <goal>manifest</goal>
- </goals>
- <configuration>
- <instructions>
- <Export-Package>org.eclipse.jetty.npn.*;version="9.0"</Export-Package>
- <Import-Package>*</Import-Package>
- <Bundle-Description>Next Protocol Negotiation API. must be in the bootstrap packages at runtime.</Bundle-Description>
- </instructions>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <!--
- Required for OSGI
- -->
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
- </archive>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-release-plugin</artifactId>
- <version>2.2.1</version>
- <configuration>
- <useReleaseProfile>false</useReleaseProfile>
- <goals>deploy</goals>
- <arguments>-Peclipse-release</arguments>
- <preparationGoals>clean install</preparationGoals>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
diff --git a/jetty-npn/src/main/java/org/eclipse/jetty/npn/NextProtoNego.java b/jetty-npn/src/main/java/org/eclipse/jetty/npn/NextProtoNego.java
deleted file mode 100644
index 6dbea165b5..0000000000
--- a/jetty-npn/src/main/java/org/eclipse/jetty/npn/NextProtoNego.java
+++ /dev/null
@@ -1,248 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2013 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.npn;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.WeakHashMap;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLSocket;
-
-/**
- * <p>{@link NextProtoNego} provides an API to applications that want to make use of the
- * <a href="http://technotes.googlecode.com/git/nextprotoneg.html">Next Protocol Negotiation</a>.</p>
- * <p>The NPN extension is only available when using the TLS protocol, therefore applications must
- * ensure that the TLS protocol is used:</p>
- * <pre>
- * SSLContext context = SSLContext.getInstance("TLSv1");
- * </pre>
- * <p>Refer to the
- * <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SSLContext">list
- * of standard SSLContext protocol names</a> for further information on TLS protocol versions supported.</p>
- * <p>Applications must register instances of either {@link SSLSocket} or {@link SSLEngine} with a
- * {@link ClientProvider} or with a {@link ServerProvider}, depending whether they are on client or
- * server side.</p>
- * <p>The NPN implementation will invoke the provider callbacks to allow applications to interact
- * with the negotiation of the next protocol.</p>
- * <p>Client side typical usage:</p>
- * <pre>
- * SSLSocket sslSocket = ...;
- * NextProtoNego.put(sslSocket, new NextProtoNego.ClientProvider()
- * {
- * &#64;Override
- * public boolean supports()
- * {
- * return true;
- * }
- *
- * &#64;Override
- * public void unsupported()
- * {
- * }
- *
- * &#64;Override
- * public String selectProtocol(List&lt;String&gt; protocols)
- * {
- * return protocols.get(0);
- * }
- * });
- * </pre>
- * <p>Server side typical usage:</p>
- * <pre>
- * SSLSocket sslSocket = ...;
- * NextProtoNego.put(sslSocket, new NextProtoNego.ServerProvider()
- * {
- * &#64;Override
- * public void unsupported()
- * {
- * }
- *
- * &#64;Override
- * public List<String> protocols()
- * {
- * return Arrays.asList("http/1.1");
- * }
- *
- * &#64;Override
- * public void protocolSelected(String protocol)
- * {
- * System.out.println("Protocol Selected is: " + protocol);
- * }
- * });
- * </pre>
- * <p>There is no need to unregister {@link SSLSocket} or {@link SSLEngine} instances, as they
- * are kept in a {@link WeakHashMap} and will be garbage collected when the application does not
- * hard reference them anymore. However, methods to explicitly unregister {@link SSLSocket} or
- * {@link SSLEngine} instances are provided.</p>
- * <p>In order to help application development, you can set the {@link NextProtoNego#debug} field
- * to {@code true} to have debug code printed to {@link System#err}.</p>
- */
-public class NextProtoNego
-{
- /**
- * <p>Enables debug logging on {@link System#err}.</p>
- */
- public static boolean debug = false;
-
- private static Map<Object, Provider> objects = Collections.synchronizedMap(new WeakHashMap<Object, Provider>());
-
- private NextProtoNego()
- {
- }
-
- /**
- * <p>Registers a SSLSocket with a provider.</p>
- *
- * @param socket the socket to register with the provider
- * @param provider the provider to register with the socket
- * @see #remove(SSLSocket)
- */
- public static void put(SSLSocket socket, Provider provider)
- {
- objects.put(socket, provider);
- }
-
- /**
- * @param socket a socket registered with {@link #put(SSLSocket, Provider)}
- * @return the provider registered with the given socket
- */
- public static Provider get(SSLSocket socket)
- {
- return objects.get(socket);
- }
-
- /**
- * <p>Unregisters the given SSLSocket.</p>
- *
- * @param socket the socket to unregister
- * @return the provider registered with the socket
- * @see #put(SSLSocket, Provider)
- */
- public static Provider remove(SSLSocket socket)
- {
- return objects.remove(socket);
- }
-
- /**
- * <p>Registers a SSLEngine with a provider.</p>
- *
- * @param engine the engine to register with the provider
- * @param provider the provider to register with the engine
- * @see #remove(SSLEngine)
- */
- public static void put(SSLEngine engine, Provider provider)
- {
- objects.put(engine, provider);
- }
-
- /**
- *
- * @param engine an engine registered with {@link #put(SSLEngine, Provider)}
- * @return the provider registered with the given engine
- */
- public static Provider get(SSLEngine engine)
- {
- return objects.get(engine);
- }
-
- /**
- * <p>Unregisters the given SSLEngine.</p>
- *
- * @param engine the engine to unregister
- * @return the provider registered with the engine
- * @see #put(SSLEngine, Provider)
- */
- public static Provider remove(SSLEngine engine)
- {
- return objects.remove(engine);
- }
-
- /**
- * <p>Base, empty, interface for providers.</p>
- */
- public interface Provider
- {
- }
-
- /**
- * <p>The client-side provider interface that applications must implement to interact
- * with the negotiation of the next protocol.</p>
- */
- public interface ClientProvider extends Provider
- {
- /**
- * <p>Callback invoked to let the implementation know whether an
- * empty NPN extension should be added to a ClientHello SSL message.</p>
- *
- * @return true to add the NPN extension, false otherwise
- */
- public boolean supports();
-
- /**
- * <p>Callback invoked to let the application know that the server does
- * not support NPN.</p>
- */
- public void unsupported();
-
- /**
- * <p>Callback invoked to let the application select a protocol
- * among the ones sent by the server.</p>
- *
- * @param protocols the protocols sent by the server
- * @return the protocol selected by the application, or null if the
- * NextProtocol SSL message should not be sent to the server
- */
- public String selectProtocol(List<String> protocols);
- }
-
- /**
- * <p>The server-side provider interface that applications must implement to interact
- * with the negotiation of the next protocol.</p>
- */
- public interface ServerProvider extends Provider
- {
- /**
- * <p>Callback invoked to let the application know that the client does not
- * support NPN.</p>
- */
- public void unsupported();
-
- /**
- * <p>Callback invoked to let the implementation know the list
- * of protocols that should be added to an NPN extension in a
- * ServerHello SSL message.</p>
- * <p>This callback is invoked only if the client sent a NPN extension.</p>
- *
- * @return the list of protocols, or null if no NPN extension
- * should be sent to the client
- */
- public List<String> protocols();
-
- /**
- * <p>Callback invoked to let the application know the protocol selected
- * by the client.</p>
- * <p>This callback is invoked only if the client sent a NextProtocol SSL message.</p>
- *
- * @param protocol the selected protocol
- */
- public void protocolSelected(String protocol);
- }
-}
diff --git a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml
index 325448d0d6..a7e5645b29 100644
--- a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml
+++ b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-osgi-boot-jsp</artifactId>
diff --git a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/PluggableWebAppRegistrationCustomizerImpl.java b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/ContainerTldBundleDiscoverer.java
index 2521ed186d..f9c212a516 100644
--- a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/PluggableWebAppRegistrationCustomizerImpl.java
+++ b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/ContainerTldBundleDiscoverer.java
@@ -21,8 +21,6 @@ package org.eclipse.jetty.osgi.boot.jasper;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -32,67 +30,48 @@ import java.util.regex.Pattern;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.osgi.boot.OSGiWebInfConfiguration;
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
-import org.eclipse.jetty.osgi.boot.utils.WebappRegistrationCustomizer;
+import org.eclipse.jetty.osgi.boot.utils.TldBundleDiscoverer;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
+
+
/**
- * Plug bundles that contains tld files so that jasper will discover them and
- * set them up in jetty.
+ * ContainerTldBundleDiscoverer
+ *
+ *
+ * Use a System property to define bundles that contain tlds that need to
+ * be treated by jasper as if they were on the jetty container's classpath.
+ *
+ * The value of the property is evaluated against the DeploymentManager
+ * context attribute "org.eclipse.jetty.server.webapp.containerIncludeBundlePattern",
+ * which defines a pattern of matching bundle names.
+ *
+ * The bundle locations are converted to URLs for jasper's use.
+ *
+ * Eg:
+ * -Dorg.eclipse.jetty.osgi.tldbundles=org.springframework.web.servlet,com.opensymphony.module.sitemesh
*
- * For example:
- * -Dorg.eclipse.jetty.osgi.tldbundles=org.springframework.web.servlet
- * ,com.opensymphony.module.sitemesh Otherwise use an attribute to the
- * WebAppDeployer &lt;New
- * class="org.eclipse.jetty.deploy.providers.WebAppProvider"&gt; .... &lt;Set
- * name="tldBundles"&gt;&ltProperty name="org.eclipse.jetty.osgi.tldsbundles"
- * default="" /&gt;&lt;/Set&gt; &lt;New&gt;
*/
-public class PluggableWebAppRegistrationCustomizerImpl implements WebappRegistrationCustomizer
+public class ContainerTldBundleDiscoverer implements TldBundleDiscoverer
{
/**
- * To plug into jasper bundles that contain tld files please use a list of
- * bundle's symbolic names:
- * -Djetty.osgi.tldbundles=org.springframework.web.servlet
- * ,com.opensymphony.module.sitemesh
+ * Comma separated list of names of bundles that contain tld files that should be
+ * discoved by jasper as if they were on the container's classpath.
+ * Eg:
+ * -Djetty.osgi.tldbundles=org.springframework.web.servlet,com.opensymphony.module.sitemesh
*/
public static final String SYS_PROP_TLD_BUNDLES = "org.eclipse.jetty.osgi.tldbundles";
- /**
- * Union of the tld bundles defined system wide and the one defines as an
- * attribute of the AppProvider.
- *
- * @param provider
- * @return
- */
- private static Collection<String> getTldBundles(DeploymentManager deploymentManager)
- {
- String sysprop = System.getProperty(SYS_PROP_TLD_BUNDLES);
- String att = (String) deploymentManager.getContextAttribute(OSGiWebInfConfiguration.CONTAINER_BUNDLE_PATTERN);
- if (sysprop == null && att == null) { return Collections.emptySet(); }
- if (att == null)
- {
- att = sysprop;
- }
- else if (sysprop != null)
- {
- att = att + "," + sysprop;
- }
- Collection<String> tldbundles = new HashSet<String>();
- StringTokenizer tokenizer = new StringTokenizer(att, ", \n\r\t", false);
- while (tokenizer.hasMoreTokens())
- {
- tldbundles.add(tokenizer.nextToken());
- }
- return tldbundles;
- }
/**
- * @return The location of the jars that contain tld files. Jasper will
- * discover them.
+ * Check the System property "org.eclipse.jetty.osgi.tldbundles" for names of
+ * bundles that contain tlds and convert to URLs.
+ *
+ * @return The location of the jars that contain tld files as URLs.
*/
- public URL[] getJarsWithTlds(DeploymentManager deploymentManager, BundleFileLocatorHelper locatorHelper) throws Exception
+ public URL[] getUrlsForBundlesWithTlds(DeploymentManager deploymentManager, BundleFileLocatorHelper locatorHelper) throws Exception
{
// naive way of finding those bundles.
// lots of assumptions: for example we assume a single version of each
@@ -103,7 +82,7 @@ public class PluggableWebAppRegistrationCustomizerImpl implements WebappRegistra
// probably using custom properties in the ContextHandler service
// and mirroring those in the MANIFEST.MF
- Bundle[] bundles = FrameworkUtil.getBundle(PluggableWebAppRegistrationCustomizerImpl.class).getBundleContext().getBundles();
+ Bundle[] bundles = FrameworkUtil.getBundle(ContainerTldBundleDiscoverer.class).getBundleContext().getBundles();
HashSet<URL> urls = new HashSet<URL>();
String tmp = System.getProperty(SYS_PROP_TLD_BUNDLES); //comma separated exact names
List<String> sysNames = new ArrayList<String>();
@@ -118,10 +97,10 @@ public class PluggableWebAppRegistrationCustomizerImpl implements WebappRegistra
for (Bundle bundle : bundles)
{
if (sysNames.contains(bundle.getSymbolicName()))
- registerTldBundle(locatorHelper, bundle, urls);
+ convertBundleLocationToURL(locatorHelper, bundle, urls);
if (pattern != null && pattern.matcher(bundle.getSymbolicName()).matches())
- registerTldBundle(locatorHelper, bundle, urls);
+ convertBundleLocationToURL(locatorHelper, bundle, urls);
}
return urls.toArray(new URL[urls.size()]);
@@ -129,19 +108,8 @@ public class PluggableWebAppRegistrationCustomizerImpl implements WebappRegistra
}
/**
- * Resolves the bundle that contains tld files as a set of URLs that will be
- * passed to jasper as a URLClassLoader later on. Usually that would be a
- * single URL per bundle. But we do some more work if there are jars
- * embedded in the bundle.
- *
- * The jasper TldScanner expects a URLClassloader to parse a jar for the
- * /META-INF/*.tld it may contain. We place the bundles that we know contain
- * such tag-libraries. Please note that it will work if and only if the
- * bundle is a jar (!) Currently we just hardcode the bundle that contains
- * the jstl implemenation.
- *
- * A workaround when the tld cannot be parsed with this method is to copy
- * and paste it inside the WEB-INF of the webapplication where it is used.
+ * Resolves a bundle that contains tld files as a URL. The URLs are
+ * used by jasper to discover the tld files.
*
* Support only 2 types of packaging for the bundle: - the bundle is a jar
* (recommended for runtime.) - the bundle is a folder and contain jars in
@@ -153,7 +121,7 @@ public class PluggableWebAppRegistrationCustomizerImpl implements WebappRegistra
* @param urls
* @throws Exception
*/
- private void registerTldBundle(BundleFileLocatorHelper locatorHelper, Bundle bundle, Set<URL> urls) throws Exception
+ private void convertBundleLocationToURL(BundleFileLocatorHelper locatorHelper, Bundle bundle, Set<URL> urls) throws Exception
{
File jasperLocation = locatorHelper.getBundleInstallLocation(bundle);
if (jasperLocation.isDirectory())
@@ -181,7 +149,5 @@ public class PluggableWebAppRegistrationCustomizerImpl implements WebappRegistra
{
urls.add(jasperLocation.toURI().toURL());
}
-
}
-
} \ No newline at end of file
diff --git a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/WebappRegistrationCustomizerImpl.java b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/JSTLBundleDiscoverer.java
index 7b744b99cd..23628c39e7 100644
--- a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/WebappRegistrationCustomizerImpl.java
+++ b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/JSTLBundleDiscoverer.java
@@ -34,7 +34,7 @@ import org.apache.jasper.xmlparser.ParserUtils;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
-import org.eclipse.jetty.osgi.boot.utils.WebappRegistrationCustomizer;
+import org.eclipse.jetty.osgi.boot.utils.TldBundleDiscoverer;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.osgi.framework.Bundle;
@@ -44,17 +44,20 @@ import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
+ *
+ * JSTLBundleDiscoverer
+ *
* Fix various shortcomings with the way jasper parses the tld files. Plugs the
* JSTL tlds assuming that they are packaged with the bundle that contains the
* JSTL classes.
* <p>
* Pluggable tlds at the server level are handled by
- * {@link PluggableWebAppRegistrationCustomizerImpl}.
+ * {@link ContainerTldBundleDiscoverer}.
* </p>
*/
-public class WebappRegistrationCustomizerImpl implements WebappRegistrationCustomizer
+public class JSTLBundleDiscoverer implements TldBundleDiscoverer
{
- private static final Logger LOG = Log.getLogger(WebappRegistrationCustomizerImpl.class);
+ private static final Logger LOG = Log.getLogger(JSTLBundleDiscoverer.class);
/**
@@ -83,7 +86,7 @@ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCusto
*/
private static String DEFAULT_JSP_FACTORY_IMPL_CLASS = "org.apache.jasper.runtime.JspFactoryImpl";
- public WebappRegistrationCustomizerImpl()
+ public JSTLBundleDiscoverer()
{
fixupDtdResolution();
@@ -136,7 +139,7 @@ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCusto
* @return array of URLs
* @throws Exception
*/
- public URL[] getJarsWithTlds(DeploymentManager deployer, BundleFileLocatorHelper locatorHelper) throws Exception
+ public URL[] getUrlsForBundlesWithTlds(DeploymentManager deployer, BundleFileLocatorHelper locatorHelper) throws Exception
{
ArrayList<URL> urls = new ArrayList<URL>();
@@ -148,7 +151,7 @@ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCusto
// So we can look for this class using this bundle's classloader:
try
{
- Class<?> jstlClass = WebappRegistrationCustomizerImpl.class.getClassLoader().loadClass(DEFAULT_JSTL_BUNDLE_CLASS);
+ Class<?> jstlClass = JSTLBundleDiscoverer.class.getClassLoader().loadClass(DEFAULT_JSTL_BUNDLE_CLASS);
classesToAddToTheTldBundles.add(jstlClass);
}
diff --git a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/FragmentActivator.java b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/FragmentActivator.java
index 9741d21c7d..b17270224f 100644
--- a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/FragmentActivator.java
+++ b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/FragmentActivator.java
@@ -19,21 +19,26 @@
package org.eclipse.jetty.osgi.boot.jsp;
import org.eclipse.jetty.osgi.boot.BundleWebAppProvider;
-import org.eclipse.jetty.osgi.boot.internal.webapp.WebBundleTrackerCustomizer;
-import org.eclipse.jetty.osgi.boot.jasper.PluggableWebAppRegistrationCustomizerImpl;
-import org.eclipse.jetty.osgi.boot.jasper.WebappRegistrationCustomizerImpl;
+import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
+import org.eclipse.jetty.osgi.boot.jasper.ContainerTldBundleDiscoverer;
+import org.eclipse.jetty.osgi.boot.jasper.JSTLBundleDiscoverer;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
/**
- * Pseudo fragment activator. Called by the main org.eclipse.jetty.osgi.boot
- * bundle. Please note: this is not a real BundleActivator. Simply something
- * called back by the host bundle.
- * <p>
- * It must be placed in the org.eclipse.jetty.osgi.boot.jsp package: this is
- * because org.eclipse.jetty.osgi.boot.jsp is the symbolic-name of this
- * fragment. From that name, the PackageadminTracker will call this class. IN a
- * different package it won't be called.
+ * FragmentActivator
+ *
+ * Sets up support for jsp. All relevant jsp jars must also be installed
+ * into the osgi environment.
+ * <p>
+ * Note that as this is part of a bundle fragment, this activator is NOT
+ * called by the OSGi environment. Instead, the org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminTracker
+ * simulates fragment activation and causes this class's start() method to
+ * be called.
+ * </p>
+ * <p>
+ * The package of this class MUST match the Bundle-SymbolicName of this fragment
+ * in order for the PackageAdminTracker to find it.
* </p>
*/
public class FragmentActivator implements BundleActivator
@@ -43,12 +48,14 @@ public class FragmentActivator implements BundleActivator
*/
public void start(BundleContext context) throws Exception
{
+ //jsr199 compilation does not work in osgi
System.setProperty("org.apache.jasper.compiler.disablejsr199", Boolean.TRUE.toString());
- WebBundleTrackerCustomizer.JSP_REGISTRATION_HELPERS.add(new WebappRegistrationCustomizerImpl());
- WebBundleTrackerCustomizer.JSP_REGISTRATION_HELPERS.add(new PluggableWebAppRegistrationCustomizerImpl());
- //Put in the support for the tag libs
- addTagLibSupport();
-
+
+ //set up some classes that will look for bundles with tlds that must be converted
+ //to urls and treated as if they are on the Jetty container's classpath so that
+ //jasper can deal with them
+ ServerInstanceWrapper.addContainerTldBundleDiscoverer(new JSTLBundleDiscoverer());
+ ServerInstanceWrapper.addContainerTldBundleDiscoverer(new ContainerTldBundleDiscoverer());
}
/**
@@ -58,12 +65,4 @@ public class FragmentActivator implements BundleActivator
{
}
-
- public void addTagLibSupport ()
- {
- String[] defaultConfigurations = new String[BundleWebAppProvider.getDefaultConfigurations().length+1];
- System.arraycopy(BundleWebAppProvider.getDefaultConfigurations(), 0, defaultConfigurations, 0, BundleWebAppProvider.getDefaultConfigurations().length);
- defaultConfigurations[defaultConfigurations.length-1] = "org.eclipse.jetty.osgi.boot.jsp.TagLibOSGiConfiguration";
- BundleWebAppProvider.setDefaultConfigurations(defaultConfigurations);
- }
}
diff --git a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml
index 59ce3cc2c7..5927ad5136 100644
--- a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml
+++ b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/jetty-osgi/jetty-osgi-boot/pom.xml b/jetty-osgi/jetty-osgi-boot/pom.xml
index 703ca92996..a630b1f33d 100644
--- a/jetty-osgi/jetty-osgi-boot/pom.xml
+++ b/jetty-osgi/jetty-osgi-boot/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-osgi-boot</artifactId>
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractContextProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractContextProvider.java
index 6f07480ab6..5d801c614e 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractContextProvider.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractContextProvider.java
@@ -22,14 +22,12 @@ import java.io.File;
import java.net.URL;
import java.util.Dictionary;
import java.util.HashMap;
-import java.util.Hashtable;
import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppProvider;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
import org.eclipse.jetty.osgi.boot.internal.webapp.BundleFileLocatorHelperFactory;
-import org.eclipse.jetty.osgi.boot.utils.EventSender;
import org.eclipse.jetty.osgi.boot.utils.OSGiClassLoader;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
@@ -37,11 +35,8 @@ import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.JarResource;
import org.eclipse.jetty.util.resource.Resource;
-import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.xml.XmlConfiguration;
import org.osgi.framework.Bundle;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.ServiceRegistration;
@@ -49,14 +44,15 @@ import org.osgi.framework.ServiceRegistration;
/**
* AbstractContextProvider
*
- *
+ * Base class for DeploymentManager Providers that can deploy ContextHandlers into
+ * Jetty that have been discovered via OSGI either as bundles or services.
+ *
*/
public abstract class AbstractContextProvider extends AbstractLifeCycle implements AppProvider
{
private static final Logger LOG = Log.getLogger(AbstractContextProvider.class);
- private DeploymentManager _deploymentManager;
-
+ private DeploymentManager _deploymentManager;
private ServerInstanceWrapper _serverWrapper;
@@ -65,7 +61,7 @@ public abstract class AbstractContextProvider extends AbstractLifeCycle implemen
/* ------------------------------------------------------------ */
/**
- * BundleApp
+ * OSGiApp
*
*
*/
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractOSGiApp.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractOSGiApp.java
index be09d2cfd6..b9e040b128 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractOSGiApp.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractOSGiApp.java
@@ -32,9 +32,10 @@ import org.osgi.framework.ServiceRegistration;
/**
- * AbstractBundleApp
- *
+ * AbstractOSGiApp
*
+ * Base class representing info about a webapp/ContextHandler that is deployed into Jetty.
+ *
*/
public abstract class AbstractOSGiApp extends App
{
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractWebAppProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractWebAppProvider.java
index 73da20f41c..cbae1c92d8 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractWebAppProvider.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractWebAppProvider.java
@@ -20,14 +20,9 @@ package org.eclipse.jetty.osgi.boot;
import java.io.File;
import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Map;
-
import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppProvider;
@@ -35,7 +30,6 @@ import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
import org.eclipse.jetty.osgi.boot.internal.webapp.BundleFileLocatorHelperFactory;
import org.eclipse.jetty.osgi.boot.internal.webapp.OSGiWebappClassLoader;
-import org.eclipse.jetty.osgi.boot.utils.EventSender;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
@@ -44,9 +38,7 @@ import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.xml.XmlConfiguration;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
import org.osgi.service.packageadmin.PackageAdmin;
@@ -55,7 +47,9 @@ import org.osgi.service.packageadmin.PackageAdmin;
/**
* AbstractWebAppProvider
*
- *
+ * Base class for Jetty DeploymentManager Providers that are capable of deploying a webapp,
+ * either from a bundle or an OSGi service.
+ *
*/
public abstract class AbstractWebAppProvider extends AbstractLifeCycle implements AppProvider
{
@@ -64,10 +58,9 @@ public abstract class AbstractWebAppProvider extends AbstractLifeCycle implement
public static String __defaultConfigurations[] = {
"org.eclipse.jetty.osgi.boot.OSGiWebInfConfiguration",
"org.eclipse.jetty.webapp.WebXmlConfiguration",
- "org.eclipse.jetty.osgi.boot.OSGiMetaInfConfiguration",
+ "org.eclipse.jetty.webapp.MetaInfConfiguration",
"org.eclipse.jetty.webapp.FragmentConfiguration",
- "org.eclipse.jetty.webapp.JettyWebXmlConfiguration"//,
- //"org.eclipse.jetty.osgi.boot.jsp.TagLibOSGiConfiguration"
+ "org.eclipse.jetty.webapp.JettyWebXmlConfiguration"
};
public static void setDefaultConfigurations (String[] defaultConfigs)
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleContextProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleContextProvider.java
index 149aa99b80..92dcbd45c2 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleContextProvider.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleContextProvider.java
@@ -26,16 +26,11 @@ import java.util.List;
import java.util.Map;
import org.eclipse.jetty.deploy.App;
-import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
-import org.eclipse.jetty.osgi.boot.utils.EventSender;
-import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.webapp.WebAppContext;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
@@ -43,7 +38,7 @@ import org.osgi.framework.ServiceRegistration;
/**
* BundleContextProvider
*
- * Handles deploying bundles that define a context xml file for configuring them.
+ * Handles deploying OSGi bundles that define a context xml file for configuring them.
*
*
*/
@@ -136,6 +131,7 @@ public class BundleContextProvider extends AbstractContextProvider implements Bu
}
apps.add(app);
getDeploymentManager().addApp(app);
+ added = true;
}
return added; //true if even 1 context from this bundle was added
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleProvider.java
index c87c071bf5..e1372697c0 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleProvider.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleProvider.java
@@ -20,6 +20,11 @@ package org.eclipse.jetty.osgi.boot;
import org.osgi.framework.Bundle;
+/**
+ * BundleProvider
+ *
+ * Jetty DeploymentManager Provider api for webapps or ContextHandlers that are discovered as osgi bundles.
+ */
public interface BundleProvider
{
public boolean bundleAdded (Bundle bundle) throws Exception;
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleWebAppProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleWebAppProvider.java
index 2a5e6e3cd0..ab38f29ac6 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleWebAppProvider.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleWebAppProvider.java
@@ -25,7 +25,6 @@ import java.util.Map;
import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
-import org.eclipse.jetty.osgi.boot.utils.EventSender;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.osgi.framework.Bundle;
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java
index 2ed6e7bf5e..8763ece7b9 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java
@@ -18,45 +18,35 @@
package org.eclipse.jetty.osgi.boot;
-import java.util.Dictionary;
-import java.util.Hashtable;
-
import org.eclipse.jetty.osgi.boot.internal.serverfactory.DefaultJettyAtJettyHomeHelper;
import org.eclipse.jetty.osgi.boot.internal.serverfactory.JettyServerServiceTracker;
-import org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper;
-import org.eclipse.jetty.osgi.boot.internal.webapp.JettyContextHandlerServiceTracker;
-import org.eclipse.jetty.osgi.boot.internal.webapp.WebBundleTrackerCustomizer;
+import org.eclipse.jetty.osgi.boot.internal.webapp.BundleWatcher;
+import org.eclipse.jetty.osgi.boot.internal.webapp.ServiceWatcher;
import org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminServiceTracker;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
-import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.BundleTracker;
/**
+ * JettyBootstrapActivator
+ *
* Bootstrap jetty and publish a default Server instance as an OSGi service.
*
* Listen for other Server instances to be published as services and support them as deployment targets.
*
- * Listen for Bundles to be activated, and deploy those that represent webapps to one of the known Server instances.
+ * Listen for Bundles to be activated, and deploy those that represent webapps/ContextHandlers to one of the known Server instances.
*
- * <ol>
- * <li>basic servlet [ok]</li>
- * <li>basic jetty.xml [ok]</li>
- * <li>basic jetty.xml and jetty-plus.xml [ok]</li>
- * <li>basic jsp [ok]</li>
- * <li>jsp with tag-libs [ok]</li>
- * <li>test-jndi with atomikos and derby inside ${jetty.home}/lib/ext [ok]</li>
- * </ul>
*/
public class JettyBootstrapActivator implements BundleActivator
{
-
+ private static final Logger LOG = Log.getLogger(JettyBootstrapActivator.class);
+
private static JettyBootstrapActivator INSTANCE = null;
public static JettyBootstrapActivator getInstance()
@@ -66,7 +56,7 @@ public class JettyBootstrapActivator implements BundleActivator
private ServiceRegistration _registeredServer;
- private JettyContextHandlerServiceTracker _jettyContextHandlerTracker;
+ private ServiceWatcher _jettyContextHandlerTracker;
private PackageAdminServiceTracker _packageAdminServiceTracker;
@@ -75,7 +65,10 @@ public class JettyBootstrapActivator implements BundleActivator
private BundleContext _bundleContext;
private JettyServerServiceTracker _jettyServerServiceTracker;
-
+
+
+
+ /* ------------------------------------------------------------ */
/**
* Setup a new jetty Server, registers it as a service. Setup the Service
* tracker for the jetty ContextHandlers that are in charge of deploying the
@@ -84,7 +77,7 @@ public class JettyBootstrapActivator implements BundleActivator
*
* @param context
*/
- public void start(BundleContext context) throws Exception
+ public void start(final BundleContext context) throws Exception
{
INSTANCE = this;
_bundleContext = context;
@@ -98,18 +91,23 @@ public class JettyBootstrapActivator implements BundleActivator
context.addServiceListener(_jettyServerServiceTracker, "(objectclass=" + Server.class.getName() + ")");
// track ContextHandler class instances and deploy them to one of the known Servers
- _jettyContextHandlerTracker = new JettyContextHandlerServiceTracker();
+ _jettyContextHandlerTracker = new ServiceWatcher();
context.addServiceListener(_jettyContextHandlerTracker, "(objectclass=" + ContextHandler.class.getName() + ")");
// Create a default jetty instance right now.
- DefaultJettyAtJettyHomeHelper.startJettyAtJettyHome(context);
-
- // track Bundles and deploy those that represent webapps to one of the known Servers
- WebBundleTrackerCustomizer customizer = new WebBundleTrackerCustomizer();
- _webBundleTracker = new BundleTracker(context, Bundle.ACTIVE | Bundle.STOPPING, customizer);
- customizer.setAndOpenWebBundleTracker(_webBundleTracker);
+ Server defaultServer = DefaultJettyAtJettyHomeHelper.startJettyAtJettyHome(context);
+
+ //Create a bundle tracker to help deploy webapps and ContextHandlers
+ BundleWatcher bundleTrackerCustomizer = new BundleWatcher();
+ bundleTrackerCustomizer.setWaitForDefaultServer(defaultServer != null);
+ _webBundleTracker = new BundleTracker(context, Bundle.ACTIVE | Bundle.STOPPING, bundleTrackerCustomizer);
+ bundleTrackerCustomizer.setBundleTracker(_webBundleTracker);
+ bundleTrackerCustomizer.open();
}
-
+
+
+
+ /* ------------------------------------------------------------ */
/**
* Stop the activator.
*
@@ -120,7 +118,6 @@ public class JettyBootstrapActivator implements BundleActivator
{
try
{
-
if (_webBundleTracker != null)
{
_webBundleTracker.close();
@@ -164,122 +161,4 @@ public class JettyBootstrapActivator implements BundleActivator
INSTANCE = null;
}
}
-
- /**
- * Helper method that creates a new org.jetty.webapp.WebAppContext and
- * registers it as an OSGi service. The tracker
- * {@link JettyContextHandlerServiceTracker} will do the actual deployment.
- *
- * @param contributor The bundle
- * @param webappFolderPath The path to the root of the webapp. Must be a
- * path relative to bundle; either an absolute path.
- * @param contextPath The context path. Must start with "/"
- * @throws Exception
- */
- public static void registerWebapplication(Bundle contributor, String webappFolderPath, String contextPath) throws Exception
- {
- checkBundleActivated();
- WebAppContext contextHandler = new WebAppContext();
- Dictionary<String,String> dic = new Hashtable<String,String>();
- dic.put(OSGiWebappConstants.SERVICE_PROP_WAR, webappFolderPath);
- dic.put(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH, contextPath);
- String requireTldBundle = (String) contributor.getHeaders().get(OSGiWebappConstants.REQUIRE_TLD_BUNDLE);
- if (requireTldBundle != null)
- {
- dic.put(OSGiWebappConstants.SERVICE_PROP_REQUIRE_TLD_BUNDLE, requireTldBundle);
- }
- contributor.getBundleContext().registerService(ContextHandler.class.getName(), contextHandler, dic);
- }
-
- /**
- * Helper method that creates a new org.jetty.webapp.WebAppContext and
- * registers it as an OSGi service. The tracker
- * {@link JettyContextHandlerServiceTracker} will do the actual deployment.
- *
- * @param contributor The bundle
- * @param webappFolderPath The path to the root of the webapp. Must be a
- * path relative to bundle; either an absolute path.
- * @param contextPath The context path. Must start with "/"
- * @param dic TODO: parameter description
- * @throws Exception
- */
- public static void registerWebapplication(Bundle contributor, String webappFolderPath, String contextPath, Dictionary<String, String> dic) throws Exception
- {
- checkBundleActivated();
- WebAppContext contextHandler = new WebAppContext();
- dic.put(OSGiWebappConstants.SERVICE_PROP_WAR, webappFolderPath);
- dic.put(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH, contextPath);
- contributor.getBundleContext().registerService(ContextHandler.class.getName(), contextHandler, dic);
- }
-
- /**
- * Helper method that creates a new skeleton of a ContextHandler and
- * registers it as an OSGi service. The tracker
- * {@link JettyContextHandlerServiceTracker} will do the actual deployment.
- *
- * @param contributor The bundle that registers a new context
- * @param contextFilePath The path to the file inside the bundle that
- * defines the context.
- * @throws Exception
- */
- public static void registerContext(Bundle contributor, String contextFilePath) throws Exception
- {
- registerContext(contributor, contextFilePath, new Hashtable<String, String>());
- }
-
- /**
- * Helper method that creates a new skeleton of a ContextHandler and
- * registers it as an OSGi service. The tracker
- * {@link JettyContextHandlerServiceTracker} will do the actual deployment.
- *
- * @param contributor The bundle that registers a new context
- * @param contextFilePath The path to the file inside the bundle that
- * defines the context.
- * @param dic TODO: parameter description
- * @throws Exception
- */
- public static void registerContext(Bundle contributor, String contextFilePath, Dictionary<String, String> dic) throws Exception
- {
- checkBundleActivated();
- ContextHandler contextHandler = new ContextHandler();
- dic.put(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH, contextFilePath);
- dic.put(IWebBundleDeployerHelper.INTERNAL_SERVICE_PROP_UNKNOWN_CONTEXT_HANDLER_TYPE, Boolean.TRUE.toString());
- contributor.getBundleContext().registerService(ContextHandler.class.getName(), contextHandler, dic);
- }
-
- public static void unregister(String contextPath)
- {
- // todo
- }
-
- /**
- * Since org.eclipse.jetty.osgi.boot does not have a lazy activation policy
- * when one of the static methods to register a webapp is called we should
- * make sure that the bundle is started.
- */
- private static void checkBundleActivated()
- {
- if (INSTANCE == null)
- {
- Bundle thisBundle = FrameworkUtil.getBundle(JettyBootstrapActivator.class);
- try
- {
- thisBundle.start();
- }
- catch (BundleException e)
- {
- // nevermind.
- }
- }
- }
-
- /**
- * @return The bundle context for this bundle.
- */
- public static BundleContext getBundleContext()
- {
- checkBundleActivated();
- return INSTANCE._bundleContext;
- }
-
}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiDeployer.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiDeployer.java
index 5f9321ebc9..1b80e04edd 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiDeployer.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiDeployer.java
@@ -27,7 +27,9 @@ import org.eclipse.jetty.osgi.boot.utils.EventSender;
/**
* OSGiDeployer
*
- *
+ * Extension of standard Jetty deployer that emits OSGi EventAdmin
+ * events whenever a webapp is deployed into OSGi via Jetty.
+ *
*/
public class OSGiDeployer extends StandardDeployer
{
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiMetaInfConfiguration.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiMetaInfConfiguration.java
index bacc8ea9a0..9767bd310c 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiMetaInfConfiguration.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiMetaInfConfiguration.java
@@ -32,6 +32,14 @@ import org.eclipse.jetty.webapp.MetaInfConfiguration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.osgi.framework.Bundle;
+/**
+ * OSGiMetaInfConfiguration
+ *
+ * Extension of standard Jetty MetaInfConfiguration class to handle OSGi bundle
+ * fragments that may also need to be scanned for META-INF info.
+ *
+ * @deprecated
+ */
public class OSGiMetaInfConfiguration extends MetaInfConfiguration
{
private static final Logger LOG = Log.getLogger(OSGiMetaInfConfiguration.class);
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiServerConstants.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiServerConstants.java
index 2f9df55ad8..67ef323aee 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiServerConstants.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiServerConstants.java
@@ -19,6 +19,8 @@
package org.eclipse.jetty.osgi.boot;
/**
+ * OSGiServerConstants
+ *
* Name of the properties that configure a jetty Server OSGi service.
*/
public class OSGiServerConstants
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiUndeployer.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiUndeployer.java
index ac068741d0..674f960b23 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiUndeployer.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiUndeployer.java
@@ -29,7 +29,9 @@ import org.eclipse.jetty.osgi.boot.utils.EventSender;
/**
* OSGiUndeployer
*
- *
+ * Extension of the Jetty Undeployer which emits OSGi EventAdmin events
+ * whenever a webapp is undeployed from Jetty.
+ *
*/
public class OSGiUndeployer extends StandardUndeployer
{
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebInfConfiguration.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebInfConfiguration.java
index 988ebb244f..76eb8ade44 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebInfConfiguration.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebInfConfiguration.java
@@ -52,7 +52,7 @@ public class OSGiWebInfConfiguration extends WebInfConfiguration
public static final String CONTAINER_BUNDLE_PATTERN = "org.eclipse.jetty.server.webapp.containerIncludeBundlePattern";
-
+ /* ------------------------------------------------------------ */
/**
* Check to see if there have been any bundle symbolic names added of bundles that should be
* regarded as being on the container classpath, and scanned for fragments, tlds etc etc.
@@ -120,7 +120,7 @@ public class OSGiWebInfConfiguration extends WebInfConfiguration
}
-
+ /* ------------------------------------------------------------ */
/**
* Consider the fragment bundles associated with the bundle of the webapp being deployed.
*
@@ -148,7 +148,7 @@ public class OSGiWebInfConfiguration extends WebInfConfiguration
return mergedResources;
}
-
+ /* ------------------------------------------------------------ */
/**
* Allow fragments to supply some resources that are added to the baseResource of the webapp.
*
@@ -227,11 +227,10 @@ public class OSGiWebInfConfiguration extends WebInfConfiguration
resources[resources.length-1] = context.getBaseResource();
context.setBaseResource(new ResourceCollection(resources));
}
-
}
-
+ /* ------------------------------------------------------------ */
/**
* Resolves the bundle. Usually that would be a single URL per bundle. But we do some more work if there are jars
* embedded in the bundle.
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java
index 1908eb2de5..e97457aecd 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java
@@ -19,7 +19,12 @@
package org.eclipse.jetty.osgi.boot;
/**
- * Name of the service properties for a ContextHandler that configure a webapp deployed on jetty OSGi.
+ * OSGiWebappConstants
+ *
+ *
+ * Constants (MANIFEST headers, service properties etc) associated with deploying
+ * webapps into OSGi via Jetty.
+ *
*/
public class OSGiWebappConstants
{
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceContextProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceContextProvider.java
index 2e36904fc4..a228a6288d 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceContextProvider.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceContextProvider.java
@@ -38,7 +38,9 @@ import org.osgi.framework.ServiceRegistration;
/**
* ServiceContextProvider
*
- *
+ * Jetty DeploymentManager Provider that is able to deploy ContextHandlers discovered via OSGi as services.
+ *
+ *
*/
public class ServiceContextProvider extends AbstractContextProvider implements ServiceProvider
{
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceProvider.java
index f2304c6b13..34335cf31b 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceProvider.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceProvider.java
@@ -21,6 +21,11 @@ package org.eclipse.jetty.osgi.boot;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.osgi.framework.ServiceReference;
+/**
+ * ServiceProvider
+ *
+ * Jetty DeploymentManager Provider api for webapps or ContextHandlers that are discovered as OSGi services.
+ */
public interface ServiceProvider
{
public boolean serviceAdded (ServiceReference ref, ContextHandler handler) throws Exception;
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceWebAppProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceWebAppProvider.java
index e3f97f0913..6008aa033c 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceWebAppProvider.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceWebAppProvider.java
@@ -27,7 +27,6 @@ import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppProvider;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
-import org.eclipse.jetty.osgi.boot.utils.EventSender;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/jsp/TldLocatableURLClassloaderWithInsertedJettyClassloader.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/jsp/TldLocatableURLClassloaderWithInsertedJettyClassloader.java
deleted file mode 100644
index e4cf805aac..0000000000
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/jsp/TldLocatableURLClassloaderWithInsertedJettyClassloader.java
+++ /dev/null
@@ -1,69 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2013 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.osgi.boot.internal.jsp;
-
-import java.net.URL;
-
-/**
- * Add a classloader to the
- * org.apache.jasper.compiler.TldLocatableURLClassloader. Hopefuly not
- * necessary: still experimenting.
- *
- * @see TldLocatableURLClassloader
- */
-public class TldLocatableURLClassloaderWithInsertedJettyClassloader extends TldLocatableURLClassloader
-{
-
- private ClassLoader _internalClassLoader;
-
- /**
- *
- * @param osgiClassLoaderParent
- * The parent classloader
- * @param internalClassLoader
- * The classloader that will be at the same level than the
- * jarsWithTldsInside
- * @param jarsWithTldsInside
- * jars that are scanned for tld files.
- */
- public TldLocatableURLClassloaderWithInsertedJettyClassloader(ClassLoader osgiClassLoaderParent, ClassLoader internalClassLoader, URL[] jarsWithTldsInside)
- {
- super(osgiClassLoaderParent,jarsWithTldsInside);
- _internalClassLoader = internalClassLoader;
- }
-
- protected Class<?> findClass(String name) throws ClassNotFoundException
- {
- try
- {
- return super.findClass(name);
- }
- catch (ClassNotFoundException cne)
- {
- if (_internalClassLoader != null)
- {
- return _internalClassLoader.loadClass(name);
- }
- else
- {
- throw cne;
- }
- }
- }
-}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java
index bef4dcf373..a89ff5b730 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java
@@ -29,7 +29,6 @@ import java.util.StringTokenizer;
import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
import org.eclipse.jetty.osgi.boot.internal.webapp.BundleFileLocatorHelperFactory;
-import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -40,9 +39,12 @@ import org.osgi.framework.BundleContext;
* DefaultJettyAtJettyHomeHelper
*
*
+ * Creates a default instance of Jetty, based on the values of the
+ * System properties "jetty.home" or "jetty.home.bundle", one of which
+ * must be specified in order to create the default instance.
+ *
* Called by the {@link JettyBootstrapActivator} during the starting of the
- * bundle. If the system property 'jetty.home' is defined and points to a
- * folder, then setup the corresponding jetty server.
+ * bundle.
*/
public class DefaultJettyAtJettyHomeHelper
{
@@ -64,6 +66,7 @@ public class DefaultJettyAtJettyHomeHelper
public static final String DEFAULT_JETTYHOME = "/jettyhome/";
+
/* ------------------------------------------------------------ */
/**
* Called by the JettyBootStrapActivator. If the system property jetty.home
@@ -87,7 +90,7 @@ public class DefaultJettyAtJettyHomeHelper
* as part of their properties.
* </p>
*/
- public static void startJettyAtJettyHome(BundleContext bundleContext) throws Exception
+ public static Server startJettyAtJettyHome(BundleContext bundleContext) throws Exception
{
String jettyHomeSysProp = System.getProperty(OSGiServerConstants.JETTY_HOME);
String jettyHomeBundleSysProp = System.getProperty(OSGiServerConstants.JETTY_HOME_BUNDLE);
@@ -109,7 +112,7 @@ public class DefaultJettyAtJettyHomeHelper
if (!jettyHome.exists() || !jettyHome.isDirectory())
{
LOG.warn("Unable to locate the jetty.home folder " + jettyHomeSysProp);
- return;
+ return null;
}
}
else if (jettyHomeBundleSysProp != null)
@@ -126,14 +129,14 @@ public class DefaultJettyAtJettyHomeHelper
if (jettyHomeBundle == null)
{
LOG.warn("Unable to find the jetty.home.bundle named " + jettyHomeSysProp);
- return;
+ return null;
}
}
if (jettyHome == null && jettyHomeBundle == null)
{
LOG.warn("No default jetty created.");
- return;
+ return null;
}
Server server = new Server();
@@ -152,8 +155,11 @@ public class DefaultJettyAtJettyHomeHelper
setProperty(properties, OSGiServerConstants.JETTY_PORT, System.getProperty(OSGiServerConstants.JETTY_PORT));
setProperty(properties, OSGiServerConstants.JETTY_PORT_SSL, System.getProperty(OSGiServerConstants.JETTY_PORT_SSL));
- //register the Server instance as an OSGi service.
+ //Register the default Server instance as an OSGi service.
+ //The JettyServerServiceTracker will notice it and configure it.
bundleContext.registerService(Server.class.getName(), server, properties);
+
+ return server;
}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java
index e172c75197..b946cd8da4 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java
@@ -32,8 +32,11 @@ import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
/**
- * Deploy the jetty server instances when they are registered as an OSGi
- * service.
+ * JettyServerServiceTracker
+ *
+ * Tracks instances of Jetty Servers, and configures them so that they can deploy
+ * webapps or ContextHandlers discovered from the OSGi environment.
+ *
*/
public class JettyServerServiceTracker implements ServiceListener, IManagedJettyServerRegistry
{
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java
index a7e9daaa2e..209fee6d9d 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java
@@ -19,7 +19,6 @@
package org.eclipse.jetty.osgi.boot.internal.serverfactory;
import java.io.File;
-import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
@@ -27,8 +26,10 @@ import java.util.Collection;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.StringTokenizer;
import org.eclipse.jetty.deploy.AppLifeCycle;
@@ -44,11 +45,10 @@ import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
import org.eclipse.jetty.osgi.boot.OSGiUndeployer;
import org.eclipse.jetty.osgi.boot.ServiceContextProvider;
import org.eclipse.jetty.osgi.boot.ServiceWebAppProvider;
-import org.eclipse.jetty.osgi.boot.internal.jsp.TldLocatableURLClassloader;
import org.eclipse.jetty.osgi.boot.internal.webapp.BundleFileLocatorHelperFactory;
import org.eclipse.jetty.osgi.boot.internal.webapp.LibExtClassLoaderHelper;
-import org.eclipse.jetty.osgi.boot.internal.webapp.WebBundleTrackerCustomizer;
-import org.eclipse.jetty.osgi.boot.utils.WebappRegistrationCustomizer;
+import org.eclipse.jetty.osgi.boot.utils.FakeURLClassLoader;
+import org.eclipse.jetty.osgi.boot.utils.TldBundleDiscoverer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.util.IO;
@@ -72,6 +72,9 @@ public class ServerInstanceWrapper
* support the case where the bundle is zipped.
*/
public static final String PROPERTY_THIS_JETTY_XML_FOLDER_URL = "this.jetty.xml.parent.folder.url";
+
+
+ private static Collection<TldBundleDiscoverer> __containerTldBundleDiscoverers = new ArrayList<TldBundleDiscoverer>();
private static Logger LOG = Log.getLogger(ServerInstanceWrapper.class.getName());
@@ -96,6 +99,21 @@ public class ServerInstanceWrapper
private DeploymentManager _deploymentManager;
+
+ /* ------------------------------------------------------------ */
+ public static void addContainerTldBundleDiscoverer (TldBundleDiscoverer tldBundleDiscoverer)
+ {
+ __containerTldBundleDiscoverers.add(tldBundleDiscoverer);
+ }
+
+ /* ------------------------------------------------------------ */
+ public static Collection<TldBundleDiscoverer> getContainerTldBundleDiscoverers()
+ {
+ return __containerTldBundleDiscoverers;
+ }
+
+
+
/* ------------------------------------------------------------ */
public ServerInstanceWrapper(String managedServerName)
{
@@ -173,9 +191,29 @@ public class ServerInstanceWrapper
configure(server, props);
init();
+
+ //if support for jsp is enabled, we need to convert locations of bundles that contain tlds into urls.
+ //these are tlds that we want jasper to treat as if they are on the container's classpath. Web bundles
+ //can use the Require-TldBundle MANIFEST header to name other tld-containing bundles that should be regarded
+ //as on the webapp classpath.
+ if (!__containerTldBundleDiscoverers.isEmpty())
+ {
+ Set<URL> urls = new HashSet<URL>();
+ //discover bundles with tlds that need to be on the container's classpath as URLs
+ for (TldBundleDiscoverer d:__containerTldBundleDiscoverers)
+ {
+ URL[] list = d.getUrlsForBundlesWithTlds(_deploymentManager, BundleFileLocatorHelperFactory.getFactory().getHelper());
+ if (list != null)
+ {
+ for (URL u:list)
+ urls.add(u);
+ }
+ }
+ _commonParentClassLoaderForWebapps = new FakeURLClassLoader(libExtClassLoader, urls.toArray(new URL[urls.size()]));
+ }
+ else
+ _commonParentClassLoaderForWebapps = libExtClassLoader;
- URL[] jarsWithTlds = getJarsWithTlds();
- _commonParentClassLoaderForWebapps = jarsWithTlds == null ? libExtClassLoader : new TldLocatableURLClassloader(libExtClassLoader, jarsWithTlds);
if (LOG.isDebugEnabled()) LOG.debug("common classloader = "+_commonParentClassLoaderForWebapps);
@@ -219,54 +257,7 @@ public class ServerInstanceWrapper
}
- /* ------------------------------------------------------------ */
- /**
- * TODO: right now only the jetty-jsp bundle is scanned for common taglibs.
- * Should support a way to plug more bundles that contain taglibs.
- *
- * The jasper TldScanner expects a URLClassloader to parse a jar for the
- * /META-INF/*.tld it may contain. We place the bundles that we know contain
- * such tag-libraries. Please note that it will work if and only if the
- * bundle is a jar (!) Currently we just hardcode the bundle that contains
- * the jstl implementation.
- *
- * A workaround when the tld cannot be parsed with this method is to copy
- * and paste it inside the WEB-INF of the webapplication where it is used.
- *
- * Support only 2 types of packaging for the bundle: - the bundle is a jar
- * (recommended for runtime.) - the bundle is a folder and contain jars in
- * the root and/or in the lib folder (nice for PDE development situations)
- * Unsupported: the bundle is a jar that embeds more jars.
- *
- * @return
- * @throws Exception
- */
- private URL[] getJarsWithTlds() throws Exception
- {
-
- //Jars that are added onto the equivalent of the container classpath are:
- // jstl jars: identified by the class WhenTag (and the boot-bundle manifest imports the jstl packages
- // bundles identified by System property org.eclipse.jetty.osgi.tldbundles
- // bundle symbolic name patterns defined in the DeploymentManager
- //
- // Any bundles mentioned in the Require-TldBundle manifest header of the webapp bundle MUST ALSO HAVE Import-Bundle
- // in order to get them onto the classpath of the webapp.
-
- ArrayList<URL> res = new ArrayList<URL>();
- for (WebappRegistrationCustomizer regCustomizer : WebBundleTrackerCustomizer.JSP_REGISTRATION_HELPERS)
- {
- URL[] urls = regCustomizer.getJarsWithTlds(_deploymentManager, BundleFileLocatorHelperFactory.getFactory().getHelper());
- for (URL url : urls)
- {
- if (!res.contains(url)) res.add(url);
- }
- }
- if (!res.isEmpty())
- return res.toArray(new URL[res.size()]);
- else
- return null;
- }
-
+
/* ------------------------------------------------------------ */
private void configure(Server server, Dictionary props) throws Exception
@@ -340,7 +331,9 @@ public class ServerInstanceWrapper
}
}
-
+
+
+ /* ------------------------------------------------------------ */
/**
* Must be called after the server is configured.
*
@@ -438,7 +431,9 @@ public class ServerInstanceWrapper
}
}
}
-
+
+
+ /* ------------------------------------------------------------ */
/**
* @return The default folder in which the context files of the osgi bundles
* are located and watched. Or null when the system property
@@ -463,7 +458,7 @@ public class ServerInstanceWrapper
return new File(jettyHome, "/contexts");
}
-
+ /* ------------------------------------------------------------ */
/**
* @return the urls in this string.
*/
@@ -485,7 +480,9 @@ public class ServerInstanceWrapper
}
return urls;
}
-
+
+
+ /* ------------------------------------------------------------ */
/**
* Get the folders that might contain jars for the legacy J2EE shared
* libraries
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleTrackerCustomizer.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/BundleWatcher.java
index b8adc65705..74622c36b1 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleTrackerCustomizer.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/BundleWatcher.java
@@ -21,10 +21,14 @@ package org.eclipse.jetty.osgi.boot.internal.webapp;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
import org.eclipse.jetty.osgi.boot.BundleProvider;
import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
-import org.eclipse.jetty.osgi.boot.utils.WebappRegistrationCustomizer;
+import org.eclipse.jetty.osgi.boot.utils.TldBundleDiscoverer;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.osgi.framework.Bundle;
@@ -36,53 +40,128 @@ import org.osgi.util.tracker.BundleTrackerCustomizer;
import org.osgi.util.tracker.ServiceTracker;
/**
- * WebBundleTrackerCustomizer
+ * BundleWatcher
*
*
- * Support bundles that declare a webpp or context directly through headers in their
- * manifest. They will be deployed to the default jetty Server instance.
- *
- * If you wish to deploy a context or webapp to a different jetty Server instance,
- * register your context/webapp as an osgi service, and set the property OSGiServerConstants.MANAGED_JETTY_SERVER_NAME
- * with the name of the Server instance you wish to depoy to.
+ * Tracks the installation and removal of Bundles in the OSGi environment. Any bundles
+ * that are added are passed to the set of Jetty DeploymentManager providers to see if
+ * the bundle should be deployed as a webapp or ContextHandler into Jetty.
*
* @author hmalphettes
*/
-public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer
+public class BundleWatcher implements BundleTrackerCustomizer
{
- private static final Logger LOG = Log.getLogger(WebBundleTrackerCustomizer.class);
+ private static final Logger LOG = Log.getLogger(BundleWatcher.class);
- public static Collection<WebappRegistrationCustomizer> JSP_REGISTRATION_HELPERS = new ArrayList<WebappRegistrationCustomizer>();
- public static final String FILTER = "(&(objectclass=" + BundleProvider.class.getName() + ")"+
- "("+OSGiServerConstants.MANAGED_JETTY_SERVER_NAME+"="+OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME+"))";
+ public static Collection<TldBundleDiscoverer> JSP_REGISTRATION_HELPERS = new ArrayList<TldBundleDiscoverer>();
+
+ public static final String FILTER = "(objectclass=" + BundleProvider.class.getName() + ")";
private ServiceTracker _serviceTracker;
private BundleTracker _bundleTracker;
+ private boolean _waitForDefaultServer = true;
+ private boolean _defaultServerReady = false;
+ private Bundle _bundle = null;
+
+
/* ------------------------------------------------------------ */
/**
* @throws Exception
*/
- public WebBundleTrackerCustomizer ()
- throws Exception
+ public BundleWatcher() throws Exception
{
- Bundle myBundle = FrameworkUtil.getBundle(this.getClass());
-
- //track all instances of deployers of webapps/contexts as bundles
- _serviceTracker = new ServiceTracker(myBundle.getBundleContext(), FrameworkUtil.createFilter(FILTER),null) {
- public Object addingService(ServiceReference reference) {
- Object object = super.addingService(reference);
- LOG.debug("Deployer registered {}", reference);
- openBundleTracker();
- return object;
- }
- };
+ _bundle = FrameworkUtil.getBundle(this.getClass());
+ //Track all BundleProviders (Jetty DeploymentManager Providers that can deploy bundles)
+ _serviceTracker = new ServiceTracker(_bundle.getBundleContext(), FrameworkUtil.createFilter(FILTER),null);
_serviceTracker.open();
+ }
+
+
+ /* ------------------------------------------------------------ */
+ public boolean isWaitForDefaultServer()
+ {
+ return _waitForDefaultServer;
+ }
+
+ /* ------------------------------------------------------------ */
+ public void setWaitForDefaultServer(boolean waitForDefaultServer)
+ {
+ _waitForDefaultServer = waitForDefaultServer;
}
+
+ /* ------------------------------------------------------------ */
+ public void setBundleTracker (BundleTracker bundleTracker)
+ {
+ _bundleTracker = bundleTracker;
+ }
+
/* ------------------------------------------------------------ */
+ public void open () throws Exception
+ {
+ if (_waitForDefaultServer && !_defaultServerReady)
+ {
+ String filter = "(&(objectclass=" + BundleProvider.class.getName() + ")"+
+ "("+OSGiServerConstants.MANAGED_JETTY_SERVER_NAME+"="+OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME+"))";
+
+ ServiceTracker defaultServerTracker = new ServiceTracker(_bundle.getBundleContext(),
+ FrameworkUtil.createFilter(filter),null)
+ {
+ public Object addingService(ServiceReference reference)
+ {
+ try
+ {
+ Object object = super.addingService(reference);
+ LOG.debug("Default Jetty Server registered {}", reference);
+ _defaultServerReady = true;
+ openBundleTracker();
+ return object;
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException(e);
+ }
+ }
+ };
+ defaultServerTracker.open();
+ }
+ else
+ openBundleTracker();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param managedServerName
+ * @return
+ */
+ public Map<ServiceReference, BundleProvider> getDeployers(String managedServerName)
+ {
+ if (managedServerName == null)
+ managedServerName = OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME;
+
+ Map<ServiceReference, BundleProvider> candidates = new HashMap<ServiceReference, BundleProvider>();
+
+ ServiceReference[] references = _serviceTracker.getServiceReferences();
+ if (references != null)
+ {
+ for (ServiceReference ref:references)
+ {
+ String name = (String)ref.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
+ if (managedServerName.equalsIgnoreCase(name))
+ {
+ BundleProvider candidate = (BundleProvider)_serviceTracker.getService(ref);
+ if (candidate != null)
+ candidates.put(ref, candidate);
+ }
+ }
+ }
+ return candidates;
+ }
+
+ /* ------------------------------------------------------------ */
/**
* A bundle is being added to the <code>BundleTracker</code>.
*
@@ -138,8 +217,6 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer
*/
public void modifiedBundle(Bundle bundle, BundleEvent event, Object object)
{
- // nothing the web-bundle was already track. something changed.
- // we only reload the webapps if the bundle is stopped and restarted.
if (bundle.getState() == Bundle.STOPPING || bundle.getState() == Bundle.ACTIVE)
{
unregister(bundle);
@@ -171,35 +248,40 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer
}
+ protected void openBundleTracker()
+ {
+ _bundleTracker.open();
+ }
+
/* ------------------------------------------------------------ */
/**
* @param bundle
- * @return true if this bundle in indeed a web-bundle.
+ * @return true if this bundle can be deployed into Jetty
*/
private boolean register(Bundle bundle)
{
if (bundle == null)
return false;
- //It might be a bundle that we can deploy to our default jetty server instance
+ //It might be a bundle that is deployable by Jetty.
+ //Use any named Server instance provided, defaulting to the default Server instance if none supplied
boolean deployed = false;
- Object[] deployers = _serviceTracker.getServices();
- if (deployers != null)
+ String serverName = (String)bundle.getHeaders().get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
+ Map<ServiceReference, BundleProvider> candidates = getDeployers(serverName);
+ if (candidates != null)
{
- int i=0;
- while (!deployed && i<deployers.length)
+ Iterator<Entry<ServiceReference, BundleProvider>> itor = candidates.entrySet().iterator();
+ while (!deployed && itor.hasNext())
{
-
- BundleProvider p = (BundleProvider)deployers[i];
+ Entry<ServiceReference, BundleProvider> e = itor.next();
try
- {
- deployed = p.bundleAdded(bundle);
+ {
+ deployed = e.getValue().bundleAdded(bundle);
}
catch (Exception x)
{
LOG.warn("Error deploying bundle for jetty context", x);
}
- i++;
}
}
@@ -212,39 +294,24 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer
*/
private void unregister(Bundle bundle)
{
- Object[] deployers = _serviceTracker.getServices();
boolean undeployed = false;
- if (deployers != null)
+ String serverName = (String)bundle.getHeaders().get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
+ Map<ServiceReference, BundleProvider> candidates = getDeployers(serverName);
+ if (candidates != null)
{
- int i=0;
- while (!undeployed && i<deployers.length)
+ Iterator<Entry<ServiceReference, BundleProvider>> itor = candidates.entrySet().iterator();
+ while (!undeployed && itor.hasNext())
{
+ Entry<ServiceReference, BundleProvider> e = itor.next();
try
{
- undeployed = ((BundleProvider)deployers[i++]).bundleRemoved(bundle);
+ undeployed = e.getValue().bundleRemoved(bundle);
}
catch (Exception x)
{
- LOG.warn("Error undeploying bundle for jetty context", x);
+ LOG.warn("Error undeploying Bundle representing jetty deployable ", x);
}
}
}
}
-
- public void setAndOpenWebBundleTracker(BundleTracker bundleTracker) {
- if(_bundleTracker == null) {
- _bundleTracker = bundleTracker;
- LOG.debug("Bundle tracker is set");
- openBundleTracker();
- }
- }
-
- private void openBundleTracker() {
- if(_bundleTracker != null && _serviceTracker.getServices() != null &&
- _serviceTracker.getServices().length > 0) {
- _bundleTracker.open();
- LOG.debug("Bundle tracker has been opened");
- }
- }
-
}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/IWebBundleDeployerHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/IWebBundleDeployerHelper.java
deleted file mode 100644
index 1c5cd3e6c0..0000000000
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/IWebBundleDeployerHelper.java
+++ /dev/null
@@ -1,88 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2013 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.osgi.boot.internal.webapp;
-
-
-import org.eclipse.jetty.server.handler.ContextHandler;
-import org.eclipse.jetty.webapp.WebAppContext;
-import org.osgi.framework.Bundle;
-
-/**
- * Internal interface for the class that deploys a webapp on a server. Used as
- * we migrate from the single instance of the jety server to multiple jetty
- * servers.
- */
-public interface IWebBundleDeployerHelper
-{
-
- /**
- * when this property is present, the type of context handler registered is
- * not known in advance.
- */
- public static final String INTERNAL_SERVICE_PROP_UNKNOWN_CONTEXT_HANDLER_TYPE = "unknownContextHandlerType";
-
- /**
- * Deploy a new web application on the jetty server.
- *
- * @param bundle The bundle
- * @param webappFolderPath The path to the root of the webapp. Must be a
- * path relative to bundle; either an absolute path.
- * @param contextPath The context path. Must start with "/"
- * @param extraClasspath
- * @param overrideBundleInstallLocation
- * @param requireTldBundle The list of bundles's symbolic names that contain
- * tld files that are required by this WAB.
- * @param webXmlPath
- * @param defaultWebXmlPath TODO: parameter description
- * @return The contexthandler created and started
- * @throws Exception
- */
- public abstract WebAppContext registerWebapplication(Bundle bundle, String webappFolderPath, String contextPath, String extraClasspath,
- String overrideBundleInstallLocation, String requireTldBundle, String webXmlPath,
- String defaultWebXmlPath, WebAppContext webAppContext) throws Exception;
-
- /**
- * Stop a ContextHandler and remove it from the collection.
- *
- * @see ContextDeployer#undeploy
- * @param contextHandler
- * @throws Exception
- */
- public abstract void unregister(ContextHandler contextHandler) throws Exception;
-
- /**
- * This type of registration relies on jetty's complete context xml file.
- * Context encompasses jndi and all other things. This makes the definition
- * of the webapp a lot more self-contained.
- *
- * @param contributor
- * @param contextFileRelativePath
- * @param extraClasspath
- * @param overrideBundleInstallLocation
- * @param requireTldBundle The list of bundles'symbolic name that contain
- * tld files for this webapp.
- * @param handler the context handler passed in the server reference that
- * will be configured, deployed and started.
- * @return The contexthandler created and started
- * @throws Exception
- */
- public abstract ContextHandler registerContext(Bundle contributor, String contextFileRelativePath, String extraClasspath,
- String overrideBundleInstallLocation, String requireTldBundle, ContextHandler handler) throws Exception;
-
-} \ No newline at end of file
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java
index c66fa26b12..76738348d7 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java
@@ -33,6 +33,9 @@ import java.util.Set;
import org.eclipse.jetty.server.Server;
/**
+ * LibExtClassLoaderHelper
+ *
+ *
* Helper to create a URL class-loader with the jars inside
* ${jetty.home}/lib/ext and ${jetty.home}/resources. In an ideal world, every
* library is an OSGi bundle that does loads nicely. To support standard jars or
@@ -40,57 +43,40 @@ import org.eclipse.jetty.server.Server;
* inserting the jars in the usual jetty/lib/ext folders in the proper classpath
* for the webapps.
* <p>
- * Also the folder resources typically contains central configuration files for
- * things like: log config and others. We enable fragments to register classes
- * that are called back and passed those resources to do what they need to do.
+ * The drawback is that those jars will not be available in the OSGi
+ * classloader.
* </p>
* <p>
- * For example the test-jndi webapplication depends on derby, derbytools,
- * atomikos none of them are osgi bundles. we can either re-package them or we
- * can place them in the usual lib/ext. <br/>
- * In fact jasper's jsp libraries should maybe place in lib/ext too.
- * </p>
- * <p>
- * The drawback is that those libraries will not be available in the OSGi
- * classloader. Note that we could have setup those jars as embedded jars of the
- * current bundle. However, we would need to know in advance what are those jars
- * which was not acceptable. Also having those jars in a URLClassLoader seem to
- * be required for some cases. For example jaspers' TldLocationsCache (replaced
- * by TldScanner for servlet-3.0). <br/>
- * Also all the dependencies of those libraries must be resolvable directly from
- * the JettyBootstrapActivator bundle as it is set as the parent classloader. For
- * example: if atomikos is placed in lib/ext it will work if and only if
- * JettyBootstrapActivator import the necessary packages from javax.naming*,
- * javax.transaction*, javax.mail* etc Most of the common cases of javax are
- * added as optional import packages into jetty bootstrapper plugin. When there
- * are not covered: please make a request or create a fragment or register a
- * bundle with a buddy-policy onto the jetty bootstrapper..
- * </p>
- * <p>
- * Alternatives to placing jars in lib/ext
+ * Alternatives to placing jars in lib/ext:
* <ol>
- * <li>Bundle the jars in an osgi bundle. Have the webapp(s) that context
- * depends on them depend on that bundle. Things will go well for jetty.</li>
+ * <li>Bundle the jars in an osgi bundle. Have the webapp(s) that need these jars
+ * depend on that bundle.</li>
* <li>Bundle those jars in an osgi bundle-fragment that targets the
* jetty-bootstrap bundle</li>
* <li>Use equinox Buddy-Policy: register a buddy of the jetty bootstrapper
- * bundle. (least favorite: it will work only on equinox)</li>
+ * bundle. (Note: it will work only on equinox)</li>
* </ol>
* </p>
*/
public class LibExtClassLoaderHelper
{
-
+ /* ------------------------------------------------------------ */
/**
- * Class called back
+ * IFilesInJettyHomeResourcesProcessor
+ *
+ * Interface for callback impls
*/
public interface IFilesInJettyHomeResourcesProcessor
{
void processFilesInResourcesFolder(File jettyHome, Map<String, File> filesInResourcesFolder);
}
+
+
public static Set<IFilesInJettyHomeResourcesProcessor> registeredFilesInJettyHomeResourcesProcessors = new HashSet<IFilesInJettyHomeResourcesProcessor>();
+
+ /* ------------------------------------------------------------ */
/**
* @param server
* @return a url classloader with the jars of resources, lib/ext and the
@@ -145,6 +131,8 @@ public class LibExtClassLoaderHelper
return new URLClassLoader(urls.toArray(new URL[urls.size()]), parentClassLoader);
}
+
+ /* ------------------------------------------------------------ */
/**
* @param server
* @return a url classloader with the jars of resources, lib/ext and the
@@ -188,6 +176,7 @@ public class LibExtClassLoaderHelper
return new URLClassLoader(urls.toArray(new URL[urls.size()]), parentClassLoader);
}
+ /* ------------------------------------------------------------ */
/**
* When we find files typically used for central logging configuration we do
* what it takes in this method to do what the user expects. Without
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java
index 5f7e6443d9..e963b91344 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java
@@ -33,7 +33,6 @@ import java.util.jar.JarFile;
import javax.servlet.http.HttpServlet;
-import org.eclipse.jetty.osgi.boot.utils.BundleClassLoaderHelper;
import org.eclipse.jetty.osgi.boot.utils.BundleClassLoaderHelperFactory;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -44,8 +43,10 @@ import org.osgi.framework.Bundle;
import org.osgi.framework.BundleReference;
/**
- * Extends the webappclassloader to insert the classloader provided by the osgi
- * bundle at the same level than any other jars palced in the webappclassloader.
+ * OSGiWebappClassLoader
+ *
+ *
+ * Extends the webapp classloader to also use the classloader of the Bundle defining the webapp.
*/
public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleReference
{
@@ -79,10 +80,9 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
private boolean _lookInOsgiFirst = true;
- private Set<String> _libsAlreadyInManifest = new HashSet<String>();
-
+ /* ------------------------------------------------------------ */
/**
- * @param parent The parent classloader. In this case
+ * @param parent The parent classloader.
* @param context The WebAppContext
* @param contributor The bundle that defines this web-application.
* @throws IOException
@@ -94,7 +94,10 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
_contributor = contributor;
_osgiBundleClassLoader = BundleClassLoaderHelperFactory.getFactory().getHelper().getBundleClassLoader(contributor);
}
-
+
+
+
+ /* ------------------------------------------------------------ */
/**
* Returns the <code>Bundle</code> that defined this web-application.
*
@@ -106,17 +109,7 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
return _contributor;
}
- /**
- * Reads the manifest. If the manifest is already configured to loads a few
- * libs we should not add them to the classpath of the webapp. Not really
- * important as we resolve classes through the osgi classloader first and
- * then default on the libs of the webapp.
- */
- private void computeLibsAlreadyInOSGiClassLoader()
- {
- // TODO
- }
-
+ /* ------------------------------------------------------------ */
@Override
public Enumeration<URL> getResources(String name) throws IOException
{
@@ -131,7 +124,10 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
return Collections.enumeration(toList(urls, osgiUrls));
}
}
-
+
+
+
+ /* ------------------------------------------------------------ */
@Override
public URL getResource(String name)
{
@@ -146,7 +142,10 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
return url != null ? url : _osgiBundleClassLoader.getResource(name);
}
}
-
+
+
+
+ /* ------------------------------------------------------------ */
private List<URL> toList(Enumeration<URL> e, Enumeration<URL> e2)
{
List<URL> list = new ArrayList<URL>();
@@ -157,9 +156,8 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
return list;
}
- /**
- *
- */
+
+ /* ------------------------------------------------------------ */
protected Class<?> findClass(String name) throws ClassNotFoundException
{
try
@@ -178,7 +176,10 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
}
}
}
-
+
+
+
+ /* ------------------------------------------------------------ */
/**
* Parse the classpath ourselves to be able to filter things. This is a
* derivative work of the super class
@@ -207,6 +208,8 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
}
+
+ /* ------------------------------------------------------------ */
/**
* @param lib
* @return true if the lib should be included in the webapp classloader.
@@ -255,6 +258,8 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
private static Field _contextField;
+
+ /* ------------------------------------------------------------ */
/**
* In the case of the generation of a webapp via a jetty context file we
* need a proper classloader to setup the app before we have the
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyContextHandlerServiceTracker.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/ServiceWatcher.java
index 6bd352da2a..08dbd4a902 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyContextHandlerServiceTracker.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/ServiceWatcher.java
@@ -18,28 +18,18 @@
package org.eclipse.jetty.osgi.boot.internal.webapp;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import org.eclipse.jetty.osgi.boot.BundleWebAppProvider;
import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
import org.eclipse.jetty.osgi.boot.OSGiWebappConstants;
import org.eclipse.jetty.osgi.boot.ServiceProvider;
-import org.eclipse.jetty.osgi.boot.internal.serverfactory.DefaultJettyAtJettyHomeHelper;
-import org.eclipse.jetty.osgi.boot.internal.serverfactory.IManagedJettyServerRegistry;
-import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.Scanner;
-import org.eclipse.jetty.webapp.WebAppContext;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
@@ -49,7 +39,7 @@ import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
/**
- * JettyContextHandlerServiceTracker
+ * ServiceWatcher
*
* When a {@link ContextHandler} is activated as an osgi service we find a jetty deployer
* for it. The ContextHandler could be either a WebAppContext or any other derivative of
@@ -59,9 +49,9 @@ import org.osgi.util.tracker.ServiceTracker;
* osgi services. Instead, they can be deployed via manifest headers inside bundles. See
* {@link WebBundleTrackerCustomizer}.
*/
-public class JettyContextHandlerServiceTracker implements ServiceListener
+public class ServiceWatcher implements ServiceListener
{
- private static Logger LOG = Log.getLogger(JettyContextHandlerServiceTracker.class);
+ private static Logger LOG = Log.getLogger(ServiceWatcher.class);
public static final String FILTER = "(objectclass=" + ServiceProvider.class.getName() + ")";
@@ -75,7 +65,7 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
/**
* @param registry
*/
- public JettyContextHandlerServiceTracker() throws Exception
+ public ServiceWatcher() throws Exception
{
//track all instances of deployers of webapps
Bundle myBundle = FrameworkUtil.getBundle(this.getClass());
@@ -195,6 +185,7 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
try
{
added = e.getValue().serviceAdded(sr, contextHandler);
+ System.err.println(serverName+" deployed "+contextHandler+": "+added);
if (added && LOG.isDebugEnabled())
LOG.debug("Provider "+e.getValue()+" deployed "+contextHandler);
}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleClassLoaderHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleClassLoaderHelper.java
index 4c4382f3d4..ba99ac21d3 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleClassLoaderHelper.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleClassLoaderHelper.java
@@ -22,6 +22,10 @@ import org.eclipse.jetty.osgi.boot.utils.internal.DefaultBundleClassLoaderHelper
import org.osgi.framework.Bundle;
/**
+ *
+ * BundleClassLoaderHelper
+ *
+ *
* Is there a clean OSGi way to go from the Bundle object to the classloader of
* the Bundle ? You can certainly take a class inside the bundle and get the
* bundle's classloader that way. Getting the classloader directly from the
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleClassLoaderHelperFactory.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleClassLoaderHelperFactory.java
index edcfde0f57..297f0f3c71 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleClassLoaderHelperFactory.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleClassLoaderHelperFactory.java
@@ -32,15 +32,19 @@ public class BundleClassLoaderHelperFactory
private static BundleClassLoaderHelperFactory _instance = new BundleClassLoaderHelperFactory();
+
+ /* ------------------------------------------------------------ */
public static BundleClassLoaderHelperFactory getFactory()
{
return _instance;
}
+ /* ------------------------------------------------------------ */
private BundleClassLoaderHelperFactory()
{
}
+ /* ------------------------------------------------------------ */
public BundleClassLoaderHelper getHelper()
{
//use the default
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java
index 0809b72906..2abd7a0ab1 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java
@@ -26,6 +26,9 @@ import org.eclipse.jetty.osgi.boot.utils.internal.DefaultFileLocatorHelper;
import org.osgi.framework.Bundle;
/**
+ * BundleFileLocatorHelper
+ *
+ *
* From a bundle to its location on the filesystem. Assumes the bundle is not a
* jar.
*
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/EventSender.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/EventSender.java
index 13703fa416..c4e06a2b5c 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/EventSender.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/EventSender.java
@@ -21,14 +21,18 @@ package org.eclipse.jetty.osgi.boot.utils;
import java.util.Dictionary;
import java.util.Hashtable;
-import javax.security.auth.login.FailedLoginException;
-
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
+/**
+ * EventSender
+ *
+ * Utility class for emiting OSGi EventAdmin events
+ *
+ */
public class EventSender
{
//OSGi Event Admin events for webapps
@@ -43,6 +47,13 @@ public class EventSender
private Bundle _myBundle;
private EventAdmin _eventAdmin;
+
+
+
+ /* ------------------------------------------------------------ */
+ /**
+ *
+ */
private EventSender ()
{
_myBundle = FrameworkUtil.getBundle(EventSender.class);
@@ -50,13 +61,27 @@ public class EventSender
if (ref != null)
_eventAdmin = (EventAdmin)_myBundle.getBundleContext().getService(ref);
}
-
+
+
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return
+ */
public static EventSender getInstance()
{
return __instance;
}
+
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param topic
+ * @param wab
+ * @param contextPath
+ */
public void send (String topic, Bundle wab, String contextPath)
{
if (topic==null || wab==null || contextPath==null)
@@ -66,6 +91,14 @@ public class EventSender
}
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param topic
+ * @param wab
+ * @param contextPath
+ * @param ex
+ */
public void send (String topic, Bundle wab, String contextPath, Exception ex)
{
if (_eventAdmin == null)
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/jsp/TldLocatableURLClassloader.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/FakeURLClassLoader.java
index 4b48aef2a3..77f85100e3 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/jsp/TldLocatableURLClassloader.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/FakeURLClassLoader.java
@@ -16,29 +16,42 @@
// ========================================================================
//
-package org.eclipse.jetty.osgi.boot.internal.jsp;
+package org.eclipse.jetty.osgi.boot.utils;
import java.net.URL;
import java.net.URLClassLoader;
/**
- * Tricky url classloader. In fact we don't want a real URLClassLoader: we want
- * OSGi to provide its classloader and let it does. But to let
- * {@link org.apache.jasper.compiler.TldLocationsCache} find the core tlds
- * inside the jars we must be a URLClassLoader that returns an array of jars
- * where tlds are stored when the method getURLs is called.
+ *
+ * FakeURLClassLoader
+ *
+ * A URLClassloader that overrides the getURLs() method to return the list
+ * of urls passed in to the constructor, but otherwise acts as if it has no
+ * urls, which would cause it to delegate to the parent classloader (in this
+ * case an OSGi classloader).
+ *
+ * The main use of this class is with jars containing tlds. Jasper expects a
+ * URL classloader to inspect for jars with tlds.
+ *
*/
-public class TldLocatableURLClassloader extends URLClassLoader
+public class FakeURLClassLoader extends URLClassLoader
{
- private URL[] _jarsWithTldsInside;
-
- public TldLocatableURLClassloader(ClassLoader osgiClassLoader, URL[] jarsWithTldsInside)
+ private URL[] _jars;
+
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param osgiClassLoader
+ * @param jars
+ */
+ public FakeURLClassLoader(ClassLoader osgiClassLoader, URL[] jars)
{
super(new URL[] {},osgiClassLoader);
- _jarsWithTldsInside = jarsWithTldsInside;
+ _jars = jars;
}
+ /* ------------------------------------------------------------ */
/**
* @return the jars that contains tlds so that TldLocationsCache or
* TldScanner can find them.
@@ -46,16 +59,21 @@ public class TldLocatableURLClassloader extends URLClassLoader
@Override
public URL[] getURLs()
{
- return _jarsWithTldsInside;
+ return _jars;
}
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see java.lang.Object#toString()
+ */
public String toString()
{
StringBuilder builder = new StringBuilder();
- if (_jarsWithTldsInside != null)
+ if (_jars != null)
{
- for (URL u:_jarsWithTldsInside)
+ for (URL u:_jars)
builder.append(" "+u.toString());
return builder.toString();
}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/OSGiClassLoader.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/OSGiClassLoader.java
index 8850f5e639..91f42afb94 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/OSGiClassLoader.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/OSGiClassLoader.java
@@ -78,8 +78,7 @@ public class OSGiClassLoader extends URLClassLoader
}
if (url == null)
- {
-
+ {
url = _osgiBundleClassLoader.getResource(name);
if (url == null && name.startsWith("/"))
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/TldBundleDiscoverer.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/TldBundleDiscoverer.java
new file mode 100644
index 0000000000..bdd6168f21
--- /dev/null
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/TldBundleDiscoverer.java
@@ -0,0 +1,43 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2013 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.osgi.boot.utils;
+
+import java.net.URL;
+
+import org.eclipse.jetty.deploy.DeploymentManager;
+
+
+/**
+ * TldBundleDiscoverer
+ *
+ * Convert bundles that contain tlds into URL locations for consumption by jasper.
+ */
+public interface TldBundleDiscoverer
+{
+ /**
+ * Find bundles that contain tlds and convert into URL references to their location.
+ *
+ * @param manager
+ * @param fileLocator
+ * @return array of URLs representing locations of tld containing bundles
+ * @throws Exception
+ */
+ URL[] getUrlsForBundlesWithTlds(DeploymentManager manager, BundleFileLocatorHelper fileLocator) throws Exception;
+
+}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/WebappRegistrationCustomizer.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/WebappRegistrationCustomizer.java
deleted file mode 100644
index 813bff42fc..0000000000
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/WebappRegistrationCustomizer.java
+++ /dev/null
@@ -1,61 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2013 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.osgi.boot.utils;
-
-import java.net.URL;
-
-import org.eclipse.jetty.deploy.DeploymentManager;
-
-
-/**
- * Fix various shortcomings with the way jasper parses the tld files.
- */
-public interface WebappRegistrationCustomizer
-{
- /**
- * we could do something a lot more pluggable with a custom header in the
- * manifest or some customer declarative services let's keep it simple for
- * now. hopefully the rest of the world won't need to customize this.
- */
- public static final String CLASS_NAME = "org.eclipse.jetty.osgi.boot.jasper.WebappRegistrationCustomizerImpl";
-
- /**
- * TODO: right now only the jetty-jsp bundle is scanned for common taglibs.
- * Should support a way to plug more bundles that contain taglibs.
- *
- * The jasper TldScanner expects a URLClassloader to parse a jar for the
- * /META-INF/*.tld it may contain. We place the bundles that we know contain
- * such tag-libraries. Please note that it will work if and only if the
- * bundle is a jar (!) Currently we just hardcode the bundle that contains
- * the jstl implemenation.
- *
- * A workaround when the tld cannot be parsed with this method is to copy
- * and paste it inside the WEB-INF of the webapplication where it is used.
- *
- * Support only 2 types of packaging for the bundle: - the bundle is a jar
- * (recommended for runtime.) - the bundle is a folder and contain jars in
- * the root and/or in the lib folder (nice for PDE developement situations)
- * Unsupported: the bundle is a jar that embeds more jars.
- *
- * @return array of URLs
- * @throws Exception
- */
- URL[] getJarsWithTlds(DeploymentManager manager, BundleFileLocatorHelper fileLocator) throws Exception;
-
-}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java
index 9bb074a5f2..ee0d7c225e 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java
@@ -28,6 +28,9 @@ import org.eclipse.jetty.util.log.Logger;
import org.osgi.framework.Bundle;
/**
+ * DefaultBundleClassLoaderHelper
+ *
+ *
* Default implementation of the BundleClassLoaderHelper. Uses introspection to
* support equinox-3.5 and felix-2.0.0
*/
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java
index 2d31459de1..7349cd08bb 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java
@@ -31,11 +31,14 @@ import java.util.zip.ZipFile;
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
import org.eclipse.jetty.util.URIUtil;
-import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.resource.FileResource;
+import org.eclipse.jetty.util.resource.Resource;
import org.osgi.framework.Bundle;
/**
+ * DefaultFileLocatorHelper
+ *
+ *
* From a bundle to its location on the filesystem. Assumes the bundle is not a
* jar.
*
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/PackageAdminServiceTracker.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/PackageAdminServiceTracker.java
index 384b392c9a..7ce7551aed 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/PackageAdminServiceTracker.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/PackageAdminServiceTracker.java
@@ -35,8 +35,14 @@ import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.startlevel.StartLevel;
/**
+ * PackageAdminServiceTracker
+ *
+ *
* When the PackageAdmin service is activated we can look for the fragments
- * attached to this bundle and "activate" them.
+ * attached to this bundle and do a fake "activate" on them.
+ *
+ * See particularly the jetty-osgi-boot-jsp fragment bundle that uses this
+ * facility.
*/
public class PackageAdminServiceTracker implements ServiceListener
{
diff --git a/jetty-osgi/jetty-osgi-httpservice/pom.xml b/jetty-osgi/jetty-osgi-httpservice/pom.xml
index 2f17b54b71..db9872a5fa 100644
--- a/jetty-osgi/jetty-osgi-httpservice/pom.xml
+++ b/jetty-osgi/jetty-osgi-httpservice/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-httpservice</artifactId>
diff --git a/jetty-osgi/jetty-osgi-npn/pom.xml b/jetty-osgi/jetty-osgi-npn/pom.xml
index 1d71cbb72b..0515eaa6f1 100644
--- a/jetty-osgi/jetty-osgi-npn/pom.xml
+++ b/jetty-osgi/jetty-osgi-npn/pom.xml
@@ -1,9 +1,8 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-osgi-npn</artifactId>
diff --git a/jetty-osgi/pom.xml b/jetty-osgi/pom.xml
index 0e98d1d2f5..bcf9990804 100644
--- a/jetty-osgi/pom.xml
+++ b/jetty-osgi/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
diff --git a/jetty-osgi/test-jetty-osgi-context/pom.xml b/jetty-osgi/test-jetty-osgi-context/pom.xml
index 8b4eecc922..03634fd691 100644
--- a/jetty-osgi/test-jetty-osgi-context/pom.xml
+++ b/jetty-osgi/test-jetty-osgi-context/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>test-jetty-osgi-context</artifactId>
diff --git a/jetty-osgi/test-jetty-osgi-webapp/pom.xml b/jetty-osgi/test-jetty-osgi-webapp/pom.xml
index b3ea3e6804..444840f427 100644
--- a/jetty-osgi/test-jetty-osgi-webapp/pom.xml
+++ b/jetty-osgi/test-jetty-osgi-webapp/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml
index e673df15b1..85d0989269 100644
--- a/jetty-osgi/test-jetty-osgi/pom.xml
+++ b/jetty-osgi/test-jetty-osgi/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/jetty-plus/pom.xml b/jetty-plus/pom.xml
index 4aeff7593a..d1bacea52f 100644
--- a/jetty-plus/pom.xml
+++ b/jetty-plus/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-plus</artifactId>
diff --git a/jetty-proxy/pom.xml b/jetty-proxy/pom.xml
index ce2e37effd..27353e155e 100644
--- a/jetty-proxy/pom.xml
+++ b/jetty-proxy/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-proxy</artifactId>
diff --git a/jetty-rewrite/pom.xml b/jetty-rewrite/pom.xml
index a54c6cbc7c..cdbf469e4a 100644
--- a/jetty-rewrite/pom.xml
+++ b/jetty-rewrite/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-rewrite</artifactId>
diff --git a/jetty-runner/pom.xml b/jetty-runner/pom.xml
index c1b42e92ca..ec57a92de6 100644
--- a/jetty-runner/pom.xml
+++ b/jetty-runner/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.eclipse.jetty</groupId>
diff --git a/jetty-security/pom.xml b/jetty-security/pom.xml
index a13eef1543..9aa83c79ae 100644
--- a/jetty-security/pom.xml
+++ b/jetty-security/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-security</artifactId>
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
index a606a0c08b..7878479bc4 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
@@ -696,6 +696,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
HttpConfiguration httpConfig = HttpChannel.getCurrentHttpChannel().getHttpConfiguration();
+
if (dataConstraint == UserDataConstraint.Confidential || dataConstraint == UserDataConstraint.Integral)
{
if (request.isSecure())
@@ -703,11 +704,13 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
if (httpConfig.getSecurePort() > 0)
{
- String url = httpConfig.getSecureScheme() + "://" + request.getServerName() + ":" + httpConfig.getSecurePort()
- + request.getRequestURI();
+ String scheme = httpConfig.getSecureScheme();
+ int port = httpConfig.getSecurePort();
+ String url = ("https".equalsIgnoreCase(scheme) && port==443)
+ ? "https://"+request.getServerName()+request.getRequestURI()
+ : scheme + "://" + request.getServerName() + ":" + port + request.getRequestURI();
if (request.getQueryString() != null)
url += "?" + request.getQueryString();
-
response.setContentLength(0);
response.sendRedirect(url);
}
diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java
index dc4b13b671..abbfe732e7 100644
--- a/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java
+++ b/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java
@@ -41,6 +41,8 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
import org.eclipse.jetty.security.authentication.FormAuthenticator;
import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
@@ -65,12 +67,14 @@ public class ConstraintTest
private Server _server;
private LocalConnector _connector;
private ConstraintSecurityHandler _security;
+ private HttpConfiguration _config;
@Before
public void startServer()
{
_server = new Server();
_connector = new LocalConnector(_server);
+ _config=_connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration();
_server.setConnectors(new Connector[]{_connector});
ContextHandler _context = new ContextHandler();
@@ -161,7 +165,15 @@ public class ConstraintTest
mapping5.setConstraint(constraint5);
mapping5.setMethod("POST");
- return Arrays.asList(mapping0, mapping1, mapping2, mapping3, mapping4, mapping5);
+ Constraint constraint6 = new Constraint();
+ constraint6.setAuthenticate(false);
+ constraint6.setName("data constraint");
+ constraint6.setDataConstraint(2);
+ ConstraintMapping mapping6 = new ConstraintMapping();
+ mapping6.setPathSpec("/data/*");
+ mapping6.setConstraint(constraint6);
+
+ return Arrays.asList(mapping0, mapping1, mapping2, mapping3, mapping4, mapping5, mapping6);
}
@Test
@@ -742,9 +754,9 @@ public class ConstraintTest
response = _connector.getResponses("GET /ctx/forbid/info HTTP/1.0\r\n\r\n");
assertThat(response,startsWith("HTTP/1.1 403 Forbidden"));
- response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n\r\n");
+ response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\nHost:wibble.com:8888\r\n\r\n");
assertThat(response,containsString(" 302 Found"));
- assertThat(response,containsString("/ctx/testLoginPage"));
+ assertThat(response,containsString("http://wibble.com:8888/ctx/testLoginPage"));
String session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx"));
@@ -840,6 +852,48 @@ public class ConstraintTest
assertThat(response,startsWith("HTTP/1.1 200 OK"));
}
+
+
+ @Test
+ public void testDataRedirection() throws Exception
+ {
+ _security.setAuthenticator(new BasicAuthenticator());
+ _server.start();
+
+ String response;
+
+ response = _connector.getResponses("GET /ctx/data/info HTTP/1.0\r\n\r\n");
+ assertTrue(response.startsWith("HTTP/1.1 403"));
+
+ _config.setSecurePort(8443);
+ _config.setSecureScheme("https");
+
+ response = _connector.getResponses("GET /ctx/data/info HTTP/1.0\r\n\r\n");
+ assertTrue(response.startsWith("HTTP/1.1 302 Found"));
+ assertTrue(response.indexOf("Location") > 0);
+ assertTrue(response.indexOf(":8443/ctx/data/info") > 0);
+
+ _config.setSecurePort(443);
+ response = _connector.getResponses("GET /ctx/data/info HTTP/1.0\r\n\r\n");
+ assertTrue(response.startsWith("HTTP/1.1 302 Found"));
+ assertTrue(response.indexOf("Location") > 0);
+ assertTrue(response.indexOf(":443/ctx/data/info") < 0);
+
+ _config.setSecurePort(8443);
+ response = _connector.getResponses("GET /ctx/data/info HTTP/1.0\r\nHost: wobble.com\r\n\r\n");
+ assertTrue(response.startsWith("HTTP/1.1 302 Found"));
+ assertTrue(response.indexOf("Location") > 0);
+ assertTrue(response.indexOf("https://wobble.com:8443/ctx/data/info") > 0);
+
+ _config.setSecurePort(443);
+ response = _connector.getResponses("GET /ctx/data/info HTTP/1.0\r\nHost: wobble.com\r\n\r\n");
+ System.err.println(response);
+ assertTrue(response.startsWith("HTTP/1.1 302 Found"));
+ assertTrue(response.indexOf("Location") > 0);
+ assertTrue(response.indexOf(":443") < 0);
+ assertTrue(response.indexOf("https://wobble.com/ctx/data/info") > 0);
+ }
+
@Test
public void testRoleRef() throws Exception
{
diff --git a/jetty-server/pom.xml b/jetty-server/pom.xml
index 577d57e16d..04c86c663c 100644
--- a/jetty-server/pom.xml
+++ b/jetty-server/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-server</artifactId>
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
index bcc13aa3cd..28fea907e5 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
@@ -151,6 +151,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
private long _idleTimeout = 30000;
private String _defaultProtocol;
private ConnectionFactory _defaultConnectionFactory;
+ private String _name;
/**
@@ -288,8 +289,9 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
// If we have a stop timeout
long stopTimeout = getStopTimeout();
- if (stopTimeout > 0 && _stopping!=null)
- _stopping.await(stopTimeout,TimeUnit.MILLISECONDS);
+ CountDownLatch stopping=_stopping;
+ if (stopTimeout > 0 && stopping!=null)
+ stopping.await(stopTimeout,TimeUnit.MILLISECONDS);
_stopping=null;
super.doStop();
@@ -474,7 +476,9 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
{
_acceptors[_acceptor] = null;
}
- _stopping.countDown();
+ CountDownLatch stopping=_stopping;
+ if (stopping!=null)
+ stopping.countDown();
}
}
}
@@ -525,10 +529,28 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
}
@Override
+ public String getName()
+ {
+ return _name;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set a connector name. A context may be configured with
+ * virtual hosts in the form "@contextname" and will only serve
+ * requests from the named connector,
+ * @param name A connector name.
+ */
+ public void setName(String name)
+ {
+ _name=name;
+ }
+
+ @Override
public String toString()
{
return String.format("%s@%x{%s}",
- getClass().getSimpleName(),
+ _name==null?getClass().getSimpleName():_name,
hashCode(),
getDefaultProtocol());
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncNCSARequestLog.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncNCSARequestLog.java
index 047e3b6d40..300d23cc75 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncNCSARequestLog.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncNCSARequestLog.java
@@ -57,7 +57,7 @@ public class AsyncNCSARequestLog extends NCSARequestLog
{
super(filename);
if (queue==null)
- queue=new ConcurrentArrayBlockingQueue.Bounded<String>(1024);
+ queue=new ConcurrentArrayBlockingQueue.Unbounded<String>();
_queue=queue;
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java
index 3454c7869e..6866e5e49a 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java
@@ -24,6 +24,7 @@ import java.util.concurrent.Executor;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.Graceful;
@@ -90,4 +91,15 @@ public interface Connector extends LifeCycle, Graceful
* @return immutable collection of connected endpoints
*/
public Collection<EndPoint> getConnectedEndPoints();
+
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Get the connector name if set.
+ * <p>A {@link ContextHandler} may be configured with
+ * virtual hosts in the form "@connectorName" and will only serve
+ * requests from the named connector.
+ * @return The connector name or null.
+ */
+ public String getName();
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java
index aba29959cd..e789d389a5 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java
@@ -146,6 +146,7 @@ public class ShutdownMonitor
{
if (isAlive())
{
+ // TODO why are we reentrant here?
if (DEBUG)
System.err.printf("ShutdownMonitorThread already started");
return; // cannot start it again
@@ -157,7 +158,8 @@ public class ShutdownMonitor
{
return;
}
- System.err.println("Starting ShutdownMonitorThread");
+ if (DEBUG)
+ System.err.println("Starting ShutdownMonitorThread");
super.start();
}
@@ -352,7 +354,9 @@ public class ShutdownMonitor
{
if (thread != null && thread.isAlive())
{
- System.err.printf("ShutdownMonitorThread already started");
+ // TODO why are we reentrant here?
+ if (DEBUG)
+ System.err.printf("ShutdownMonitorThread already started");
return; // cannot start it again
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/SslConnectionFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/SslConnectionFactory.java
index da83f1f96d..d3e9fd6c78 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/SslConnectionFactory.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/SslConnectionFactory.java
@@ -78,6 +78,7 @@ public class SslConnectionFactory extends AbstractConnectionFactory
engine.setUseClientMode(false);
SslConnection sslConnection = newSslConnection(connector, endPoint, engine);
+ sslConnection.setRenegotiationAllowed(_sslContextFactory.isRenegotiationAllowed());
configure(sslConnection, connector, endPoint);
ConnectionFactory next = connector.getConnectionFactory(_nextProtocol);
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
index 4d15352b28..3d5fad459c 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
@@ -65,6 +65,7 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.server.ClassLoaderDump;
+import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HandlerContainer;
@@ -280,7 +281,8 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
*
* @param vhosts
* Array of virtual hosts that this context responds to. A null host name or null/empty array means any hostname is acceptable. Host names may be
- * String representation of IP addresses. Host names may start with '*.' to wildcard one level of names.
+ * String representation of IP addresses. Host names may start with '*.' to wildcard one level of names. Hosts may start with '@', in which case they
+ * will match the {@link Connector#getName()} for the request.
*/
public void setVirtualHosts(String[] vhosts)
{
@@ -872,18 +874,29 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
boolean match = false;
- for (int i = 0; !match && i < _vhosts.length; i++)
+ loop: for (String contextVhost:_vhosts)
{
- String contextVhost = _vhosts[i];
- if (contextVhost == null)
+ if (contextVhost == null || contextVhost.length()==0)
continue;
- if (contextVhost.startsWith("*."))
+ char c=contextVhost.charAt(0);
+ switch (c)
{
- // wildcard only at the beginning, and only for one additional subdomain level
- match = contextVhost.regionMatches(true,2,vhost,vhost.indexOf(".") + 1,contextVhost.length() - 2);
+ case '*':
+ if (contextVhost.startsWith("*."))
+ // wildcard only at the beginning, and only for one additional subdomain level
+ match = contextVhost.regionMatches(true,2,vhost,vhost.indexOf(".") + 1,contextVhost.length() - 2);
+ break;
+ case '@':
+ String name=baseRequest.getHttpChannel().getConnector().getName();
+ match=name!=null && contextVhost.length()==name.length()+1 && contextVhost.endsWith(name);
+ break;
+ default:
+ match = contextVhost.equalsIgnoreCase(vhost);
}
- else
- match = contextVhost.equalsIgnoreCase(vhost);
+
+ if (match)
+ break loop;
+
}
if (!match)
return false;
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/LowResourcesMonitorTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/LowResourcesMonitorTest.java
index 365a85b079..eac10577bf 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/LowResourcesMonitorTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/LowResourcesMonitorTest.java
@@ -80,13 +80,14 @@ public class LowResourcesMonitorTest
@Test
public void testLowOnThreads() throws Exception
{
+ Thread.sleep(1200);
_threadPool.setMaxThreads(_threadPool.getThreads()-_threadPool.getIdleThreads()+10);
Thread.sleep(1200);
Assert.assertFalse(_lowResourcesMonitor.isLowOnResources());
final CountDownLatch latch = new CountDownLatch(1);
- for (int i=0;i<20;i++)
+ for (int i=0;i<100;i++)
{
_threadPool.dispatch(new Runnable()
{
@@ -110,7 +111,6 @@ public class LowResourcesMonitorTest
latch.countDown();
Thread.sleep(1200);
- System.err.println(_threadPool.dump());
Assert.assertFalse(_lowResourcesMonitor.isLowOnResources());
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerTest.java
index b8fe723dec..f9d07f47b8 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerTest.java
@@ -118,6 +118,79 @@ public class ContextHandlerTest
}
}
+
+
+ @Test
+ public void testNamedConnector() throws Exception
+ {
+ Server server = new Server();
+ LocalConnector connector = new LocalConnector(server);
+ LocalConnector connectorN = new LocalConnector(server);
+ connectorN.setName("name");
+ server.setConnectors(new Connector[] { connector, connectorN });
+
+ ContextHandler contextA = new ContextHandler("/");
+ contextA.setVirtualHosts(new String[]{"www.example.com" });
+ IsHandledHandler handlerA = new IsHandledHandler();
+ contextA.setHandler(handlerA);
+
+ ContextHandler contextB = new ContextHandler("/");
+ IsHandledHandler handlerB = new IsHandledHandler();
+ contextB.setHandler(handlerB);
+ contextB.setVirtualHosts(new String[]{ "@name" });
+
+ ContextHandler contextC = new ContextHandler("/");
+ IsHandledHandler handlerC = new IsHandledHandler();
+ contextC.setHandler(handlerC);
+
+ HandlerCollection c = new HandlerCollection();
+ c.addHandler(contextA);
+ c.addHandler(contextB);
+ c.addHandler(contextC);
+ server.setHandler(c);
+
+ server.start();
+ try
+ {
+ connector.getResponses("GET / HTTP/1.0\n" + "Host: www.example.com.\n\n");
+ assertTrue(handlerA.isHandled());
+ assertFalse(handlerB.isHandled());
+ assertFalse(handlerC.isHandled());
+ handlerA.reset();
+ handlerB.reset();
+ handlerC.reset();
+
+ connector.getResponses("GET / HTTP/1.0\n" + "Host: localhost\n\n");
+ assertFalse(handlerA.isHandled());
+ assertFalse(handlerB.isHandled());
+ assertTrue(handlerC.isHandled());
+ handlerA.reset();
+ handlerB.reset();
+ handlerC.reset();
+
+ connectorN.getResponses("GET / HTTP/1.0\n" + "Host: www.example.com.\n\n");
+ assertTrue(handlerA.isHandled());
+ assertFalse(handlerB.isHandled());
+ assertFalse(handlerC.isHandled());
+ handlerA.reset();
+ handlerB.reset();
+ handlerC.reset();
+
+ connectorN.getResponses("GET / HTTP/1.0\n" + "Host: localhost\n\n");
+ assertFalse(handlerA.isHandled());
+ assertTrue(handlerB.isHandled());
+ assertFalse(handlerC.isHandled());
+ handlerA.reset();
+ handlerB.reset();
+ handlerC.reset();
+
+ }
+ finally
+ {
+ server.stop();
+ }
+
+ }
@Test
public void testContextGetContext() throws Exception
diff --git a/jetty-servlet/pom.xml b/jetty-servlet/pom.xml
index bcc92b29cb..552e4b2ccb 100644
--- a/jetty-servlet/pom.xml
+++ b/jetty-servlet/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>jetty-project</artifactId>
<groupId>org.eclipse.jetty</groupId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-servlet</artifactId>
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java
index 0d67bb3f75..f95a58dff8 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java
@@ -434,7 +434,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
if (resource!=null && resource.exists() && !resource.isDirectory())
{
// Tell caches that response may vary by accept-encoding
- response.setHeader(HttpHeader.VARY.asString(),HttpHeader.ACCEPT_ENCODING.asString());
+ response.addHeader(HttpHeader.VARY.asString(),HttpHeader.ACCEPT_ENCODING.asString());
// Does the client accept gzip?
String accept=request.getHeader(HttpHeader.ACCEPT_ENCODING.asString());
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java
index 6de3b7e48b..1e50dd1249 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java
@@ -71,7 +71,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
private static final Logger LOG = Log.getLogger(ServletHolder.class);
/* ---------------------------------------------------------------- */
- private int _initOrder;
+ private int _initOrder = -1;
private boolean _initOnStartup=false;
private Map<String, String> _roleMap;
private String _forcedPath;
@@ -179,7 +179,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
*/
public void setInitOrder(int order)
{
- _initOnStartup=order>0;
+ _initOnStartup=order>=0;
_initOrder = order;
}
@@ -329,7 +329,6 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
throws Exception
{
super.initialize();
-
if (_extInstance || _initOnStartup)
{
try
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletContextHandlerTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletContextHandlerTest.java
index 4c06368b4b..b923e53d8c 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletContextHandlerTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletContextHandlerTest.java
@@ -130,8 +130,8 @@ public class ServletContextHandlerTest
holder0.setInitOrder(0);
_server.start();
- assertEquals(2,__testServlets.get());
- assertThat(holder0.getServletInstance(),nullValue());
+ assertEquals(3,__testServlets.get());
+ assertThat(holder0.getServletInstance(),notNullValue(Servlet.class));
_server.stop();
assertEquals(0,__testServlets.get());
diff --git a/jetty-servlets/pom.xml b/jetty-servlets/pom.xml
index b1e1f367de..0e0f464962 100644
--- a/jetty-servlets/pom.xml
+++ b/jetty-servlets/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>jetty-project</artifactId>
<groupId>org.eclipse.jetty</groupId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-servlets</artifactId>
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java
index 1cb6d10bdf..44690347f8 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java
@@ -84,15 +84,6 @@ public class IncludableGzipFilter extends GzipFilter
{
return null;
}
-
- @Override
- protected void setHeader(String name, String value)
- {
- super.setHeader(name, value);
- HttpServletResponse response = (HttpServletResponse)getResponse();
- if (!response.containsHeader(name))
- response.setHeader("org.eclipse.jetty.server.include." + name, value);
- }
};
}
};
@@ -111,15 +102,6 @@ public class IncludableGzipFilter extends GzipFilter
{
return new GZIPOutputStream(_response.getOutputStream(),_bufferSize);
}
-
- @Override
- protected void setHeader(String name, String value)
- {
- super.setHeader(name, value);
- HttpServletResponse response = (HttpServletResponse)getResponse();
- if (!response.containsHeader(name))
- response.setHeader("org.eclipse.jetty.server.include." + name, value);
- }
};
}
};
@@ -138,15 +120,6 @@ public class IncludableGzipFilter extends GzipFilter
{
return new DeflaterOutputStream(_response.getOutputStream(),new Deflater(_deflateCompressionLevel, _deflateNoWrap));
}
-
- @Override
- protected void setHeader(String name, String value)
- {
- super.setHeader(name, value);
- HttpServletResponse response = (HttpServletResponse)getResponse();
- if (!response.containsHeader(name))
- response.setHeader("org.eclipse.jetty.server.include." + name, value);
- }
};
}
};
@@ -176,6 +149,16 @@ public class IncludableGzipFilter extends GzipFilter
if (!response.containsHeader(name))
response.setHeader("org.eclipse.jetty.server.include."+name,value);
}
+
+ @Override
+ public void addHeader(String name, String value)
+ {
+ super.addHeader(name, value);
+ HttpServletResponse response = (HttpServletResponse)getResponse();
+ if (!response.containsHeader(name))
+ setHeader(name,value);
+ }
+
@Override
protected PrintWriter newWriter(OutputStream out, String encoding) throws UnsupportedEncodingException
{
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/AbstractCompressedStream.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/AbstractCompressedStream.java
index bd10743932..60456a53ac 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/AbstractCompressedStream.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/AbstractCompressedStream.java
@@ -235,7 +235,7 @@ public abstract class AbstractCompressedStream extends ServletOutputStream
setHeader("Content-Encoding", _encoding);
if (_response.containsHeader("Content-Encoding"))
{
- setHeader("Vary",_vary);
+ addHeader("Vary",_vary);
_out=_compressedOutputStream=createStream();
if (_out!=null)
{
@@ -270,7 +270,7 @@ public abstract class AbstractCompressedStream extends ServletOutputStream
if (_out == null || _bOut != null)
{
if (sendVary)
- setHeader("Vary",_vary);
+ addHeader("Vary",_vary);
if (_wrapper.getETag()!=null)
setHeader("ETag",_wrapper.getETag());
@@ -342,6 +342,11 @@ public abstract class AbstractCompressedStream extends ServletOutputStream
return encoding == null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
}
+ protected void addHeader(String name,String value)
+ {
+ _response.addHeader(name, value);
+ }
+
protected void setHeader(String name,String value)
{
_response.setHeader(name, value);
diff --git a/jetty-spdy/pom.xml b/jetty-spdy/pom.xml
index 0a237216da..7b3020bd0e 100644
--- a/jetty-spdy/pom.xml
+++ b/jetty-spdy/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/jetty-spdy/spdy-client/pom.xml b/jetty-spdy/spdy-client/pom.xml
index 30609a1d1d..9bb89aeaea 100644
--- a/jetty-spdy/spdy-client/pom.xml
+++ b/jetty-spdy/spdy-client/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.spdy</groupId>
<artifactId>spdy-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java
index 2a23c5f2c1..2456a2228f 100644
--- a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java
+++ b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java
@@ -307,6 +307,7 @@ public class SPDYClient
{
final SSLEngine engine = client.newSSLEngine(sslContextFactory, channel);
SslConnection sslConnection = new SslConnection(bufferPool, getExecutor(), endPoint, engine);
+ sslConnection.setRenegotiationAllowed(sslContextFactory.isRenegotiationAllowed());
DecryptedEndPoint sslEndPoint = sslConnection.getDecryptedEndPoint();
NextProtoNegoClientConnection connection = new NextProtoNegoClientConnection(channel, sslEndPoint, attachment, getExecutor(), client);
sslEndPoint.setConnection(connection);
diff --git a/jetty-spdy/spdy-core/pom.xml b/jetty-spdy/spdy-core/pom.xml
index 520c59220c..3bd7e717b3 100644
--- a/jetty-spdy/spdy-core/pom.xml
+++ b/jetty-spdy/spdy-core/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.spdy</groupId>
<artifactId>spdy-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardSession.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardSession.java
index c642050f9e..a0bda51d2e 100644
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardSession.java
+++ b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardSession.java
@@ -110,7 +110,9 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
private final AtomicBoolean goAwaySent = new AtomicBoolean();
private final AtomicBoolean goAwayReceived = new AtomicBoolean();
private final AtomicInteger lastStreamId = new AtomicInteger();
+ private final AtomicInteger localStreamCount = new AtomicInteger(0);
private final FlowControlStrategy flowControlStrategy;
+ private volatile int maxConcurrentLocalStreams = -1;
private boolean flushing;
private Throwable failure;
@@ -181,6 +183,8 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
// TODO: for SPDYv3 we need to support the "slot" argument
SynStreamFrame synStream = new SynStreamFrame(version, synInfo.getFlags(), streamId, associatedStreamId, synInfo.getPriority(), (short)0, synInfo.getHeaders());
IStream stream = createStream(synStream, listener, true, promise);
+ if (stream == null)
+ return;
generateAndEnqueueControlFrame(stream, synStream, synInfo.getTimeout(), synInfo.getUnit(), stream);
}
flush();
@@ -535,15 +539,39 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
}
int streamId = stream.getId();
+
+ if (local)
+ {
+ while (true)
+ {
+ int oldStreamCountValue = localStreamCount.get();
+ int maxConcurrentStreams = maxConcurrentLocalStreams;
+ if (maxConcurrentStreams > -1 && oldStreamCountValue >= maxConcurrentStreams)
+ {
+ String msg = String.format("Max concurrent local streams (%d) exceeded.",
+ maxConcurrentStreams);
+ LOG.debug(msg);
+ promise.failed(new SPDYException(msg));
+ return null;
+ }
+ if (localStreamCount.compareAndSet(oldStreamCountValue, oldStreamCountValue + 1))
+ break;
+ }
+ }
+
if (streams.putIfAbsent(streamId, stream) != null)
{
+ //TODO: fail promise
if (local)
+ {
+ localStreamCount.decrementAndGet();
throw new IllegalStateException("Duplicate stream id " + streamId);
+ }
RstInfo rstInfo = new RstInfo(streamId, StreamStatus.PROTOCOL_ERROR);
LOG.debug("Duplicate stream, {}", rstInfo);
try
{
- rst(rstInfo);
+ rst(rstInfo); //TODO: non blocking reset or find the reason why blocking is used
}
catch (InterruptedException | ExecutionException | TimeoutException e)
{
@@ -554,8 +582,7 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
else
{
LOG.debug("Created {}", stream);
- if (local)
- notifyStreamCreated(stream);
+ notifyStreamCreated(stream);
return stream;
}
}
@@ -590,10 +617,15 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
IStream removed = streams.remove(stream.getId());
if (removed != null)
+ {
assert removed == stream;
- LOG.debug("Removed {}", stream);
- notifyStreamClosed(stream);
+ if (streamIds.get() % 2 == stream.getId() % 2)
+ localStreamCount.decrementAndGet();
+
+ LOG.debug("Removed {}", stream);
+ notifyStreamClosed(stream);
+ }
}
private void notifyStreamClosed(IStream stream)
@@ -666,6 +698,13 @@ public class StandardSession implements ISession, Parser.Listener, Dumpable
setWindowSize(windowSize);
LOG.debug("Updated session window size to {}", windowSize);
}
+ Settings.Setting maxConcurrentStreamsSetting = frame.getSettings().get(Settings.ID.MAX_CONCURRENT_STREAMS);
+ if (maxConcurrentStreamsSetting != null)
+ {
+ int maxConcurrentStreamsValue = maxConcurrentStreamsSetting.value();
+ maxConcurrentLocalStreams = maxConcurrentStreamsValue;
+ LOG.debug("Updated session maxConcurrentLocalStreams to {}", maxConcurrentStreamsValue);
+ }
SettingsInfo settingsInfo = new SettingsInfo(frame.getSettings(), frame.isClearPersisted());
notifyOnSettings(listener, settingsInfo);
flush();
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/StandardSessionTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/StandardSessionTest.java
index 44e56ff511..813fb0ceb5 100644
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/StandardSessionTest.java
+++ b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/StandardSessionTest.java
@@ -18,15 +18,6 @@
package org.eclipse.jetty.spdy;
-import static org.hamcrest.Matchers.greaterThan;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.util.HashSet;
@@ -47,12 +38,14 @@ import org.eclipse.jetty.spdy.api.PushInfo;
import org.eclipse.jetty.spdy.api.RstInfo;
import org.eclipse.jetty.spdy.api.SPDY;
import org.eclipse.jetty.spdy.api.Session;
+import org.eclipse.jetty.spdy.api.Settings;
import org.eclipse.jetty.spdy.api.Stream;
import org.eclipse.jetty.spdy.api.StreamFrameListener;
import org.eclipse.jetty.spdy.api.StreamStatus;
import org.eclipse.jetty.spdy.api.StringDataInfo;
import org.eclipse.jetty.spdy.api.SynInfo;
import org.eclipse.jetty.spdy.frames.DataFrame;
+import org.eclipse.jetty.spdy.frames.SettingsFrame;
import org.eclipse.jetty.spdy.frames.SynReplyFrame;
import org.eclipse.jetty.spdy.frames.SynStreamFrame;
import org.eclipse.jetty.spdy.generator.Generator;
@@ -74,6 +67,15 @@ import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
@RunWith(MockitoJUnitRunner.class)
public class StandardSessionTest
{
@@ -457,7 +459,30 @@ public class StandardSessionTest
stream.headers(new HeadersInfo(headers, true));
verify(controller, times(3)).write(any(ByteBuffer.class), any(Callback.class));
+ }
+
+ @Test
+ public void testMaxConcurrentStreams() throws InterruptedException
+ {
+ final CountDownLatch failedBecauseMaxConcurrentStreamsExceeded = new CountDownLatch(1);
+
+ Settings settings = new Settings();
+ settings.put(new Settings.Setting(Settings.ID.MAX_CONCURRENT_STREAMS, 0));
+ SettingsFrame settingsFrame = new SettingsFrame(VERSION, (byte)0, settings);
+ session.onControlFrame(settingsFrame);
+
+ PushSynInfo pushSynInfo = new PushSynInfo(1, new PushInfo(new Fields(), false));
+ session.syn(pushSynInfo, null, new Promise.Adapter<Stream>()
+ {
+ @Override
+ public void failed(Throwable x)
+ {
+ failedBecauseMaxConcurrentStreamsExceeded.countDown();
+ }
+ });
+ assertThat("Opening push stream failed because maxConcurrentStream is exceeded",
+ failedBecauseMaxConcurrentStreamsExceeded.await(5, TimeUnit.SECONDS), is(true));
}
@Test
diff --git a/jetty-spdy/spdy-example-webapp/pom.xml b/jetty-spdy/spdy-example-webapp/pom.xml
index 33bc39a953..37830b28be 100644
--- a/jetty-spdy/spdy-example-webapp/pom.xml
+++ b/jetty-spdy/spdy-example-webapp/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.spdy</groupId>
<artifactId>spdy-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spdy-example-webapp</artifactId>
diff --git a/jetty-spdy/spdy-http-server/pom.xml b/jetty-spdy/spdy-http-server/pom.xml
index a130ca48bb..c3ec31e2f2 100644
--- a/jetty-spdy/spdy-http-server/pom.xml
+++ b/jetty-spdy/spdy-http-server/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.spdy</groupId>
<artifactId>spdy-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spdy-http-server</artifactId>
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ReferrerPushStrategyTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ReferrerPushStrategyTest.java
index f52c87537d..099f736c1f 100644
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ReferrerPushStrategyTest.java
+++ b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ReferrerPushStrategyTest.java
@@ -101,14 +101,14 @@ public class ReferrerPushStrategyTest extends AbstractHTTPSPDYTest
@Test
public void testPushHeadersAreValid() throws Exception
{
- sendMainRequestAndCSSRequest();
+ sendMainRequestAndCSSRequest(null);
run2ndClientRequests(true, true);
}
@Test
public void testClientResetsPushStreams() throws Exception
{
- sendMainRequestAndCSSRequest();
+ sendMainRequestAndCSSRequest(null);
final CountDownLatch pushDataLatch = new CountDownLatch(1);
final CountDownLatch pushSynHeadersValid = new CountDownLatch(1);
Session session = startClient(version, serverAddress, null);
@@ -125,14 +125,14 @@ public class ReferrerPushStrategyTest extends AbstractHTTPSPDYTest
public void testUserAgentBlackList() throws Exception
{
pushStrategy.setUserAgentBlacklist(Arrays.asList(".*(?i)firefox/16.*"));
- sendMainRequestAndCSSRequest();
+ sendMainRequestAndCSSRequest(null);
run2ndClientRequests(false, false);
}
@Test
public void testReferrerPushPeriod() throws Exception
{
- Session session = sendMainRequestAndCSSRequest();
+ Session session = sendMainRequestAndCSSRequest(null);
// Sleep for pushPeriod This should prevent application.js from being mapped as pushResource
Thread.sleep(referrerPushPeriod + 1);
@@ -148,13 +148,38 @@ public class ReferrerPushStrategyTest extends AbstractHTTPSPDYTest
connector.addConnectionFactory(defaultFactory);
connector.setDefaultProtocol(defaultFactory.getProtocol()); // TODO I don't think this is right
- Session session = sendMainRequestAndCSSRequest();
+ Session session = sendMainRequestAndCSSRequest(null);
sendRequest(session, associatedJSRequestHeaders, null, null);
run2ndClientRequests(false, true);
}
+ @Test
+ public void testMaxConcurrentStreamsToDisablePush() throws Exception
+ {
+ final CountDownLatch pushReceivedLatch = new CountDownLatch(1);
+ Session session = sendMainRequestAndCSSRequest(new SessionFrameListener.Adapter()
+ {
+ @Override
+ public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
+ {
+ pushReceivedLatch.countDown();
+ return null;
+ }
+ });
+
+// Settings settings = new Settings();
+// settings.put(new Settings.Setting(Settings.ID.MAX_CONCURRENT_STREAMS, 0));
+// SettingsInfo settingsInfo = new SettingsInfo(settings);
+//
+// session.settings(settingsInfo);
+
+ sendRequest(session, mainRequestHeaders, null, null);
+
+ assertThat(pushReceivedLatch.await(1, TimeUnit.SECONDS), is(false));
+ }
+
private InetSocketAddress createServer() throws Exception
{
GzipHandler gzipHandler = new GzipHandler();
@@ -177,9 +202,9 @@ public class ReferrerPushStrategyTest extends AbstractHTTPSPDYTest
return startHTTPServer(version, gzipHandler);
}
- private Session sendMainRequestAndCSSRequest() throws Exception
+ private Session sendMainRequestAndCSSRequest(SessionFrameListener sessionFrameListener) throws Exception
{
- Session session = startClient(version, serverAddress, null);
+ Session session = startClient(version, serverAddress, sessionFrameListener);
sendRequest(session, mainRequestHeaders, null, null);
sendRequest(session, associatedCSSRequestHeaders, null, null);
@@ -197,7 +222,8 @@ public class ReferrerPushStrategyTest extends AbstractHTTPSPDYTest
@Override
public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
{
- validateHeaders(pushInfo.getHeaders(), pushSynHeadersValid);
+ if (pushSynHeadersValid != null)
+ validateHeaders(pushInfo.getHeaders(), pushSynHeadersValid);
assertThat("Stream is unidirectional", stream.isUnidirectional(), is(true));
assertThat("URI header ends with css", pushInfo.getHeaders().get(HTTPSPDYHeader.URI.name(version))
diff --git a/jetty-spdy/spdy-server/pom.xml b/jetty-spdy/spdy-server/pom.xml
index 9d7be56489..0bd4ca8974 100644
--- a/jetty-spdy/spdy-server/pom.xml
+++ b/jetty-spdy/spdy-server/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.spdy</groupId>
<artifactId>spdy-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/AbstractTest.java b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/AbstractTest.java
index 08625cc95c..cdbe2ba6c2 100644
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/AbstractTest.java
+++ b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/AbstractTest.java
@@ -53,13 +53,15 @@ public abstract class AbstractTest
}
};
+ protected final short version = SPDY.V2;
+
protected Server server;
protected SPDYClient.Factory clientFactory;
protected SPDYServerConnector connector;
protected InetSocketAddress startServer(ServerSessionFrameListener listener) throws Exception
{
- return startServer(SPDY.V2, listener);
+ return startServer(version, listener);
}
protected InetSocketAddress startServer(short version, ServerSessionFrameListener listener) throws Exception
@@ -99,7 +101,7 @@ public abstract class AbstractTest
protected Session startClient(InetSocketAddress socketAddress, SessionFrameListener listener) throws Exception
{
- return startClient(SPDY.V2, socketAddress, listener);
+ return startClient(version, socketAddress, listener);
}
protected Session startClient(short version, InetSocketAddress socketAddress, SessionFrameListener listener) throws Exception
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/MaxConcurrentStreamTest.java b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/MaxConcurrentStreamTest.java
new file mode 100644
index 0000000000..5c74ca395f
--- /dev/null
+++ b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/MaxConcurrentStreamTest.java
@@ -0,0 +1,120 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2013 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.spdy.server;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
+import org.eclipse.jetty.spdy.api.DataInfo;
+import org.eclipse.jetty.spdy.api.ReplyInfo;
+import org.eclipse.jetty.spdy.api.Session;
+import org.eclipse.jetty.spdy.api.SessionFrameListener;
+import org.eclipse.jetty.spdy.api.Settings;
+import org.eclipse.jetty.spdy.api.SettingsInfo;
+import org.eclipse.jetty.spdy.api.Stream;
+import org.eclipse.jetty.spdy.api.StreamFrameListener;
+import org.eclipse.jetty.spdy.api.SynInfo;
+import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
+import org.eclipse.jetty.util.BufferUtil;
+import org.eclipse.jetty.util.Fields;
+import org.junit.Test;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+public class MaxConcurrentStreamTest extends AbstractTest
+{
+ @Test
+ public void testMaxConcurrentStreamsSetByServer() throws Exception, ExecutionException
+ {
+ final CountDownLatch settingsReceivedLatch = new CountDownLatch(1);
+ final CountDownLatch dataReceivedLatch = new CountDownLatch(1);
+
+ Session session = startClient(startServer(new ServerSessionFrameListener.Adapter()
+ {
+ @Override
+ public void onConnect(Session session)
+ {
+ Settings settings = new Settings();
+ settings.put(new Settings.Setting(Settings.ID.MAX_CONCURRENT_STREAMS, 1));
+ try
+ {
+ session.settings(new SettingsInfo(settings));
+ }
+ catch (ExecutionException | InterruptedException | TimeoutException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
+ {
+ try
+ {
+ stream.reply(new ReplyInfo(true));
+ }
+ catch (ExecutionException | InterruptedException | TimeoutException e)
+ {
+ e.printStackTrace();
+ }
+ return new StreamFrameListener.Adapter()
+ {
+ @Override
+ public void onData(Stream stream, DataInfo dataInfo)
+ {
+ dataReceivedLatch.countDown();
+ }
+ };
+ }
+ }), new SessionFrameListener.Adapter()
+ {
+ @Override
+ public void onSettings(Session session, SettingsInfo settingsInfo)
+ {
+ settingsReceivedLatch.countDown();
+ }
+ });
+
+ assertThat("Settings frame received", settingsReceivedLatch.await(5, TimeUnit.SECONDS), is(true));
+
+ SynInfo synInfo = new SynInfo(new Fields(), false);
+ Stream stream = session.syn(synInfo, null);
+
+ boolean failed = false;
+ try
+ {
+ session.syn(synInfo, null);
+ }
+ catch (ExecutionException | InterruptedException | TimeoutException e)
+ {
+ failed = true;
+ }
+
+ assertThat("Opening second stream failed", failed, is(true));
+
+ stream.data(new ByteBufferDataInfo(BufferUtil.EMPTY_BUFFER, true));
+ assertThat("Data has been received on first stream.", dataReceivedLatch.await(5, TimeUnit.SECONDS), is(true));
+
+ session.syn(synInfo, null);
+ }
+}
diff --git a/jetty-spring/pom.xml b/jetty-spring/pom.xml
index d2ec7c59a5..97e3aa46ca 100644
--- a/jetty-spring/pom.xml
+++ b/jetty-spring/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-spring</artifactId>
diff --git a/jetty-start/pom.xml b/jetty-start/pom.xml
index 4a4ac6a85e..240d08cebb 100644
--- a/jetty-start/pom.xml
+++ b/jetty-start/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-start</artifactId>
diff --git a/jetty-util-ajax/pom.xml b/jetty-util-ajax/pom.xml
index 9b0a2be93b..247bfd21d2 100644
--- a/jetty-util-ajax/pom.xml
+++ b/jetty-util-ajax/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-util-ajax</artifactId>
diff --git a/jetty-util/pom.xml b/jetty-util/pom.xml
index a9b1a2f8c3..01bf1fb276 100644
--- a/jetty-util/pom.xml
+++ b/jetty-util/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-util</artifactId>
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/AbstractTrie.java b/jetty-util/src/main/java/org/eclipse/jetty/util/AbstractTrie.java
index dd2f53c933..a9cb82791c 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/AbstractTrie.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/AbstractTrie.java
@@ -57,16 +57,6 @@ public abstract class AbstractTrie<V> implements Trie<V>
return get(s,0,s.length());
}
-
- @Override
- public V get(ByteBuffer b, int offset, int len)
- {
- b=b.duplicate();
- b.position(b.position()+offset);
- b.limit(b.position()+len);
- return get(BufferUtil.toString(b,StringUtil.__ISO_8859_1_CHARSET));
- }
-
@Override
public V get(ByteBuffer b)
{
@@ -86,15 +76,6 @@ public abstract class AbstractTrie<V> implements Trie<V>
}
@Override
- public V getBest(ByteBuffer b, int offset, int len)
- {
- b=b.duplicate();
- b.position(b.position()+offset);
- b.limit(b.position()+len);
- return getBest(BufferUtil.toString(b,StringUtil.__ISO_8859_1_CHARSET));
- }
-
- @Override
public boolean isCaseInsensitive()
{
return _caseInsensitive;
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ArrayTernaryTrie.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ArrayTernaryTrie.java
index 7c92ac5477..312bd966fe 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/ArrayTernaryTrie.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ArrayTernaryTrie.java
@@ -18,6 +18,7 @@
package org.eclipse.jetty.util;
+import java.nio.ByteBuffer;
import java.util.HashSet;
import java.util.Set;
@@ -194,6 +195,45 @@ public class ArrayTernaryTrie<V> extends AbstractTrie<V>
}
+ @Override
+ public V get(ByteBuffer b, int offset, int length)
+ {
+ int t = _tree[EQ];
+ int len = length;
+ int i=0;
+ offset+=b.position();
+
+ while(i<len)
+ {
+ byte c=(byte)(b.get(offset+i++)&0x7f);
+ if(isCaseInsensitive())
+ c=(byte)StringUtil.lowercases[c];
+
+ while (true)
+ {
+ int row = ROW_SIZE*t;
+ char n=_tree[row];
+ int diff=n-c;
+
+ if (diff==0)
+ {
+ if (i==len)
+ return (V)_value[t];
+ t=_tree[row+EQ];
+ if (t==0)
+ return null;
+ break;
+ }
+
+ t=_tree[row+((diff<0)?LO:HI)];
+ if (t==0)
+ return null;
+ }
+ }
+
+ return null;
+ }
+
/* ------------------------------------------------------------ */
@Override
public V getBest(String s)
@@ -248,6 +288,95 @@ public class ArrayTernaryTrie<V> extends AbstractTrie<V>
}
+ /* ------------------------------------------------------------ */
+ @Override
+ public V getBest(ByteBuffer b, int offset, int len)
+ {
+ if (b.hasArray())
+ return getBest(_tree[EQ],b.array(),b.arrayOffset()+b.position()+offset,len);
+ return getBest(_tree[EQ],b,offset,len);
+ }
+
+ /* ------------------------------------------------------------ */
+ private V getBest(int t,byte[] b, int offset, int len)
+ {
+ int node=0;
+ for(int i=0; t!=0 && i<len; i++)
+ {
+ byte c=(byte)(b[offset+i]&0x7f);
+ if(isCaseInsensitive())
+ c=(byte)StringUtil.lowercases[c];
+
+ while (t!=0)
+ {
+ int row = ROW_SIZE*t;
+ char n=_tree[row];
+ int diff=n-c;
+
+ if (diff==0)
+ {
+ node=t;
+ t=_tree[row+EQ];
+
+ // if this node is a match, recurse to remember
+ if (_key[node]!=null)
+ {
+ V best=getBest(t,b,offset+i+1,len-i-1);
+ if (best!=null)
+ return best;
+ return (V)_value[node];
+ }
+
+ break;
+ }
+
+ t=_tree[row+((diff<0)?LO:HI)];
+ }
+ }
+ return null;
+ }
+
+ /* ------------------------------------------------------------ */
+ private V getBest(int t,ByteBuffer b, int offset, int len)
+ {
+ int node=0;
+ int o= offset+b.position();
+
+ for(int i=0; t!=0 && i<len; i++)
+ {
+ byte c=(byte)(b.get(o+i)&0x7f);
+ if(isCaseInsensitive())
+ c=(byte)StringUtil.lowercases[c];
+
+ while (t!=0)
+ {
+ int row = ROW_SIZE*t;
+ char n=_tree[row];
+ int diff=n-c;
+
+ if (diff==0)
+ {
+ node=t;
+ t=_tree[row+EQ];
+
+ // if this node is a match, recurse to remember
+ if (_key[node]!=null)
+ {
+ V best=getBest(t,b,offset+i+1,len-i-1);
+ if (best!=null)
+ return best;
+ return (V)_value[node];
+ }
+
+ break;
+ }
+
+ t=_tree[row+((diff<0)?LO:HI)];
+ }
+ }
+ return null;
+ }
+
@Override
public String toString()
{
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java
index a9630e6019..f80e5ab5f5 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java
@@ -218,8 +218,7 @@ public abstract class Resource implements ResourceFactory
{
URL url=null;
// Try to format as a URL?
- ClassLoader
- loader=Thread.currentThread().getContextClassLoader();
+ ClassLoader loader=Thread.currentThread().getContextClassLoader();
if (loader!=null)
{
try
@@ -251,7 +250,7 @@ public abstract class Resource implements ResourceFactory
{
url=ClassLoader.getSystemResource(resource);
if (url==null && resource.startsWith("/"))
- url=loader.getResource(resource.substring(1));
+ url=ClassLoader.getSystemResource(resource.substring(1));
}
if (url==null)
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java
index 857d199a81..f0ff187bb0 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java
@@ -41,6 +41,9 @@ import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.net.ssl.CertPathTrustManagerParameters;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
@@ -196,8 +199,12 @@ public class SslContextFactory extends AbstractLifeCycle
/** EndpointIdentificationAlgorithm - when set to "HTTPS" hostname verification will be enabled */
private String _endpointIdentificationAlgorithm = null;
+ /** Whether to blindly trust certificates */
private boolean _trustAll;
+ /** Whether TLS renegotiation is allowed */
+ private boolean _renegotiationAllowed = true;
+
/**
* Construct an instance of SslContextFactory
* Default constructor for use in XmlConfiguration files
@@ -369,6 +376,7 @@ public class SslContextFactory extends AbstractLifeCycle
}
/**
+ * You can either use the exact cipher suite name or a a regular expression.
* @param cipherSuites
* The array of cipher suite names to exclude from
* {@link SSLEngine#setEnabledCipherSuites(String[])}
@@ -399,6 +407,7 @@ public class SslContextFactory extends AbstractLifeCycle
}
/**
+ * You can either use the exact cipher suite name or a a regular expression.
* @param cipherSuites
* The array of cipher suite names to include in
* {@link SSLEngine#setEnabledCipherSuites(String[])}
@@ -760,6 +769,22 @@ public class SslContextFactory extends AbstractLifeCycle
}
/**
+ * @return whether TLS renegotiation is allowed (true by default)
+ */
+ public boolean isRenegotiationAllowed()
+ {
+ return _renegotiationAllowed;
+ }
+
+ /**
+ * @param renegotiationAllowed whether TLS renegotiation is allowed
+ */
+ public void setRenegotiationAllowed(boolean renegotiationAllowed)
+ {
+ _renegotiationAllowed = renegotiationAllowed;
+ }
+
+ /**
* @return Path to file that contains Certificate Revocation List
*/
public String getCrlPath()
@@ -1035,25 +1060,47 @@ public class SslContextFactory extends AbstractLifeCycle
*/
public String[] selectCipherSuites(String[] enabledCipherSuites, String[] supportedCipherSuites)
{
- Set<String> selected_ciphers = new LinkedHashSet<>();
+ Set<String> selected_ciphers = new CopyOnWriteArraySet<>();
// Set the starting ciphers - either from the included or enabled list
if (_includeCipherSuites!=null)
- {
- // Use only the supported included ciphers
- for (String cipherSuite : _includeCipherSuites)
- if(Arrays.asList(supportedCipherSuites).contains(cipherSuite))
- selected_ciphers.add(cipherSuite);
- }
+ processIncludeCipherSuites(supportedCipherSuites, selected_ciphers);
else
selected_ciphers.addAll(Arrays.asList(enabledCipherSuites));
+ removeExcludedCipherSuites(selected_ciphers);
- // Remove any excluded ciphers
- selected_ciphers.removeAll(_excludeCipherSuites);
return selected_ciphers.toArray(new String[selected_ciphers.size()]);
}
+ private void processIncludeCipherSuites(String[] supportedCipherSuites, Set<String> selected_ciphers)
+ {
+ for (String cipherSuite : _includeCipherSuites)
+ {
+ Pattern p = Pattern.compile(cipherSuite);
+ for (String supportedCipherSuite : supportedCipherSuites)
+ {
+ Matcher m = p.matcher(supportedCipherSuite);
+ if (m.matches())
+ selected_ciphers.add(supportedCipherSuite);
+ }
+ }
+ }
+
+ private void removeExcludedCipherSuites(Set<String> selected_ciphers)
+ {
+ for (String excludeCipherSuite : _excludeCipherSuites)
+ {
+ Pattern excludeCipherPattern = Pattern.compile(excludeCipherSuite);
+ for (String selectedCipherSuite : selected_ciphers)
+ {
+ Matcher m = excludeCipherPattern.matcher(selectedCipherSuite);
+ if (m.matches())
+ selected_ciphers.remove(selectedCipherSuite);
+ }
+ }
+ }
+
/**
* Check if the lifecycle has been started and throw runtime exception
*/
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java
index dcfa977da5..4ffc8022b8 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java
@@ -31,6 +31,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.eclipse.jetty.util.BlockingArrayQueue;
+import org.eclipse.jetty.util.ConcurrentArrayBlockingQueue;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
@@ -91,7 +92,7 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo
setStopTimeout(5000);
if (queue==null)
- queue=new BlockingArrayQueue<Runnable>(_minThreads, _minThreads);// TODO ConcurrentArrayBlockingQueue.Unbounded<Runnable>();
+ queue=new ConcurrentArrayBlockingQueue.Unbounded<Runnable>();
_jobs=queue;
}
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/QueueBenchmarkTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/QueueBenchmarkTest.java
new file mode 100644
index 0000000000..8990102bca
--- /dev/null
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/QueueBenchmarkTest.java
@@ -0,0 +1,226 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2013 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.util;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jetty.toolchain.test.AdvancedRunner;
+import org.eclipse.jetty.toolchain.test.annotation.Slow;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.junit.Assume;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@Ignore
+@RunWith(AdvancedRunner.class)
+public class QueueBenchmarkTest
+{
+ private static final Logger logger = Log.getLogger(QueueBenchmarkTest.class);
+ private static final Runnable ELEMENT = new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ }
+ };
+ private static final Runnable END = new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ }
+ };
+
+ @Slow
+ @Test
+ public void testQueues() throws Exception
+ {
+ int cores = Runtime.getRuntime().availableProcessors();
+ Assume.assumeTrue(cores > 1);
+
+ final int readers = cores / 2;
+ final int writers = readers;
+ final int iterations = 16 * 1024 * 1024;
+
+ final List<Queue<Runnable>> queues = new ArrayList<>();
+ queues.add(new ConcurrentArrayQueue<Runnable>()); // Jetty lock-free queue, allocating array blocks
+ queues.add(new ConcurrentLinkedQueue<Runnable>()); // JDK lock-free queue, allocating nodes
+ queues.add(new ArrayBlockingQueue<Runnable>(iterations * writers)); // JDK lock-based, circular array queue
+ queues.add(new BlockingArrayQueue<Runnable>(iterations * writers)); // Jetty lock-based, circular array queue
+
+ testQueues(readers, writers, iterations, queues, false);
+ }
+
+ @Slow
+ @Test
+ public void testBlockingQueues() throws Exception
+ {
+ int cores = Runtime.getRuntime().availableProcessors();
+ Assume.assumeTrue(cores > 1);
+
+ final int readers = cores / 2;
+ final int writers = readers;
+ final int iterations = 16 * 1024 * 1024;
+
+ final List<Queue<Runnable>> queues = new ArrayList<>();
+ queues.add(new ConcurrentArrayBlockingQueue.Unbounded<Runnable>());
+ queues.add(new ConcurrentArrayBlockingQueue.Bounded<Runnable>(iterations * writers));
+ queues.add(new LinkedBlockingQueue<Runnable>());
+ queues.add(new ArrayBlockingQueue<Runnable>(iterations * writers));
+ queues.add(new BlockingArrayQueue<Runnable>(iterations * writers));
+
+ testQueues(readers, writers, iterations, queues, true);
+ }
+
+ private void testQueues(final int readers, final int writers, final int iterations, List<Queue<Runnable>> queues, final boolean blocking) throws Exception
+ {
+ final int runs = 8;
+ int threads = readers + writers;
+ final CyclicBarrier barrier = new CyclicBarrier(threads + 1);
+
+ for (final Queue<Runnable> queue : queues)
+ {
+ for (int r = 0; r < runs; ++r)
+ {
+ for (int i = 0; i < readers; ++i)
+ {
+ Thread thread = new Thread()
+ {
+ @Override
+ public void run()
+ {
+ await(barrier);
+ consume(queue, writers, blocking);
+ await(barrier);
+ }
+ };
+ thread.start();
+ }
+ for (int i = 0; i < writers; ++i)
+ {
+ Thread thread = new Thread()
+ {
+ @Override
+ public void run()
+ {
+ await(barrier);
+ produce(queue, readers, iterations);
+ await(barrier);
+ }
+ };
+ thread.start();
+ }
+
+ await(barrier);
+ long begin = System.nanoTime();
+ await(barrier);
+ long end = System.nanoTime();
+ long elapsed = TimeUnit.NANOSECONDS.toMillis(end - begin);
+ logger.info("{} Readers/Writers: {}/{} => {} ms", queue.getClass().getSimpleName(), readers, writers, elapsed);
+ }
+ }
+ }
+
+ private static void consume(Queue<Runnable> queue, int writers, boolean blocking)
+ {
+ while (true)
+ {
+ Runnable element = blocking ? take(queue) : poll(queue);
+ if (element == END)
+ if (--writers == 0)
+ break;
+ }
+ }
+
+ private static void produce(Queue<Runnable> queue, int readers, int iterations)
+ {
+ for (int i = 0; i < iterations; ++i)
+ append(queue, ELEMENT);
+ for (int i = 0; i < readers; ++i)
+ append(queue, END);
+ }
+
+ private static void append(Queue<Runnable> queue, Runnable element)
+ {
+ if (!queue.offer(element))
+ logger.warn("Queue {} capacity is too small", queue);
+ }
+
+ private static Runnable take(Queue<Runnable> queue)
+ {
+ try
+ {
+ return ((BlockingQueue<Runnable>)queue).take();
+ }
+ catch (InterruptedException x)
+ {
+ throw new RuntimeException(x);
+ }
+ }
+
+ private static Runnable poll(Queue<Runnable> queue)
+ {
+ int loops = 0;
+ while (true)
+ {
+ Runnable element = queue.poll();
+ if (element != null)
+ return element;
+ // Busy loop
+ sleepMicros(1);
+ ++loops;
+ if (loops % 16 == 0)
+ logger.warn("Spin looping while polling empty queue: {} spins: ", loops);
+ }
+ }
+
+ private static void sleepMicros(long sleep)
+ {
+ try
+ {
+ TimeUnit.MICROSECONDS.sleep(sleep);
+ }
+ catch (InterruptedException x)
+ {
+ throw new RuntimeException(x);
+ }
+ }
+
+ private static void await(CyclicBarrier barrier)
+ {
+ try
+ {
+ barrier.await();
+ }
+ catch (Exception x)
+ {
+ throw new RuntimeException(x);
+ }
+ }
+}
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java
index 6122dfd024..980640c108 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java
@@ -18,15 +18,12 @@
package org.eclipse.jetty.util.ssl;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
+import javax.net.ssl.SSLEngine;
+
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.StdErrLog;
@@ -35,6 +32,12 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
public class SslContextFactoryTest
{
@@ -190,6 +193,30 @@ public class SslContextFactoryTest
}
@Test
+ public void testSetExcludeCipherSuitesRegex() throws Exception
+ {
+ cf.setExcludeCipherSuites(".*RC4.*");
+ cf.start();
+ SSLEngine sslEngine = cf.newSSLEngine();
+ String[] enabledCipherSuites = sslEngine.getEnabledCipherSuites();
+ assertThat("At least 1 cipherSuite is enabled", enabledCipherSuites.length, greaterThan(0));
+ for (String enabledCipherSuite : enabledCipherSuites)
+ assertThat("CipherSuite does not contain RC4", enabledCipherSuite.contains("RC4"), is(false));
+ }
+
+ @Test
+ public void testSetIncludeCipherSuitesRegex() throws Exception
+ {
+ cf.setIncludeCipherSuites(".*RC4.*");
+ cf.start();
+ SSLEngine sslEngine = cf.newSSLEngine();
+ String[] enabledCipherSuites = sslEngine.getEnabledCipherSuites();
+ assertThat("At least 1 cipherSuite is enabled", enabledCipherSuites.length, greaterThan(0));
+ for (String enabledCipherSuite : enabledCipherSuites)
+ assertThat("CipherSuite contains RC4", enabledCipherSuite.contains("RC4"), is(true));
+ }
+
+ @Test
public void testSetIncludeCipherSuitesPreservesOrder()
{
String[] supportedCipherSuites = new String[]{"cipher4", "cipher2", "cipher1", "cipher3"};
diff --git a/jetty-webapp/pom.xml b/jetty-webapp/pom.xml
index a1c8e4e521..f397e92005 100644
--- a/jetty-webapp/pom.xml
+++ b/jetty-webapp/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-webapp</artifactId>
diff --git a/jetty-websocket/pom.xml b/jetty-websocket/pom.xml
index 701c7ec6ba..8633efc83a 100644
--- a/jetty-websocket/pom.xml
+++ b/jetty-websocket/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>jetty-project</artifactId>
<groupId>org.eclipse.jetty</groupId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/jetty-websocket/websocket-api/pom.xml b/jetty-websocket/websocket-api/pom.xml
index 5dceaec9cf..f8500469f3 100644
--- a/jetty-websocket/websocket-api/pom.xml
+++ b/jetty-websocket/websocket-api/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/jetty-websocket/websocket-client/pom.xml b/jetty-websocket/websocket-client/pom.xml
index b06b251c33..ae009463dd 100644
--- a/jetty-websocket/websocket-client/pom.xml
+++ b/jetty-websocket/websocket-client/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/WebSocketClientSelectorManager.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/WebSocketClientSelectorManager.java
index 21c76954ff..e3f1669a54 100644
--- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/WebSocketClientSelectorManager.java
+++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/WebSocketClientSelectorManager.java
@@ -22,7 +22,6 @@ import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.util.concurrent.Executor;
-
import javax.net.ssl.SSLEngine;
import org.eclipse.jetty.io.ByteBufferPool;
@@ -82,6 +81,7 @@ public class WebSocketClientSelectorManager extends SelectorManager
{
SSLEngine engine = newSSLEngine(sslContextFactory,channel);
SslConnection sslConnection = new SslConnection(bufferPool,getExecutor(),endPoint,engine);
+ sslConnection.setRenegotiationAllowed(sslContextFactory.isRenegotiationAllowed());
EndPoint sslEndPoint = sslConnection.getDecryptedEndPoint();
Connection connection = newUpgradeConnection(channel,sslEndPoint,connectPromise);
diff --git a/jetty-websocket/websocket-common/pom.xml b/jetty-websocket/websocket-common/pom.xml
index aec3c9538d..eb052381ad 100644
--- a/jetty-websocket/websocket-common/pom.xml
+++ b/jetty-websocket/websocket-common/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/jetty-websocket/websocket-server/pom.xml b/jetty-websocket/websocket-server/pom.xml
index 45b533e208..25b95062c6 100644
--- a/jetty-websocket/websocket-server/pom.xml
+++ b/jetty-websocket/websocket-server/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java
index cb2770d24d..b7e80d3f25 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java
@@ -18,8 +18,6 @@
package org.eclipse.jetty.websocket.server;
-import static org.hamcrest.Matchers.*;
-
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -45,11 +43,15 @@ import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
+import org.junit.Ignore;
import org.junit.Test;
+import static org.hamcrest.Matchers.is;
+
/**
* Tests various close scenarios
*/
+@Ignore
public class WebSocketCloseTest
{
@SuppressWarnings("serial")
diff --git a/jetty-websocket/websocket-servlet/pom.xml b/jetty-websocket/websocket-servlet/pom.xml
index a9154bb186..826b5ccbfc 100644
--- a/jetty-websocket/websocket-servlet/pom.xml
+++ b/jetty-websocket/websocket-servlet/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/jetty-xml/pom.xml b/jetty-xml/pom.xml
index 111f47ab13..d8a39e8c6b 100644
--- a/jetty-xml/pom.xml
+++ b/jetty-xml/pom.xml
@@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-xml</artifactId>
diff --git a/pom.xml b/pom.xml
index 36e9d6ed07..0ffd760516 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
<version>20</version>
</parent>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
<name>Jetty :: Project</name>
<url>${jetty.url}</url>
<packaging>pom</packaging>
@@ -286,7 +286,7 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
- <argLine>-showversion -XX:+PrintGCDetails</argLine>
+ <argLine>-showversion -Xmx1g -Xms1g -XX:+PrintGCDetails</argLine>
<failIfNoTests>false</failIfNoTests>
<!--systemProperties>
<property>
@@ -709,7 +709,7 @@
})();
</script>
]]>
- </header>
+ </header>
</configuration>
</plugin>
</plugins>
diff --git a/tests/pom.xml b/tests/pom.xml
index fff3d3ad06..707898b0c6 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.eclipse.jetty.tests</groupId>
diff --git a/tests/test-continuation/pom.xml b/tests/test-continuation/pom.xml
index c63dceb029..e0da1c44df 100644
--- a/tests/test-continuation/pom.xml
+++ b/tests/test-continuation/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>tests-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/tests/test-loginservice/pom.xml b/tests/test-loginservice/pom.xml
index ef098c40d5..99e5b6d927 100644
--- a/tests/test-loginservice/pom.xml
+++ b/tests/test-loginservice/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>tests-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<artifactId>test-loginservice</artifactId>
<name>Jetty Tests :: Login Service</name>
diff --git a/tests/test-sessions/pom.xml b/tests/test-sessions/pom.xml
index a9262e0d02..dac197644d 100644
--- a/tests/test-sessions/pom.xml
+++ b/tests/test-sessions/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>tests-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<artifactId>test-sessions-parent</artifactId>
<name>Jetty Tests :: Sessions :: Parent</name>
diff --git a/tests/test-sessions/test-hash-sessions/pom.xml b/tests/test-sessions/test-hash-sessions/pom.xml
index 995656f33e..5a52c042e5 100644
--- a/tests/test-sessions/test-hash-sessions/pom.xml
+++ b/tests/test-sessions/test-hash-sessions/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-sessions-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<artifactId>test-hash-sessions</artifactId>
<name>Jetty Tests :: Sessions :: Hash</name>
diff --git a/tests/test-sessions/test-jdbc-sessions/pom.xml b/tests/test-sessions/test-jdbc-sessions/pom.xml
index 286b537fd0..46e03badaf 100644
--- a/tests/test-sessions/test-jdbc-sessions/pom.xml
+++ b/tests/test-sessions/test-jdbc-sessions/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-sessions-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<artifactId>test-jdbc-sessions</artifactId>
<name>Jetty Tests :: Sessions :: JDBC</name>
diff --git a/tests/test-sessions/test-sessions-common/pom.xml b/tests/test-sessions/test-sessions-common/pom.xml
index 37ea24b714..7c7a8b6bff 100644
--- a/tests/test-sessions/test-sessions-common/pom.xml
+++ b/tests/test-sessions/test-sessions-common/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-sessions-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<artifactId>test-sessions-common</artifactId>
<name>Jetty Tests :: Sessions :: Common</name>
diff --git a/tests/test-webapps/pom.xml b/tests/test-webapps/pom.xml
index e51971915a..f6ae8867f9 100644
--- a/tests/test-webapps/pom.xml
+++ b/tests/test-webapps/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>tests-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>test-webapps-parent</artifactId>
diff --git a/tests/test-webapps/test-jaas-webapp/pom.xml b/tests/test-webapps/test-jaas-webapp/pom.xml
index e77d24a142..fbffd7d94d 100644
--- a/tests/test-webapps/test-jaas-webapp/pom.xml
+++ b/tests/test-webapps/test-jaas-webapp/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-webapps-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<artifactId>test-jaas-webapp</artifactId>
<name>Jetty Tests :: WebApp :: JAAS</name>
diff --git a/tests/test-webapps/test-jetty-webapp/pom.xml b/tests/test-webapps/test-jetty-webapp/pom.xml
index 8efd3b764b..6aae466aac 100644
--- a/tests/test-webapps/test-jetty-webapp/pom.xml
+++ b/tests/test-webapps/test-jetty-webapp/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-webapps-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/tests/test-webapps/test-jndi-webapp/pom.xml b/tests/test-webapps/test-jndi-webapp/pom.xml
index 0ef65dcece..dd1a649e51 100644
--- a/tests/test-webapps/test-jndi-webapp/pom.xml
+++ b/tests/test-webapps/test-jndi-webapp/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-webapps-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<artifactId>test-jndi-webapp</artifactId>
<name>Jetty Tests :: WebApp :: JNDI</name>
diff --git a/tests/test-webapps/test-mock-resources/pom.xml b/tests/test-webapps/test-mock-resources/pom.xml
index edc6c82075..8bc98f22b9 100644
--- a/tests/test-webapps/test-mock-resources/pom.xml
+++ b/tests/test-webapps/test-mock-resources/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-webapps-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<name>Jetty Tests :: WebApp :: Mock Resources</name>
<artifactId>test-mock-resources</artifactId>
diff --git a/tests/test-webapps/test-proxy-webapp/pom.xml b/tests/test-webapps/test-proxy-webapp/pom.xml
index 5cab4d1ad6..42d505790e 100644
--- a/tests/test-webapps/test-proxy-webapp/pom.xml
+++ b/tests/test-webapps/test-proxy-webapp/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-webapps-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/tests/test-webapps/test-servlet-spec/pom.xml b/tests/test-webapps/test-servlet-spec/pom.xml
index be5640df7e..6c61e5743b 100644
--- a/tests/test-webapps/test-servlet-spec/pom.xml
+++ b/tests/test-webapps/test-servlet-spec/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-webapps-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<artifactId>test-servlet-spec-parent</artifactId>
<name>Jetty Tests :: Spec Test WebApp :: Parent</name>
diff --git a/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml b/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml
index f5ec148153..13ea272fb4 100644
--- a/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml
+++ b/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-servlet-spec-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<artifactId>test-container-initializer</artifactId>
<packaging>jar</packaging>
diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml
index ea70ea8000..44ac6d8d1f 100644
--- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml
+++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-servlet-spec-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<name>Jetty Tests :: Webapps :: Spec Webapp</name>
<artifactId>test-spec-webapp</artifactId>
diff --git a/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml b/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml
index f830a12523..e04bb1788b 100644
--- a/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml
+++ b/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-servlet-spec-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<name>Jetty Tests :: WebApp :: Servlet Spec :: Fragment Jar</name>
<groupId>org.eclipse.jetty.tests</groupId>
diff --git a/tests/test-webapps/test-webapp-rfc2616/pom.xml b/tests/test-webapps/test-webapp-rfc2616/pom.xml
index c8e3b9773e..0dd389f89c 100644
--- a/tests/test-webapps/test-webapp-rfc2616/pom.xml
+++ b/tests/test-webapps/test-webapp-rfc2616/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-webapps-parent</artifactId>
- <version>9.0.1-SNAPSHOT</version>
+ <version>9.0.2-SNAPSHOT</version>
</parent>
<artifactId>test-webapp-rfc2616</artifactId>
<name>Jetty Tests :: WebApp :: RFC2616</name>

Back to the top