From 67f3f05d7042a8e11f600bf077a0ee42caf0e4f7 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Thu, 8 Mar 2012 20:44:47 -0600 Subject: [PATCH 001/100] Updating VERSION.txt top section --- VERSION.txt | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index f92e93231c5..379f4da7229 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,6 +1,4 @@ -jetty-7.6.3-SNAPSHOT - -jetty-7.6.2.v20120302 - 02 March 2012 +jetty-7.6.2.v20120308 - 08 March 2012 + 370387 SafariWebsocketDraft0Test failure during build. + 371168 Update ClientCrossContextSessionTest + 372093 handle quotes in Require-Bundle manifest string @@ -9,7 +7,17 @@ jetty-7.6.2.v20120302 - 02 March 2012 will happen in the next major release (to avoid break implementers). + 372487 JDBCSessionManager does not work with Oracle + 372806 Command line should accept relative paths for xml config files + + 373037 jetty.server.Response.setContentLength(int) should not close a Writer + when length=0 + + 373162 add improved implementation for getParameterMap(), needs a test + though and the existing setup doesn't seem like it would easily support the + needed test so need to do that still + + 373306 Set default user agent extraction pattern for UserAgentFilter + + 373567 cert validation issue with ocsp and crldp always being enabled when + validating turned on fixed + + JETTY-1409 GzipFilter will double-compress application/x-gzip content + JETTY-1489 WebAppProvider attempts to deploy .svn folder + + JETTY-1494 . jetty-7.6.1.v20120215 - 15 February 2012 + 369121 simplified test From a63b3fdc5e6c29d9b4961889ac44edf1a9c2bce1 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Thu, 8 Mar 2012 21:09:37 -0600 Subject: [PATCH 002/100] [maven-release-plugin] prepare release jetty-7.6.2.v20120308 --- example-jetty-embedded/pom.xml | 2 +- jetty-aggregate/jetty-all-server/pom.xml | 2 +- jetty-aggregate/jetty-all/pom.xml | 2 +- jetty-aggregate/jetty-client/pom.xml | 2 +- jetty-aggregate/jetty-plus/pom.xml | 2 +- jetty-aggregate/jetty-server/pom.xml | 2 +- jetty-aggregate/jetty-servlet/pom.xml | 2 +- jetty-aggregate/jetty-webapp/pom.xml | 2 +- jetty-aggregate/jetty-websocket/pom.xml | 2 +- jetty-aggregate/pom.xml | 2 +- jetty-ajp/pom.xml | 2 +- jetty-annotations/pom.xml | 2 +- jetty-client/pom.xml | 2 +- jetty-continuation/pom.xml | 2 +- jetty-deploy/pom.xml | 2 +- jetty-distribution/pom.xml | 2 +- jetty-http-spi/pom.xml | 2 +- jetty-http/pom.xml | 2 +- jetty-io/pom.xml | 2 +- jetty-jaspi/pom.xml | 2 +- jetty-jmx/pom.xml | 2 +- jetty-jndi/pom.xml | 2 +- jetty-jsp/pom.xml | 2 +- jetty-monitor/pom.xml | 2 +- jetty-nested/pom.xml | 2 +- jetty-nosql/pom.xml | 2 +- jetty-npn/pom.xml | 6 ++---- jetty-osgi/jetty-osgi-boot-jsp/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-logback/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-warurl/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot/pom.xml | 2 +- jetty-osgi/jetty-osgi-equinoxtools/pom.xml | 2 +- jetty-osgi/jetty-osgi-httpservice/pom.xml | 2 +- jetty-osgi/pom.xml | 2 +- jetty-osgi/test-jetty-osgi/pom.xml | 2 +- jetty-overlay-deployer/pom.xml | 2 +- jetty-plus/pom.xml | 2 +- jetty-policy/pom.xml | 2 +- jetty-rewrite/pom.xml | 2 +- jetty-security/pom.xml | 2 +- jetty-server/pom.xml | 2 +- jetty-servlet/pom.xml | 2 +- jetty-servlets/pom.xml | 2 +- jetty-spdy/pom.xml | 5 ++--- jetty-spdy/spdy-core/pom.xml | 6 ++---- jetty-spdy/spdy-jetty-http-webapp/pom.xml | 5 ++--- jetty-spdy/spdy-jetty-http/pom.xml | 5 ++--- jetty-spdy/spdy-jetty/pom.xml | 5 ++--- jetty-start/pom.xml | 2 +- jetty-util/pom.xml | 2 +- jetty-webapp/pom.xml | 2 +- jetty-websocket/pom.xml | 2 +- jetty-xml/pom.xml | 2 +- pom.xml | 2 +- test-continuation/pom.xml | 2 +- test-jetty-nested/pom.xml | 2 +- test-jetty-servlet/pom.xml | 2 +- test-jetty-webapp/pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-integration/pom.xml | 2 +- tests/test-loginservice/pom.xml | 2 +- tests/test-sessions/pom.xml | 2 +- tests/test-sessions/test-hash-sessions/pom.xml | 2 +- tests/test-sessions/test-jdbc-sessions/pom.xml | 2 +- tests/test-sessions/test-mongodb-sessions/pom.xml | 2 +- tests/test-sessions/test-sessions-common/pom.xml | 2 +- tests/test-webapps/pom.xml | 2 +- tests/test-webapps/test-webapp-rfc2616/pom.xml | 2 +- 68 files changed, 74 insertions(+), 82 deletions(-) diff --git a/example-jetty-embedded/pom.xml b/example-jetty-embedded/pom.xml index a0c53ce5695..7fa75e8d60c 100644 --- a/example-jetty-embedded/pom.xml +++ b/example-jetty-embedded/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 example-jetty-embedded diff --git a/jetty-aggregate/jetty-all-server/pom.xml b/jetty-aggregate/jetty-all-server/pom.xml index 31b79ddbfb1..fff663e075e 100644 --- a/jetty-aggregate/jetty-all-server/pom.xml +++ b/jetty-aggregate/jetty-all-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.aggregate jetty-aggregate-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-all-server diff --git a/jetty-aggregate/jetty-all/pom.xml b/jetty-aggregate/jetty-all/pom.xml index e4a0593e7f7..644a8a2cecd 100644 --- a/jetty-aggregate/jetty-all/pom.xml +++ b/jetty-aggregate/jetty-all/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.aggregate jetty-aggregate-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-all diff --git a/jetty-aggregate/jetty-client/pom.xml b/jetty-aggregate/jetty-client/pom.xml index 819cbe7174f..97d468056ac 100644 --- a/jetty-aggregate/jetty-client/pom.xml +++ b/jetty-aggregate/jetty-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.aggregate jetty-aggregate-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-client diff --git a/jetty-aggregate/jetty-plus/pom.xml b/jetty-aggregate/jetty-plus/pom.xml index 40a65deac1c..e6bb57d718b 100644 --- a/jetty-aggregate/jetty-plus/pom.xml +++ b/jetty-aggregate/jetty-plus/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.aggregate jetty-aggregate-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-plus diff --git a/jetty-aggregate/jetty-server/pom.xml b/jetty-aggregate/jetty-server/pom.xml index b853d76d92f..fa25bb947d1 100644 --- a/jetty-aggregate/jetty-server/pom.xml +++ b/jetty-aggregate/jetty-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.aggregate jetty-aggregate-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-server diff --git a/jetty-aggregate/jetty-servlet/pom.xml b/jetty-aggregate/jetty-servlet/pom.xml index cd32b86e965..2c9c565248b 100644 --- a/jetty-aggregate/jetty-servlet/pom.xml +++ b/jetty-aggregate/jetty-servlet/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.aggregate jetty-aggregate-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-servlet diff --git a/jetty-aggregate/jetty-webapp/pom.xml b/jetty-aggregate/jetty-webapp/pom.xml index fa250deeb72..d6cf4d96ec2 100644 --- a/jetty-aggregate/jetty-webapp/pom.xml +++ b/jetty-aggregate/jetty-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.aggregate jetty-aggregate-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-webapp diff --git a/jetty-aggregate/jetty-websocket/pom.xml b/jetty-aggregate/jetty-websocket/pom.xml index a17a741d1d3..9d06f81adb8 100644 --- a/jetty-aggregate/jetty-websocket/pom.xml +++ b/jetty-aggregate/jetty-websocket/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.aggregate jetty-aggregate-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-websocket diff --git a/jetty-aggregate/pom.xml b/jetty-aggregate/pom.xml index 472419aaa38..810ac19555d 100644 --- a/jetty-aggregate/pom.xml +++ b/jetty-aggregate/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 org.eclipse.jetty.aggregate jetty-aggregate-project diff --git a/jetty-ajp/pom.xml b/jetty-ajp/pom.xml index 8fe8f311d52..e9675e1965f 100644 --- a/jetty-ajp/pom.xml +++ b/jetty-ajp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-ajp diff --git a/jetty-annotations/pom.xml b/jetty-annotations/pom.xml index 5a8051c2c4d..c2720c218cc 100644 --- a/jetty-annotations/pom.xml +++ b/jetty-annotations/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-annotations diff --git a/jetty-client/pom.xml b/jetty-client/pom.xml index f98e281b61f..b0fd96905b4 100644 --- a/jetty-client/pom.xml +++ b/jetty-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 diff --git a/jetty-continuation/pom.xml b/jetty-continuation/pom.xml index 2cfa65e7005..ea9d7487844 100644 --- a/jetty-continuation/pom.xml +++ b/jetty-continuation/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-continuation diff --git a/jetty-deploy/pom.xml b/jetty-deploy/pom.xml index 72cb042eebf..a82e8a17b7f 100644 --- a/jetty-deploy/pom.xml +++ b/jetty-deploy/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-deploy diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml index d588b06a85c..f083cac7d41 100644 --- a/jetty-distribution/pom.xml +++ b/jetty-distribution/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 jetty-distribution Jetty :: Distribution Assemblies diff --git a/jetty-http-spi/pom.xml b/jetty-http-spi/pom.xml index 87c81305902..535ad74d0df 100644 --- a/jetty-http-spi/pom.xml +++ b/jetty-http-spi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-http-spi diff --git a/jetty-http/pom.xml b/jetty-http/pom.xml index 66633339b18..83509484d22 100644 --- a/jetty-http/pom.xml +++ b/jetty-http/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-http diff --git a/jetty-io/pom.xml b/jetty-io/pom.xml index f5c8dcab778..bcae61d1d20 100644 --- a/jetty-io/pom.xml +++ b/jetty-io/pom.xml @@ -2,7 +2,7 @@ jetty-project org.eclipse.jetty - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-io diff --git a/jetty-jaspi/pom.xml b/jetty-jaspi/pom.xml index 3f82b9ebedb..5aa82011c1e 100644 --- a/jetty-jaspi/pom.xml +++ b/jetty-jaspi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-jaspi diff --git a/jetty-jmx/pom.xml b/jetty-jmx/pom.xml index 6cb2dbd152d..58e63981ada 100644 --- a/jetty-jmx/pom.xml +++ b/jetty-jmx/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-jmx diff --git a/jetty-jndi/pom.xml b/jetty-jndi/pom.xml index 23b4ee3ccf7..2c297a24d27 100644 --- a/jetty-jndi/pom.xml +++ b/jetty-jndi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-jndi diff --git a/jetty-jsp/pom.xml b/jetty-jsp/pom.xml index 11dee5659ad..f92a0e9e716 100644 --- a/jetty-jsp/pom.xml +++ b/jetty-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-jsp diff --git a/jetty-monitor/pom.xml b/jetty-monitor/pom.xml index ec560bb978c..e9b3dce73ef 100644 --- a/jetty-monitor/pom.xml +++ b/jetty-monitor/pom.xml @@ -19,7 +19,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-monitor diff --git a/jetty-nested/pom.xml b/jetty-nested/pom.xml index 99eca0d7756..596796b3dc7 100644 --- a/jetty-nested/pom.xml +++ b/jetty-nested/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 jetty-nested Jetty :: Nested diff --git a/jetty-nosql/pom.xml b/jetty-nosql/pom.xml index 09346853c9e..91ed00be4ac 100644 --- a/jetty-nosql/pom.xml +++ b/jetty-nosql/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-nosql diff --git a/jetty-npn/pom.xml b/jetty-npn/pom.xml index b251398c1e3..6079fdd9182 100644 --- a/jetty-npn/pom.xml +++ b/jetty-npn/pom.xml @@ -1,11 +1,9 @@ - + org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 diff --git a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml index 4baa60ac316..3517d3fe560 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 ../pom.xml 4.0.0 diff --git a/jetty-osgi/jetty-osgi-boot-logback/pom.xml b/jetty-osgi/jetty-osgi-boot-logback/pom.xml index c1ff444ca70..50834ac7e7f 100644 --- a/jetty-osgi/jetty-osgi-boot-logback/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-logback/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 ../pom.xml 4.0.0 diff --git a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml index 12df3058e17..7ee990bf679 100644 --- a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 ../pom.xml 4.0.0 diff --git a/jetty-osgi/jetty-osgi-boot/pom.xml b/jetty-osgi/jetty-osgi-boot/pom.xml index 277eb9db3f1..2a2585a95a0 100644 --- a/jetty-osgi/jetty-osgi-boot/pom.xml +++ b/jetty-osgi/jetty-osgi-boot/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 ../pom.xml 4.0.0 diff --git a/jetty-osgi/jetty-osgi-equinoxtools/pom.xml b/jetty-osgi/jetty-osgi-equinoxtools/pom.xml index 6c22c0850fc..6bcb3abf4b3 100644 --- a/jetty-osgi/jetty-osgi-equinoxtools/pom.xml +++ b/jetty-osgi/jetty-osgi-equinoxtools/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 ../pom.xml 4.0.0 diff --git a/jetty-osgi/jetty-osgi-httpservice/pom.xml b/jetty-osgi/jetty-osgi-httpservice/pom.xml index 9b20c736fa0..e1bf133af77 100644 --- a/jetty-osgi/jetty-osgi-httpservice/pom.xml +++ b/jetty-osgi/jetty-osgi-httpservice/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 ../pom.xml 4.0.0 diff --git a/jetty-osgi/pom.xml b/jetty-osgi/pom.xml index a6f22e17739..1f2501741e7 100644 --- a/jetty-osgi/pom.xml +++ b/jetty-osgi/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 ../pom.xml org.eclipse.jetty.osgi diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index a9fef116985..03b058752ae 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 ../pom.xml 4.0.0 diff --git a/jetty-overlay-deployer/pom.xml b/jetty-overlay-deployer/pom.xml index 3557aa19137..1f07c4b921a 100644 --- a/jetty-overlay-deployer/pom.xml +++ b/jetty-overlay-deployer/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-overlay-deployer diff --git a/jetty-plus/pom.xml b/jetty-plus/pom.xml index 68f6c07a650..efa698fef26 100644 --- a/jetty-plus/pom.xml +++ b/jetty-plus/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-plus diff --git a/jetty-policy/pom.xml b/jetty-policy/pom.xml index f7e7c616538..7bfdd703ce1 100644 --- a/jetty-policy/pom.xml +++ b/jetty-policy/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 jetty-policy Jetty :: Policy Tool diff --git a/jetty-rewrite/pom.xml b/jetty-rewrite/pom.xml index 58b9c36f24a..0c841fcee66 100644 --- a/jetty-rewrite/pom.xml +++ b/jetty-rewrite/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-rewrite diff --git a/jetty-security/pom.xml b/jetty-security/pom.xml index 08c0ba2efb6..6ee0f4f9d66 100644 --- a/jetty-security/pom.xml +++ b/jetty-security/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-security diff --git a/jetty-server/pom.xml b/jetty-server/pom.xml index f9c73e17fe5..74577e3e9d8 100644 --- a/jetty-server/pom.xml +++ b/jetty-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-server diff --git a/jetty-servlet/pom.xml b/jetty-servlet/pom.xml index abf9b924446..d9a6a54a914 100644 --- a/jetty-servlet/pom.xml +++ b/jetty-servlet/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-servlet diff --git a/jetty-servlets/pom.xml b/jetty-servlets/pom.xml index 434ddf68e09..6e74842a470 100644 --- a/jetty-servlets/pom.xml +++ b/jetty-servlets/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-servlets diff --git a/jetty-spdy/pom.xml b/jetty-spdy/pom.xml index 02a657f9ef0..a35cc62a119 100644 --- a/jetty-spdy/pom.xml +++ b/jetty-spdy/pom.xml @@ -1,10 +1,9 @@ - + org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 diff --git a/jetty-spdy/spdy-core/pom.xml b/jetty-spdy/spdy-core/pom.xml index e24895787fb..d8eb4e69055 100644 --- a/jetty-spdy/spdy-core/pom.xml +++ b/jetty-spdy/spdy-core/pom.xml @@ -1,11 +1,9 @@ - + org.eclipse.jetty.spdy spdy-parent - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 diff --git a/jetty-spdy/spdy-jetty-http-webapp/pom.xml b/jetty-spdy/spdy-jetty-http-webapp/pom.xml index 5640d31716b..9c325630c46 100644 --- a/jetty-spdy/spdy-jetty-http-webapp/pom.xml +++ b/jetty-spdy/spdy-jetty-http-webapp/pom.xml @@ -1,10 +1,9 @@ - + org.eclipse.jetty.spdy spdy-parent - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 spdy-jetty-http-webapp diff --git a/jetty-spdy/spdy-jetty-http/pom.xml b/jetty-spdy/spdy-jetty-http/pom.xml index 3a31efaa096..deab52246ce 100644 --- a/jetty-spdy/spdy-jetty-http/pom.xml +++ b/jetty-spdy/spdy-jetty-http/pom.xml @@ -1,10 +1,9 @@ - + org.eclipse.jetty.spdy spdy-parent - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 spdy-jetty-http diff --git a/jetty-spdy/spdy-jetty/pom.xml b/jetty-spdy/spdy-jetty/pom.xml index 24ebf0b4359..1b63f41450f 100644 --- a/jetty-spdy/spdy-jetty/pom.xml +++ b/jetty-spdy/spdy-jetty/pom.xml @@ -1,10 +1,9 @@ - + org.eclipse.jetty.spdy spdy-parent - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 spdy-jetty diff --git a/jetty-start/pom.xml b/jetty-start/pom.xml index 46b25d3821e..0980d46bf9f 100644 --- a/jetty-start/pom.xml +++ b/jetty-start/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-start diff --git a/jetty-util/pom.xml b/jetty-util/pom.xml index f7cd942be52..a8848b7bcb2 100644 --- a/jetty-util/pom.xml +++ b/jetty-util/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-util diff --git a/jetty-webapp/pom.xml b/jetty-webapp/pom.xml index 093a4202cbc..bcc434b82f7 100644 --- a/jetty-webapp/pom.xml +++ b/jetty-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-webapp diff --git a/jetty-websocket/pom.xml b/jetty-websocket/pom.xml index 180d1e69548..08f68f1a887 100644 --- a/jetty-websocket/pom.xml +++ b/jetty-websocket/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 diff --git a/jetty-xml/pom.xml b/jetty-xml/pom.xml index ff4f04d1d84..af71e675368 100644 --- a/jetty-xml/pom.xml +++ b/jetty-xml/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 jetty-xml diff --git a/pom.xml b/pom.xml index 6e4d55f5deb..3c5d4467747 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 19 jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 Jetty :: Project ${jetty.url} pom diff --git a/test-continuation/pom.xml b/test-continuation/pom.xml index 263146b982b..62a8e513ce1 100644 --- a/test-continuation/pom.xml +++ b/test-continuation/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 test-continuation diff --git a/test-jetty-nested/pom.xml b/test-jetty-nested/pom.xml index 2915d06fcf3..653de498294 100644 --- a/test-jetty-nested/pom.xml +++ b/test-jetty-nested/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 test-jetty-nested Jetty :: Nested Test diff --git a/test-jetty-servlet/pom.xml b/test-jetty-servlet/pom.xml index 1d1c2c41892..4ab2d2f8f58 100644 --- a/test-jetty-servlet/pom.xml +++ b/test-jetty-servlet/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 test-jetty-servlet diff --git a/test-jetty-webapp/pom.xml b/test-jetty-webapp/pom.xml index cfd04177fb6..bc4caeac4ec 100644 --- a/test-jetty-webapp/pom.xml +++ b/test-jetty-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 test-jetty-webapp diff --git a/tests/pom.xml b/tests/pom.xml index 566749bcd41..4aeb67551b0 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -21,7 +21,7 @@ org.eclipse.jetty jetty-project - 7.6.2-SNAPSHOT + 7.6.2.v20120308 org.eclipse.jetty.tests tests-parent diff --git a/tests/test-integration/pom.xml b/tests/test-integration/pom.xml index fab815f92c5..8b956453f52 100644 --- a/tests/test-integration/pom.xml +++ b/tests/test-integration/pom.xml @@ -20,7 +20,7 @@ org.eclipse.jetty.tests tests-parent - 7.6.2-SNAPSHOT + 7.6.2.v20120308 4.0.0 test-integration diff --git a/tests/test-loginservice/pom.xml b/tests/test-loginservice/pom.xml index 504748b30d5..51c2c462fd4 100644 --- a/tests/test-loginservice/pom.xml +++ b/tests/test-loginservice/pom.xml @@ -21,7 +21,7 @@ org.eclipse.jetty.tests tests-parent - 7.6.2-SNAPSHOT + 7.6.2.v20120308 test-loginservice Jetty Tests :: Login Service diff --git a/tests/test-sessions/pom.xml b/tests/test-sessions/pom.xml index 90cd048267b..6274b1ffecc 100644 --- a/tests/test-sessions/pom.xml +++ b/tests/test-sessions/pom.xml @@ -21,7 +21,7 @@ org.eclipse.jetty.tests tests-parent - 7.6.2-SNAPSHOT + 7.6.2.v20120308 test-sessions-parent Jetty Tests :: Sessions :: Parent diff --git a/tests/test-sessions/test-hash-sessions/pom.xml b/tests/test-sessions/test-hash-sessions/pom.xml index ac985f66af4..10ddbb9697b 100644 --- a/tests/test-sessions/test-hash-sessions/pom.xml +++ b/tests/test-sessions/test-hash-sessions/pom.xml @@ -21,7 +21,7 @@ org.eclipse.jetty.tests test-sessions-parent - 7.6.2-SNAPSHOT + 7.6.2.v20120308 test-hash-sessions Jetty Tests :: Sessions :: Hash diff --git a/tests/test-sessions/test-jdbc-sessions/pom.xml b/tests/test-sessions/test-jdbc-sessions/pom.xml index 0676a6aae9b..86357ba67df 100644 --- a/tests/test-sessions/test-jdbc-sessions/pom.xml +++ b/tests/test-sessions/test-jdbc-sessions/pom.xml @@ -21,7 +21,7 @@ org.eclipse.jetty.tests test-sessions-parent - 7.6.2-SNAPSHOT + 7.6.2.v20120308 test-jdbc-sessions Jetty Tests :: Sessions :: JDBC diff --git a/tests/test-sessions/test-mongodb-sessions/pom.xml b/tests/test-sessions/test-mongodb-sessions/pom.xml index 3e7cda34db2..768dda86d37 100644 --- a/tests/test-sessions/test-mongodb-sessions/pom.xml +++ b/tests/test-sessions/test-mongodb-sessions/pom.xml @@ -21,7 +21,7 @@ org.eclipse.jetty.tests test-sessions-parent - 7.6.2-SNAPSHOT + 7.6.2.v20120308 test-mongodb-sessions Jetty Tests :: Sessions :: Mongo diff --git a/tests/test-sessions/test-sessions-common/pom.xml b/tests/test-sessions/test-sessions-common/pom.xml index d6f6cfabfd1..f6f79a510df 100644 --- a/tests/test-sessions/test-sessions-common/pom.xml +++ b/tests/test-sessions/test-sessions-common/pom.xml @@ -21,7 +21,7 @@ org.eclipse.jetty.tests test-sessions-parent - 7.6.2-SNAPSHOT + 7.6.2.v20120308 test-sessions-common Jetty Tests :: Sessions :: Common diff --git a/tests/test-webapps/pom.xml b/tests/test-webapps/pom.xml index 2b6000b55e3..b69052b0124 100644 --- a/tests/test-webapps/pom.xml +++ b/tests/test-webapps/pom.xml @@ -21,7 +21,7 @@ org.eclipse.jetty.tests tests-parent - 7.6.2-SNAPSHOT + 7.6.2.v20120308 test-webapps-parent Jetty Tests :: WebApps :: Parent diff --git a/tests/test-webapps/test-webapp-rfc2616/pom.xml b/tests/test-webapps/test-webapp-rfc2616/pom.xml index 9518b6e14ac..38e6bd81b54 100644 --- a/tests/test-webapps/test-webapp-rfc2616/pom.xml +++ b/tests/test-webapps/test-webapp-rfc2616/pom.xml @@ -21,7 +21,7 @@ org.eclipse.jetty.tests test-webapps-parent - 7.6.2-SNAPSHOT + 7.6.2.v20120308 test-webapp-rfc2616 Jetty Tests :: WebApp :: RFC2616 From 246e3ed7561ce9e39ca64e20c7a1ca89c749ce16 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Thu, 8 Mar 2012 21:09:46 -0600 Subject: [PATCH 003/100] [maven-release-plugin] prepare for next development iteration --- example-jetty-embedded/pom.xml | 2 +- jetty-aggregate/jetty-all-server/pom.xml | 2 +- jetty-aggregate/jetty-all/pom.xml | 2 +- jetty-aggregate/jetty-client/pom.xml | 2 +- jetty-aggregate/jetty-plus/pom.xml | 2 +- jetty-aggregate/jetty-server/pom.xml | 2 +- jetty-aggregate/jetty-servlet/pom.xml | 2 +- jetty-aggregate/jetty-webapp/pom.xml | 2 +- jetty-aggregate/jetty-websocket/pom.xml | 2 +- jetty-aggregate/pom.xml | 2 +- jetty-ajp/pom.xml | 2 +- jetty-annotations/pom.xml | 2 +- jetty-client/pom.xml | 2 +- jetty-continuation/pom.xml | 2 +- jetty-deploy/pom.xml | 2 +- jetty-distribution/pom.xml | 2 +- jetty-http-spi/pom.xml | 2 +- jetty-http/pom.xml | 2 +- jetty-io/pom.xml | 2 +- jetty-jaspi/pom.xml | 2 +- jetty-jmx/pom.xml | 2 +- jetty-jndi/pom.xml | 2 +- jetty-jsp/pom.xml | 2 +- jetty-monitor/pom.xml | 2 +- jetty-nested/pom.xml | 2 +- jetty-nosql/pom.xml | 2 +- jetty-npn/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-jsp/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-logback/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-warurl/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot/pom.xml | 2 +- jetty-osgi/jetty-osgi-equinoxtools/pom.xml | 2 +- jetty-osgi/jetty-osgi-httpservice/pom.xml | 2 +- jetty-osgi/pom.xml | 2 +- jetty-osgi/test-jetty-osgi/pom.xml | 2 +- jetty-overlay-deployer/pom.xml | 2 +- jetty-plus/pom.xml | 2 +- jetty-policy/pom.xml | 2 +- jetty-rewrite/pom.xml | 2 +- jetty-security/pom.xml | 2 +- jetty-server/pom.xml | 2 +- jetty-servlet/pom.xml | 2 +- jetty-servlets/pom.xml | 2 +- jetty-spdy/pom.xml | 2 +- jetty-spdy/spdy-core/pom.xml | 2 +- jetty-spdy/spdy-jetty-http-webapp/pom.xml | 2 +- jetty-spdy/spdy-jetty-http/pom.xml | 2 +- jetty-spdy/spdy-jetty/pom.xml | 2 +- jetty-start/pom.xml | 2 +- jetty-util/pom.xml | 2 +- jetty-webapp/pom.xml | 2 +- jetty-websocket/pom.xml | 2 +- jetty-xml/pom.xml | 2 +- pom.xml | 2 +- test-continuation/pom.xml | 2 +- test-jetty-nested/pom.xml | 2 +- test-jetty-servlet/pom.xml | 2 +- test-jetty-webapp/pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-integration/pom.xml | 2 +- tests/test-loginservice/pom.xml | 2 +- tests/test-sessions/pom.xml | 2 +- tests/test-sessions/test-hash-sessions/pom.xml | 2 +- tests/test-sessions/test-jdbc-sessions/pom.xml | 2 +- tests/test-sessions/test-mongodb-sessions/pom.xml | 2 +- tests/test-sessions/test-sessions-common/pom.xml | 2 +- tests/test-webapps/pom.xml | 2 +- tests/test-webapps/test-webapp-rfc2616/pom.xml | 2 +- 68 files changed, 68 insertions(+), 68 deletions(-) diff --git a/example-jetty-embedded/pom.xml b/example-jetty-embedded/pom.xml index 7fa75e8d60c..d502516fcab 100644 --- a/example-jetty-embedded/pom.xml +++ b/example-jetty-embedded/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 example-jetty-embedded diff --git a/jetty-aggregate/jetty-all-server/pom.xml b/jetty-aggregate/jetty-all-server/pom.xml index fff663e075e..79cca0d1ac5 100644 --- a/jetty-aggregate/jetty-all-server/pom.xml +++ b/jetty-aggregate/jetty-all-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.aggregate jetty-aggregate-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-all-server diff --git a/jetty-aggregate/jetty-all/pom.xml b/jetty-aggregate/jetty-all/pom.xml index 644a8a2cecd..1732fe91454 100644 --- a/jetty-aggregate/jetty-all/pom.xml +++ b/jetty-aggregate/jetty-all/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.aggregate jetty-aggregate-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-all diff --git a/jetty-aggregate/jetty-client/pom.xml b/jetty-aggregate/jetty-client/pom.xml index 97d468056ac..d9564cc6500 100644 --- a/jetty-aggregate/jetty-client/pom.xml +++ b/jetty-aggregate/jetty-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.aggregate jetty-aggregate-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-client diff --git a/jetty-aggregate/jetty-plus/pom.xml b/jetty-aggregate/jetty-plus/pom.xml index e6bb57d718b..7b9072035ec 100644 --- a/jetty-aggregate/jetty-plus/pom.xml +++ b/jetty-aggregate/jetty-plus/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.aggregate jetty-aggregate-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-plus diff --git a/jetty-aggregate/jetty-server/pom.xml b/jetty-aggregate/jetty-server/pom.xml index fa25bb947d1..9d40c3c2874 100644 --- a/jetty-aggregate/jetty-server/pom.xml +++ b/jetty-aggregate/jetty-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.aggregate jetty-aggregate-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-server diff --git a/jetty-aggregate/jetty-servlet/pom.xml b/jetty-aggregate/jetty-servlet/pom.xml index 2c9c565248b..c07d0f0cb27 100644 --- a/jetty-aggregate/jetty-servlet/pom.xml +++ b/jetty-aggregate/jetty-servlet/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.aggregate jetty-aggregate-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-servlet diff --git a/jetty-aggregate/jetty-webapp/pom.xml b/jetty-aggregate/jetty-webapp/pom.xml index d6cf4d96ec2..601029b7fc4 100644 --- a/jetty-aggregate/jetty-webapp/pom.xml +++ b/jetty-aggregate/jetty-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.aggregate jetty-aggregate-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-webapp diff --git a/jetty-aggregate/jetty-websocket/pom.xml b/jetty-aggregate/jetty-websocket/pom.xml index 9d06f81adb8..64a63f6ce6c 100644 --- a/jetty-aggregate/jetty-websocket/pom.xml +++ b/jetty-aggregate/jetty-websocket/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.aggregate jetty-aggregate-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-websocket diff --git a/jetty-aggregate/pom.xml b/jetty-aggregate/pom.xml index 810ac19555d..e14e64cfe8f 100644 --- a/jetty-aggregate/pom.xml +++ b/jetty-aggregate/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT org.eclipse.jetty.aggregate jetty-aggregate-project diff --git a/jetty-ajp/pom.xml b/jetty-ajp/pom.xml index e9675e1965f..fd5738a61a1 100644 --- a/jetty-ajp/pom.xml +++ b/jetty-ajp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-ajp diff --git a/jetty-annotations/pom.xml b/jetty-annotations/pom.xml index c2720c218cc..0d70342a924 100644 --- a/jetty-annotations/pom.xml +++ b/jetty-annotations/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-annotations diff --git a/jetty-client/pom.xml b/jetty-client/pom.xml index b0fd96905b4..cc1680f72db 100644 --- a/jetty-client/pom.xml +++ b/jetty-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 diff --git a/jetty-continuation/pom.xml b/jetty-continuation/pom.xml index ea9d7487844..8fbbb06a52d 100644 --- a/jetty-continuation/pom.xml +++ b/jetty-continuation/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-continuation diff --git a/jetty-deploy/pom.xml b/jetty-deploy/pom.xml index a82e8a17b7f..8c860d28e25 100644 --- a/jetty-deploy/pom.xml +++ b/jetty-deploy/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-deploy diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml index f083cac7d41..a76dbaa55d6 100644 --- a/jetty-distribution/pom.xml +++ b/jetty-distribution/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT jetty-distribution Jetty :: Distribution Assemblies diff --git a/jetty-http-spi/pom.xml b/jetty-http-spi/pom.xml index 535ad74d0df..84c54ea3d23 100644 --- a/jetty-http-spi/pom.xml +++ b/jetty-http-spi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-http-spi diff --git a/jetty-http/pom.xml b/jetty-http/pom.xml index 83509484d22..73619e5cdbe 100644 --- a/jetty-http/pom.xml +++ b/jetty-http/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-http diff --git a/jetty-io/pom.xml b/jetty-io/pom.xml index bcae61d1d20..b96a6037e19 100644 --- a/jetty-io/pom.xml +++ b/jetty-io/pom.xml @@ -2,7 +2,7 @@ jetty-project org.eclipse.jetty - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-io diff --git a/jetty-jaspi/pom.xml b/jetty-jaspi/pom.xml index 5aa82011c1e..891baa6e469 100644 --- a/jetty-jaspi/pom.xml +++ b/jetty-jaspi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-jaspi diff --git a/jetty-jmx/pom.xml b/jetty-jmx/pom.xml index 58e63981ada..b6d1c526123 100644 --- a/jetty-jmx/pom.xml +++ b/jetty-jmx/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-jmx diff --git a/jetty-jndi/pom.xml b/jetty-jndi/pom.xml index 2c297a24d27..975d0354c4b 100644 --- a/jetty-jndi/pom.xml +++ b/jetty-jndi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-jndi diff --git a/jetty-jsp/pom.xml b/jetty-jsp/pom.xml index f92a0e9e716..9b7ffa4be2e 100644 --- a/jetty-jsp/pom.xml +++ b/jetty-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-jsp diff --git a/jetty-monitor/pom.xml b/jetty-monitor/pom.xml index e9b3dce73ef..9aaba66f66d 100644 --- a/jetty-monitor/pom.xml +++ b/jetty-monitor/pom.xml @@ -19,7 +19,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-monitor diff --git a/jetty-nested/pom.xml b/jetty-nested/pom.xml index 596796b3dc7..08c1c75622a 100644 --- a/jetty-nested/pom.xml +++ b/jetty-nested/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT jetty-nested Jetty :: Nested diff --git a/jetty-nosql/pom.xml b/jetty-nosql/pom.xml index 91ed00be4ac..d9a7d9d713a 100644 --- a/jetty-nosql/pom.xml +++ b/jetty-nosql/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-nosql diff --git a/jetty-npn/pom.xml b/jetty-npn/pom.xml index 6079fdd9182..89fefffbd69 100644 --- a/jetty-npn/pom.xml +++ b/jetty-npn/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 diff --git a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml index 3517d3fe560..229510055df 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-osgi/jetty-osgi-boot-logback/pom.xml b/jetty-osgi/jetty-osgi-boot-logback/pom.xml index 50834ac7e7f..4be355432a2 100644 --- a/jetty-osgi/jetty-osgi-boot-logback/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-logback/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml index 7ee990bf679..54439743d41 100644 --- a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-osgi/jetty-osgi-boot/pom.xml b/jetty-osgi/jetty-osgi-boot/pom.xml index 2a2585a95a0..2af33ad6470 100644 --- a/jetty-osgi/jetty-osgi-boot/pom.xml +++ b/jetty-osgi/jetty-osgi-boot/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-osgi/jetty-osgi-equinoxtools/pom.xml b/jetty-osgi/jetty-osgi-equinoxtools/pom.xml index 6bcb3abf4b3..8213e4ca137 100644 --- a/jetty-osgi/jetty-osgi-equinoxtools/pom.xml +++ b/jetty-osgi/jetty-osgi-equinoxtools/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-osgi/jetty-osgi-httpservice/pom.xml b/jetty-osgi/jetty-osgi-httpservice/pom.xml index e1bf133af77..767042c2a42 100644 --- a/jetty-osgi/jetty-osgi-httpservice/pom.xml +++ b/jetty-osgi/jetty-osgi-httpservice/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-osgi/pom.xml b/jetty-osgi/pom.xml index 1f2501741e7..d95a1b9e025 100644 --- a/jetty-osgi/pom.xml +++ b/jetty-osgi/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT ../pom.xml org.eclipse.jetty.osgi diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index 03b058752ae..f0cfa42690b 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-overlay-deployer/pom.xml b/jetty-overlay-deployer/pom.xml index 1f07c4b921a..ca9f243f9cc 100644 --- a/jetty-overlay-deployer/pom.xml +++ b/jetty-overlay-deployer/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-overlay-deployer diff --git a/jetty-plus/pom.xml b/jetty-plus/pom.xml index efa698fef26..195dc9e3f5e 100644 --- a/jetty-plus/pom.xml +++ b/jetty-plus/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-plus diff --git a/jetty-policy/pom.xml b/jetty-policy/pom.xml index 7bfdd703ce1..e1a8b37e946 100644 --- a/jetty-policy/pom.xml +++ b/jetty-policy/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT jetty-policy Jetty :: Policy Tool diff --git a/jetty-rewrite/pom.xml b/jetty-rewrite/pom.xml index 0c841fcee66..f555c1e10de 100644 --- a/jetty-rewrite/pom.xml +++ b/jetty-rewrite/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-rewrite diff --git a/jetty-security/pom.xml b/jetty-security/pom.xml index 6ee0f4f9d66..51b25dc0d52 100644 --- a/jetty-security/pom.xml +++ b/jetty-security/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-security diff --git a/jetty-server/pom.xml b/jetty-server/pom.xml index 74577e3e9d8..cd446cab611 100644 --- a/jetty-server/pom.xml +++ b/jetty-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-server diff --git a/jetty-servlet/pom.xml b/jetty-servlet/pom.xml index d9a6a54a914..444a41fb492 100644 --- a/jetty-servlet/pom.xml +++ b/jetty-servlet/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-servlet diff --git a/jetty-servlets/pom.xml b/jetty-servlets/pom.xml index 6e74842a470..47c149cb588 100644 --- a/jetty-servlets/pom.xml +++ b/jetty-servlets/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-servlets diff --git a/jetty-spdy/pom.xml b/jetty-spdy/pom.xml index a35cc62a119..081ff878d69 100644 --- a/jetty-spdy/pom.xml +++ b/jetty-spdy/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 diff --git a/jetty-spdy/spdy-core/pom.xml b/jetty-spdy/spdy-core/pom.xml index d8eb4e69055..058434a1491 100644 --- a/jetty-spdy/spdy-core/pom.xml +++ b/jetty-spdy/spdy-core/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.spdy spdy-parent - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 diff --git a/jetty-spdy/spdy-jetty-http-webapp/pom.xml b/jetty-spdy/spdy-jetty-http-webapp/pom.xml index 9c325630c46..41188017aec 100644 --- a/jetty-spdy/spdy-jetty-http-webapp/pom.xml +++ b/jetty-spdy/spdy-jetty-http-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.spdy spdy-parent - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 spdy-jetty-http-webapp diff --git a/jetty-spdy/spdy-jetty-http/pom.xml b/jetty-spdy/spdy-jetty-http/pom.xml index deab52246ce..9c35d0babcc 100644 --- a/jetty-spdy/spdy-jetty-http/pom.xml +++ b/jetty-spdy/spdy-jetty-http/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.spdy spdy-parent - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 spdy-jetty-http diff --git a/jetty-spdy/spdy-jetty/pom.xml b/jetty-spdy/spdy-jetty/pom.xml index 1b63f41450f..6332c18e01e 100644 --- a/jetty-spdy/spdy-jetty/pom.xml +++ b/jetty-spdy/spdy-jetty/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.spdy spdy-parent - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 spdy-jetty diff --git a/jetty-start/pom.xml b/jetty-start/pom.xml index 0980d46bf9f..c227d7a7ed1 100644 --- a/jetty-start/pom.xml +++ b/jetty-start/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-start diff --git a/jetty-util/pom.xml b/jetty-util/pom.xml index a8848b7bcb2..c254b68dab1 100644 --- a/jetty-util/pom.xml +++ b/jetty-util/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-util diff --git a/jetty-webapp/pom.xml b/jetty-webapp/pom.xml index bcc434b82f7..1d799705ea4 100644 --- a/jetty-webapp/pom.xml +++ b/jetty-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-webapp diff --git a/jetty-websocket/pom.xml b/jetty-websocket/pom.xml index 08f68f1a887..d42c1bdf925 100644 --- a/jetty-websocket/pom.xml +++ b/jetty-websocket/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 diff --git a/jetty-xml/pom.xml b/jetty-xml/pom.xml index af71e675368..86fecc83b55 100644 --- a/jetty-xml/pom.xml +++ b/jetty-xml/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 jetty-xml diff --git a/pom.xml b/pom.xml index 3c5d4467747..8edf9e2e289 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 19 jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT Jetty :: Project ${jetty.url} pom diff --git a/test-continuation/pom.xml b/test-continuation/pom.xml index 62a8e513ce1..95f92bdc42f 100644 --- a/test-continuation/pom.xml +++ b/test-continuation/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 test-continuation diff --git a/test-jetty-nested/pom.xml b/test-jetty-nested/pom.xml index 653de498294..8a26d325607 100644 --- a/test-jetty-nested/pom.xml +++ b/test-jetty-nested/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT test-jetty-nested Jetty :: Nested Test diff --git a/test-jetty-servlet/pom.xml b/test-jetty-servlet/pom.xml index 4ab2d2f8f58..c4b5870f581 100644 --- a/test-jetty-servlet/pom.xml +++ b/test-jetty-servlet/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 test-jetty-servlet diff --git a/test-jetty-webapp/pom.xml b/test-jetty-webapp/pom.xml index bc4caeac4ec..a8deb0a2f67 100644 --- a/test-jetty-webapp/pom.xml +++ b/test-jetty-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 test-jetty-webapp diff --git a/tests/pom.xml b/tests/pom.xml index 4aeb67551b0..fc08af9148b 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -21,7 +21,7 @@ org.eclipse.jetty jetty-project - 7.6.2.v20120308 + 7.6.3-SNAPSHOT org.eclipse.jetty.tests tests-parent diff --git a/tests/test-integration/pom.xml b/tests/test-integration/pom.xml index 8b956453f52..cd090026116 100644 --- a/tests/test-integration/pom.xml +++ b/tests/test-integration/pom.xml @@ -20,7 +20,7 @@ org.eclipse.jetty.tests tests-parent - 7.6.2.v20120308 + 7.6.3-SNAPSHOT 4.0.0 test-integration diff --git a/tests/test-loginservice/pom.xml b/tests/test-loginservice/pom.xml index 51c2c462fd4..0bd1190883e 100644 --- a/tests/test-loginservice/pom.xml +++ b/tests/test-loginservice/pom.xml @@ -21,7 +21,7 @@ org.eclipse.jetty.tests tests-parent - 7.6.2.v20120308 + 7.6.3-SNAPSHOT test-loginservice Jetty Tests :: Login Service diff --git a/tests/test-sessions/pom.xml b/tests/test-sessions/pom.xml index 6274b1ffecc..91c77c3b91b 100644 --- a/tests/test-sessions/pom.xml +++ b/tests/test-sessions/pom.xml @@ -21,7 +21,7 @@ org.eclipse.jetty.tests tests-parent - 7.6.2.v20120308 + 7.6.3-SNAPSHOT test-sessions-parent Jetty Tests :: Sessions :: Parent diff --git a/tests/test-sessions/test-hash-sessions/pom.xml b/tests/test-sessions/test-hash-sessions/pom.xml index 10ddbb9697b..6cdd8f83eb9 100644 --- a/tests/test-sessions/test-hash-sessions/pom.xml +++ b/tests/test-sessions/test-hash-sessions/pom.xml @@ -21,7 +21,7 @@ org.eclipse.jetty.tests test-sessions-parent - 7.6.2.v20120308 + 7.6.3-SNAPSHOT test-hash-sessions Jetty Tests :: Sessions :: Hash diff --git a/tests/test-sessions/test-jdbc-sessions/pom.xml b/tests/test-sessions/test-jdbc-sessions/pom.xml index 86357ba67df..9f8b64da707 100644 --- a/tests/test-sessions/test-jdbc-sessions/pom.xml +++ b/tests/test-sessions/test-jdbc-sessions/pom.xml @@ -21,7 +21,7 @@ org.eclipse.jetty.tests test-sessions-parent - 7.6.2.v20120308 + 7.6.3-SNAPSHOT test-jdbc-sessions Jetty Tests :: Sessions :: JDBC diff --git a/tests/test-sessions/test-mongodb-sessions/pom.xml b/tests/test-sessions/test-mongodb-sessions/pom.xml index 768dda86d37..c4a2b231af8 100644 --- a/tests/test-sessions/test-mongodb-sessions/pom.xml +++ b/tests/test-sessions/test-mongodb-sessions/pom.xml @@ -21,7 +21,7 @@ org.eclipse.jetty.tests test-sessions-parent - 7.6.2.v20120308 + 7.6.3-SNAPSHOT test-mongodb-sessions Jetty Tests :: Sessions :: Mongo diff --git a/tests/test-sessions/test-sessions-common/pom.xml b/tests/test-sessions/test-sessions-common/pom.xml index f6f79a510df..7eacd1a1268 100644 --- a/tests/test-sessions/test-sessions-common/pom.xml +++ b/tests/test-sessions/test-sessions-common/pom.xml @@ -21,7 +21,7 @@ org.eclipse.jetty.tests test-sessions-parent - 7.6.2.v20120308 + 7.6.3-SNAPSHOT test-sessions-common Jetty Tests :: Sessions :: Common diff --git a/tests/test-webapps/pom.xml b/tests/test-webapps/pom.xml index b69052b0124..a97c0f7dd63 100644 --- a/tests/test-webapps/pom.xml +++ b/tests/test-webapps/pom.xml @@ -21,7 +21,7 @@ org.eclipse.jetty.tests tests-parent - 7.6.2.v20120308 + 7.6.3-SNAPSHOT test-webapps-parent Jetty Tests :: WebApps :: Parent diff --git a/tests/test-webapps/test-webapp-rfc2616/pom.xml b/tests/test-webapps/test-webapp-rfc2616/pom.xml index 38e6bd81b54..4308f19d82b 100644 --- a/tests/test-webapps/test-webapp-rfc2616/pom.xml +++ b/tests/test-webapps/test-webapp-rfc2616/pom.xml @@ -21,7 +21,7 @@ org.eclipse.jetty.tests test-webapps-parent - 7.6.2.v20120308 + 7.6.3-SNAPSHOT test-webapp-rfc2616 Jetty Tests :: WebApp :: RFC2616 From 3561bcbf4056281a4c28b4030a34a56deab7460e Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Thu, 8 Mar 2012 21:53:24 -0600 Subject: [PATCH 004/100] set for dev --- VERSION.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/VERSION.txt b/VERSION.txt index 379f4da7229..a1f09a0276b 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,3 +1,5 @@ +jetty-7.6.3-SNAPSHOT + jetty-7.6.2.v20120308 - 08 March 2012 + 370387 SafariWebsocketDraft0Test failure during build. + 371168 Update ClientCrossContextSessionTest From 309a58647e07705f537a90bf00406252b5ea5730 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Fri, 9 Mar 2012 16:30:13 +1100 Subject: [PATCH 005/100] Fix package of org.glassfish.jsp --- jetty-osgi/jetty-osgi-boot-jsp/META-INF/MANIFEST.MF | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-osgi/jetty-osgi-boot-jsp/META-INF/MANIFEST.MF b/jetty-osgi/jetty-osgi-boot-jsp/META-INF/MANIFEST.MF index 27738d24434..313f9eba384 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/META-INF/MANIFEST.MF +++ b/jetty-osgi/jetty-osgi-boot-jsp/META-INF/MANIFEST.MF @@ -31,7 +31,7 @@ Import-Package: com.sun.el;resolution:=optional, org.apache.jasper.tagplugins.jstl;version="6.0.0";resolution:=optional, org.apache.jasper.util;version="6.0.0";resolution:=optional, org.apache.jasper.xmlparser;version="6.0.0";resolution:=optional, - org.glassfish.jasper.api;version="2.1.3";resolution:=optional, + org.glassfish.jsp.api;version="2.1.3";resolution:=optional, org.apache.taglibs.standard;version="1.2.0";resolution:=optional, org.apache.taglibs.standard.extra.spath;version="1.2.0";resolution:=optional, org.apache.taglibs.standard.functions;version="1.2.0";resolution:=optional, From d3b2a3ee0c17772337c95073932d91f184516efd Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Mon, 12 Mar 2012 12:24:52 +1100 Subject: [PATCH 006/100] 373269: only setHandled(true) if a servlet matches --- .../main/java/org/eclipse/jetty/servlet/ServletHandler.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java index 1a5e485f216..b9e2c24e58f 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java @@ -583,7 +583,8 @@ public class ServletHandler extends ScopedHandler } finally { - baseRequest.setHandled(true); + if (servlet_holder!=null) + baseRequest.setHandled(true); } } From 67ce45928c78f7550d45c72dc4ffa8c0616c9851 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Mon, 12 Mar 2012 12:25:24 +1100 Subject: [PATCH 007/100] added $Q handling to RewriteReqexRule --- .../rewrite/handler/RewriteRegexRule.java | 13 ++++++- .../rewrite/handler/RewriteRegexRuleTest.java | 39 ++++++++++++------- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java index 6c57e29bdf6..49a27dcee30 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java @@ -24,12 +24,15 @@ import org.eclipse.jetty.server.Request; * Rewrite the URI by matching with a regular expression. * The replacement string may use $n" to replace the nth capture group. * If the replacement string contains ? character, then it is split into a path - * and query string component. The returned target contains only the path. + * and query string component. The replacement query string may also contain $Q, which + * is replaced with the original query string. + * The returned target contains only the path. */ public class RewriteRegexRule extends RegexRule implements Rule.ApplyURI { private String _replacement; private String _query; + private boolean _queryGroup; /* ------------------------------------------------------------ */ public RewriteRegexRule() @@ -49,6 +52,7 @@ public class RewriteRegexRule extends RegexRule implements Rule.ApplyURI String[] split=replacement.split("\\?",2); _replacement = split[0]; _query=split.length==2?split[1]:null; + _queryGroup=_query!=null && _query.contains("$Q"); } @@ -73,7 +77,12 @@ public class RewriteRegexRule extends RegexRule implements Rule.ApplyURI } if (query!=null) + { + if (_queryGroup) + query=query.replace("$Q",request.getQueryString()==null?"":request.getQueryString()); request.setAttribute("org.eclipse.jetty.rewrite.handler.RewriteRegexRule.Q",query); + } + return target; } @@ -84,7 +93,7 @@ public class RewriteRegexRule extends RegexRule implements Rule.ApplyURI if (_query!=null) { String query=(String)request.getAttribute("org.eclipse.jetty.rewrite.handler.RewriteRegexRule.Q"); - if (request.getQueryString()==null) + if (_queryGroup||request.getQueryString()==null) request.setQueryString(query); else request.setQueryString(request.getQueryString()+"&"+query); diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java index 1464f67ab9c..55eecfafe45 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java @@ -23,13 +23,19 @@ public class RewriteRegexRuleTest extends AbstractRuleTestCase { private String[][] _tests= { - {"/foo/bar",".*","/replace","/replace",null}, - {"/foo/bar","/xxx.*","/replace",null,null}, - {"/foo/bar","/(.*)/(.*)","/$2/$1/xxx","/bar/foo/xxx",null}, - {"/foo/bar","/(foo)/(.*)(bar)","/$3/$1/xxx$2","/bar/foo/xxx",null}, - {"/foo/$bar",".*","/$replace","/$replace",null}, - {"/foo/$bar","/foo/(.*)","/$1/replace","/$bar/replace",null}, - {"/foo/bar/info","/foo/(NotHere)?([^/]*)/(.*)","/$3/other?p1=$2","/info/other","p1=bar"}, + {"/foo/bar",null,".*","/replace","/replace",null}, + {"/foo/bar","n=v",".*","/replace","/replace","n=v"}, + {"/foo/bar",null,"/xxx.*","/replace",null,null}, + {"/foo/bar",null,"/(.*)/(.*)","/$2/$1/xxx","/bar/foo/xxx",null}, + {"/foo/bar",null,"/(.*)/(.*)","/test?p2=$2&p1=$1","/test","p2=bar&p1=foo"}, + {"/foo/bar","n=v","/(.*)/(.*)","/test?p2=$2&p1=$1","/test","n=v&p2=bar&p1=foo"}, + {"/foo/bar",null,"/(foo)/(.*)(bar)","/$3/$1/xxx$2","/bar/foo/xxx",null}, + {"/foo/$bar",null,".*","/$replace","/$replace",null}, + {"/foo/$bar",null,"/foo/(.*)","/$1/replace","/$bar/replace",null}, + {"/foo/bar/info",null,"/foo/(NotHere)?([^/]*)/(.*)","/$3/other?p1=$2","/info/other","p1=bar"}, + {"/foo/bar/info",null,"/foo/(NotHere)?([^/]*)/(.*)","/$3/other?p1=$2&$Q","/info/other","p1=bar&"}, + {"/foo/bar/info","n=v","/foo/(NotHere)?([^/]*)/(.*)","/$3/other?p1=$2&$Q","/info/other","p1=bar&n=v"}, + {"/foo/bar/info","n=v","/foo/(NotHere)?([^/]*)/(.*)","/$3/other?p1=$2","/info/other","n=v&p1=bar"}, }; private RewriteRegexRule _rule; @@ -45,17 +51,20 @@ public class RewriteRegexRuleTest extends AbstractRuleTestCase { for (String[] test : _tests) { - _rule.setRegex(test[1]); - _rule.setReplacement(test[2]); - String result = _rule.matchAndApply(test[0], _request, _response); - assertEquals(test[1], test[3], result); - + String t=test[0]+"?"+test[1]+">"+test[2]+"|"+test[3]; + _rule.setRegex(test[2]); + _rule.setReplacement(test[3]); + _request.setRequestURI(test[0]); - _request.setQueryString(null); + _request.setQueryString(test[1]); + _request.getAttributes().clearAttributes(); + + String result = _rule.matchAndApply(test[0], _request, _response); + assertEquals(t, test[4], result); _rule.applyURI(_request,test[0],result); - assertEquals(test[3], _request.getRequestURI()); - assertEquals(test[4], _request.getQueryString()); + assertEquals(t,test[4], _request.getRequestURI()); + assertEquals(t,test[5], _request.getQueryString()); } } } From 9155ee46d000ceaf050db9647057ad86f20b6cd5 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Mon, 12 Mar 2012 23:59:23 +1100 Subject: [PATCH 008/100] 373951: regexrewrite will apply URI for all non null rule returns, even if target has not changed --- .../jetty/rewrite/handler/RuleContainer.java | 37 +++++++++---------- .../rewrite/handler/RewriteRegexRuleTest.java | 25 +++++++++++++ 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java index 0321859b27b..3ac926f8815 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java @@ -197,28 +197,25 @@ public class RuleContainer extends Rule if (applied!=null) { LOG.debug("applied {}",rule); - if (!target.equals(applied)) - { - LOG.debug("rewrote {} to {}",target,applied); - if (!original_set) - { - original_set=true; - request.setAttribute(_originalPathAttribute, target); - } + LOG.debug("rewrote {} to {}",target,applied); + if (!original_set) + { + original_set=true; + request.setAttribute(_originalPathAttribute, target); + } - if (_rewriteRequestURI) - { - if (rule instanceof Rule.ApplyURI && !target.equals(request.getRequestURI())) - ((Rule.ApplyURI)rule).applyURI((Request)request, target, applied); - else - ((Request)request).setRequestURI(applied); - } - - if (_rewritePathInfo) - ((Request)request).setPathInfo(applied); - - target=applied; + if (_rewriteRequestURI) + { + if (rule instanceof Rule.ApplyURI) + ((Rule.ApplyURI)rule).applyURI((Request)request, target, applied); + else + ((Request)request).setRequestURI(applied); } + + if (_rewritePathInfo) + ((Request)request).setPathInfo(applied); + + target=applied; if (rule.isHandling()) { diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java index 55eecfafe45..872bb6e5b85 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java @@ -29,6 +29,8 @@ public class RewriteRegexRuleTest extends AbstractRuleTestCase {"/foo/bar",null,"/(.*)/(.*)","/$2/$1/xxx","/bar/foo/xxx",null}, {"/foo/bar",null,"/(.*)/(.*)","/test?p2=$2&p1=$1","/test","p2=bar&p1=foo"}, {"/foo/bar","n=v","/(.*)/(.*)","/test?p2=$2&p1=$1","/test","n=v&p2=bar&p1=foo"}, + {"/foo/bar",null,"/(.*)/(.*)","/foo/bar?p2=$2&p1=$1","/foo/bar","p2=bar&p1=foo"}, + {"/foo/bar","n=v","/(.*)/(.*)","/foo/bar?p2=$2&p1=$1","/foo/bar","n=v&p2=bar&p1=foo"}, {"/foo/bar",null,"/(foo)/(.*)(bar)","/$3/$1/xxx$2","/bar/foo/xxx",null}, {"/foo/$bar",null,".*","/$replace","/$replace",null}, {"/foo/$bar",null,"/foo/(.*)","/$1/replace","/$bar/replace",null}, @@ -67,4 +69,27 @@ public class RewriteRegexRuleTest extends AbstractRuleTestCase assertEquals(t,test[5], _request.getQueryString()); } } + + @Test + public void testContainedRequestUriEnabled() throws IOException + { + RuleContainer container = new RuleContainer(); + container.setRewriteRequestURI(true); + container.addRule(_rule); + for (String[] test : _tests) + { + String t=test[0]+"?"+test[1]+">"+test[2]+"|"+test[3]; + _rule.setRegex(test[2]); + _rule.setReplacement(test[3]); + + _request.setRequestURI(test[0]); + _request.setQueryString(test[1]); + _request.getAttributes().clearAttributes(); + + String result = container.apply(test[0],_request,_response); + assertEquals(t,test[4]==null?test[0]:test[4], result); + assertEquals(t,test[4]==null?test[0]:test[4], _request.getRequestURI()); + assertEquals(t,test[5], _request.getQueryString()); + } + } } From 41874b5fbeff7db4b85ad0fbd3ca4a321092fe61 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Mon, 12 Mar 2012 15:30:26 +0100 Subject: [PATCH 009/100] Made the test portable between Jetty7 and Jetty8. --- .../jetty/spdy/http/ServerHTTPSPDYTest.java | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/jetty-spdy/spdy-jetty-http/src/test/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYTest.java b/jetty-spdy/spdy-jetty-http/src/test/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYTest.java index 2fea3ea340d..59370e5ce8e 100644 --- a/jetty-spdy/spdy-jetty-http/src/test/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYTest.java +++ b/jetty-spdy/spdy-jetty-http/src/test/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYTest.java @@ -31,8 +31,9 @@ import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.continuation.Continuation; +import org.eclipse.jetty.continuation.ContinuationSupport; import org.eclipse.jetty.io.ByteArrayBuffer; -import org.eclipse.jetty.server.AsyncContext; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.spdy.api.BytesDataInfo; @@ -975,7 +976,10 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest throws IOException, ServletException { request.setHandled(true); - final AsyncContext async = request.startAsync(); + + final Continuation continuation = ContinuationSupport.getContinuation(request); + continuation.suspend(); + new Thread() { @Override @@ -988,7 +992,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest int read = 0; while (read < data.length) read += input.read(buffer); - async.complete(); + continuation.complete(); latch.countDown(); } catch (IOException x) @@ -1034,7 +1038,10 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest throws IOException, ServletException { request.setHandled(true); - final AsyncContext async = request.startAsync(); + + final Continuation continuation = ContinuationSupport.getContinuation(request); + continuation.suspend(); + new Thread() { @Override @@ -1047,7 +1054,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest int read = 0; while (read < 2 * data.length) read += input.read(buffer); - async.complete(); + continuation.complete(); latch.countDown(); } catch (IOException x) @@ -1094,14 +1101,17 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest throws IOException, ServletException { request.setHandled(true); - if (request.getAsyncContinuation().isInitial()) + + final Continuation continuation = ContinuationSupport.getContinuation(request); + + if (continuation.isInitial()) { InputStream input = request.getInputStream(); byte[] buffer = new byte[256]; int read = 0; while (read < data.length) read += input.read(buffer); - final AsyncContext async = request.startAsync(); + continuation.suspend(); new Thread() { @Override @@ -1110,7 +1120,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest try { TimeUnit.SECONDS.sleep(1); - async.dispatch(); + continuation.resume(); latch.countDown(); } catch (InterruptedException x) From 9158115a82dd786ded740d5d0511628a6b29edf8 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Mon, 12 Mar 2012 15:31:23 +0100 Subject: [PATCH 010/100] Improved SPDY connector to take into account confidential and integral settings. --- .../spdy/http/HTTPSPDYServerConnector.java | 35 +++++++++++++++++++ .../jetty/spdy/SPDYServerConnector.java | 9 +++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/HTTPSPDYServerConnector.java b/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/HTTPSPDYServerConnector.java index 8f64049f1aa..b8359cde9c0 100644 --- a/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/HTTPSPDYServerConnector.java +++ b/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/HTTPSPDYServerConnector.java @@ -16,6 +16,11 @@ package org.eclipse.jetty.spdy.http; +import java.io.IOException; + +import org.eclipse.jetty.http.HttpSchemes; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.server.Request; import org.eclipse.jetty.spdy.AsyncConnectionFactory; import org.eclipse.jetty.spdy.SPDYServerConnector; import org.eclipse.jetty.spdy.api.SPDY; @@ -52,4 +57,34 @@ public class HTTPSPDYServerConnector extends SPDYServerConnector { return defaultConnectionFactory; } + + @Override + public void customize(EndPoint endPoint, Request request) throws IOException + { + super.customize(endPoint, request); + if (getSslContextFactory() != null) + request.setScheme(HttpSchemes.HTTPS); + } + + @Override + public boolean isConfidential(Request request) + { + if (getSslContextFactory() != null) + { + int confidentialPort = getConfidentialPort(); + return confidentialPort == 0 || confidentialPort == request.getServerPort(); + } + return super.isConfidential(request); + } + + @Override + public boolean isIntegral(Request request) + { + if (getSslContextFactory() != null) + { + int integralPort = getIntegralPort(); + return integralPort == 0 || integralPort == request.getServerPort(); + } + return super.isIntegral(request); + } } diff --git a/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYServerConnector.java b/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYServerConnector.java index be25c0fa4a4..6e5f913d69c 100644 --- a/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYServerConnector.java +++ b/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYServerConnector.java @@ -76,7 +76,7 @@ public class SPDYServerConnector extends SelectChannelConnector return bufferPool; } - protected Executor getExecutor() + public Executor getExecutor() { final ThreadPool threadPool = getThreadPool(); if (threadPool instanceof Executor) @@ -91,11 +91,16 @@ public class SPDYServerConnector extends SelectChannelConnector }; } - protected ScheduledExecutorService getScheduler() + public ScheduledExecutorService getScheduler() { return scheduler; } + public SslContextFactory getSslContextFactory() + { + return sslContextFactory; + } + @Override protected void doStart() throws Exception { From 56e726c20197ab7b2b5e146cf680b49621b0be66 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Tue, 13 Mar 2012 10:33:04 +1100 Subject: [PATCH 011/100] 374018 correctly handle requestperminuted underflow --- .../src/main/java/org/eclipse/jetty/servlets/DoSFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java index 6c12e2e75b3..d4494694999 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java @@ -992,7 +992,7 @@ public class DoSFilter implements Filter if (_rateTrackers != null && _trackerTimeoutQ != null) { long now = _trackerTimeoutQ.getNow(); - int latestIndex = _next == 0 ? 3 : (_next - 1 ) % _timestamps.length; + int latestIndex = _next == 0 ? (_timestamps.length-1) : (_next - 1 ); long last=_timestamps[latestIndex]; boolean hasRecentRequest = last != 0 && (now-last)<1000L; From 708f8ccaebb2d36112c4e6c44a198e74d72c3bf4 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 14 Mar 2012 11:48:06 +1100 Subject: [PATCH 012/100] 374158: do not asyncDispatch from SSL if suspended --- .../eclipse/jetty/io/nio/SslConnection.java | 4 +- .../jetty/server/HttpServerTestBase.java | 49 +++++++++++++++++++ .../jetty/server/SelectChannelServerTest.java | 7 +++ .../eclipse/jetty/server/SuspendHandler.java | 3 +- .../ssl/SelectChannelServerSslTest.java | 7 ++- 5 files changed, 65 insertions(+), 5 deletions(-) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java index 4b8e0a55d1d..08dcbb4aeda 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java @@ -408,7 +408,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection } // If we are reading into the temp buffer and it has some content, then we should be dispatched. - if (toFill==_unwrapBuf && _unwrapBuf.hasContent()) + if (toFill==_unwrapBuf && _unwrapBuf.hasContent() && !_connection.isSuspended()) _aEndp.asyncDispatch(); } finally @@ -550,7 +550,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection break; case BUFFER_OVERFLOW: - _logger.debug("{} unwrap {} {}->{}",_session,result.getStatus(),_inbound.toDetailString(),buffer.toDetailString()); + if (_logger.isDebugEnabled()) _logger.debug("{} unwrap {} {}->{}",_session,result.getStatus(),_inbound.toDetailString(),buffer.toDetailString()); break; case OK: diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java index de3cc399594..ccc53ba9e30 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java @@ -39,9 +39,11 @@ import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.StdErrLog; +import org.hamcrest.CoreMatchers; import org.hamcrest.Matchers; import org.junit.Test; import org.junit.matchers.JUnitMatchers; +import org.mockito.internal.matchers.Contains; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.junit.Assert.assertEquals; @@ -1280,4 +1282,51 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture response.setStatus(200); } } + + + @Test + public void testSuspendedPipeline() throws Exception + { + SuspendHandler suspend = new SuspendHandler(); + suspend.setSuspendFor(30000); + suspend.setResumeAfter(1000); + configureServer(suspend); + + long start=System.currentTimeMillis(); + Socket client=newSocket(HOST,_connector.getLocalPort()); + try + { + OutputStream os=client.getOutputStream(); + InputStream is=client.getInputStream(); + + // write an initial request + os.write(( + "GET / HTTP/1.1\r\n"+ + "host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+ + "\r\n" + ).getBytes()); + os.flush(); + + Thread.sleep(200); + + // write an pipelined request + os.write(( + "GET / HTTP/1.1\r\n"+ + "host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+ + "connection: close\r\n"+ + "\r\n" + ).getBytes()); + os.flush(); + + String response=readResponse(client); + assertThat(response,JUnitMatchers.containsString("RESUMEDHTTP/1.1 200 OK")); + assertThat((System.currentTimeMillis()-start),greaterThanOrEqualTo(1999L)); + + // TODO This test should also check that that the CPU did not spin during the suspend. + } + finally + { + client.close(); + } + } } diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelServerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelServerTest.java index d32593a83e2..b8f2b2c55a7 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelServerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelServerTest.java @@ -31,6 +31,13 @@ public class SelectChannelServerTest extends HttpServerTestBase { super.testCommittedError(); } + + @Override + public void testSuspendedPipeline() throws Exception + { + // TODO Auto-generated method stub + super.testSuspendedPipeline(); + } } diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/SuspendHandler.java b/jetty-server/src/test/java/org/eclipse/jetty/server/SuspendHandler.java index f5ea64c3bd1..1c16dc956ab 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/SuspendHandler.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/SuspendHandler.java @@ -121,8 +121,7 @@ class SuspendHandler extends HandlerWrapper try { Thread.sleep(_resumeAfter); - if(((HttpServletRequest)asyncContext.getRequest()).getSession(true).getId()!=null) - asyncContext.dispatch(); + asyncContext.dispatch(); } catch(Exception e) { diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java index f669bb53689..2e6883a2968 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java @@ -144,5 +144,10 @@ public class SelectChannelServerSslTest extends HttpServerTestBase { } - + + @Override + public void testSuspendedPipeline() throws Exception + { + super.testSuspendedPipeline(); + } } From 15b620c2d57847dfb0ba05fbc177d52776a256c0 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Wed, 14 Mar 2012 12:07:25 +1100 Subject: [PATCH 013/100] 374152 jetty-all-server MANIFEST contains wrong import: javax.servlet.annotation;version="[2.6,3)" --- jetty-aggregate/jetty-all-server/pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jetty-aggregate/jetty-all-server/pom.xml b/jetty-aggregate/jetty-all-server/pom.xml index cee39b8ffcf..6c794e0e900 100644 --- a/jetty-aggregate/jetty-all-server/pom.xml +++ b/jetty-aggregate/jetty-all-server/pom.xml @@ -80,6 +80,8 @@ !org.eclipse.jetty*, javax.annotation;version="1.0.0";resolution:=optional, javax.servlet;version="2.6.0", + javax.servlet.annotation;version="2.6.0", + javax.servlet.descriptor;version="2.6.0", javax.servlet.http;version="2.6.0", javax.mail;version="1.4.0";resolution:=optional, javax.mail.event;version="1.4.0";resolution:=optional, From 4a02fdb6c07ced65a9830cf951dcaf5bf347b60f Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 14 Mar 2012 16:12:46 +0100 Subject: [PATCH 014/100] 374252 - SslConnection.onClose() does not forward to nested connection. --- .../src/main/java/org/eclipse/jetty/io/nio/SslConnection.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java index 4b8e0a55d1d..647ee30d444 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java @@ -237,6 +237,9 @@ public class SslConnection extends AbstractConnection implements AsyncConnection /* ------------------------------------------------------------ */ public void onClose() { + Connection connection = _sslEndPoint.getConnection(); + if (connection != null && connection != this) + connection.onClose(); } /* ------------------------------------------------------------ */ From ab9bcf26b2b91b76fa2515bb2cea7a268d0948bc Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 14 Mar 2012 16:31:29 +0100 Subject: [PATCH 015/100] 374258 - SPDY leaks SSLEngines --- .../java/org/eclipse/jetty/spdy/Promise.java | 4 +- .../org/eclipse/jetty/spdy/SPDYClient.java | 34 ++++++++++--- .../jetty/spdy/SPDYServerConnector.java | 25 +++++++++- .../eclipse/jetty/spdy/SSLEngineLeakTest.java | 48 +++++++++++++++++++ 4 files changed, 102 insertions(+), 9 deletions(-) create mode 100644 jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLEngineLeakTest.java diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/Promise.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/Promise.java index ef3eee17d1e..d44da62dee8 100644 --- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/Promise.java +++ b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/Promise.java @@ -80,7 +80,9 @@ public class Promise implements Handler, Future @Override public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - latch.await(timeout, unit); + boolean elapsed = !latch.await(timeout, unit); + if (elapsed) + throw new TimeoutException(); return result(); } diff --git a/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYClient.java b/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYClient.java index 818cd8572cd..438e2e3cf03 100644 --- a/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYClient.java +++ b/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYClient.java @@ -38,6 +38,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.atomic.AtomicReference; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLException; @@ -313,7 +314,7 @@ public class SPDYClient } @Override - public AsyncConnection newConnection(final SocketChannel channel, AsyncEndPoint endPoint, final Object attachment) + public AsyncConnection newConnection(final SocketChannel channel, AsyncEndPoint endPoint, Object attachment) { SessionPromise sessionPromise = (SessionPromise)attachment; final SPDYClient client = sessionPromise.client; @@ -322,11 +323,31 @@ public class SPDYClient { if (sslContextFactory != null) { + final AtomicReference sslEndPointRef = new AtomicReference<>(); + final AtomicReference attachmentRef = new AtomicReference<>(attachment); SSLEngine engine = client.newSSLEngine(sslContextFactory, channel); - SslConnection sslConnection = new SslConnection(engine, endPoint); + SslConnection sslConnection = new SslConnection(engine, endPoint) + { + @Override + public void onClose() + { + sslEndPointRef.set(null); + attachmentRef.set(null); + super.onClose(); + } + }; endPoint.setConnection(sslConnection); - final AsyncEndPoint sslEndPoint = sslConnection.getSslEndPoint(); + AsyncEndPoint sslEndPoint = sslConnection.getSslEndPoint(); + sslEndPointRef.set(sslEndPoint); + // Instances of the ClientProvider inner class strong reference the + // SslEndPoint (via lexical scoping), which strong references the SSLEngine. + // Since NextProtoNego stores in a WeakHashMap the SSLEngine as key + // and this instance as value, we are in the situation where the value + // of a WeakHashMap refers indirectly to the key, which is bad because + // the entry will never be removed from the WeakHashMap. + // We use AtomicReferences to be captured via lexical scoping, + // and we null them out above when the connection is closed. NextProtoNego.put(engine, new NextProtoNego.ClientProvider() { @Override @@ -340,7 +361,8 @@ public class SPDYClient { // Server does not support NPN, but this is a SPDY client, so hardcode SPDY ClientSPDYAsyncConnectionFactory connectionFactory = new ClientSPDYAsyncConnectionFactory(); - AsyncConnection connection = connectionFactory.newAsyncConnection(channel, sslEndPoint, attachment); + AsyncEndPoint sslEndPoint = sslEndPointRef.get(); + AsyncConnection connection = connectionFactory.newAsyncConnection(channel, sslEndPoint, attachmentRef.get()); sslEndPoint.setConnection(connection); } @@ -352,9 +374,9 @@ public class SPDYClient return null; AsyncConnectionFactory connectionFactory = client.getAsyncConnectionFactory(protocol); - AsyncConnection connection = connectionFactory.newAsyncConnection(channel, sslEndPoint, attachment); + AsyncEndPoint sslEndPoint = sslEndPointRef.get(); + AsyncConnection connection = connectionFactory.newAsyncConnection(channel, sslEndPoint, attachmentRef.get()); sslEndPoint.setConnection(connection); - return protocol; } }); diff --git a/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYServerConnector.java b/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYServerConnector.java index 6e5f913d69c..2a496070f96 100644 --- a/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYServerConnector.java +++ b/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYServerConnector.java @@ -29,6 +29,7 @@ import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLException; @@ -176,16 +177,35 @@ public class SPDYServerConnector extends SelectChannelConnector if (sslContextFactory != null) { SSLEngine engine = newSSLEngine(sslContextFactory, channel); - SslConnection sslConnection = new SslConnection(engine, endPoint); + final AtomicReference sslEndPointRef = new AtomicReference<>(); + SslConnection sslConnection = new SslConnection(engine, endPoint) + { + @Override + public void onClose() + { + sslEndPointRef.set(null); + super.onClose(); + } + }; endPoint.setConnection(sslConnection); - final AsyncEndPoint sslEndPoint = sslConnection.getSslEndPoint(); + AsyncEndPoint sslEndPoint = sslConnection.getSslEndPoint(); + sslEndPointRef.set(sslEndPoint); + // Instances of the ServerProvider inner class strong reference the + // SslEndPoint (via lexical scoping), which strong references the SSLEngine. + // Since NextProtoNego stores in a WeakHashMap the SSLEngine as key + // and this instance as value, we are in the situation where the value + // of a WeakHashMap refers indirectly to the key, which is bad because + // the entry will never be removed from the WeakHashMap. + // We use AtomicReferences to be captured via lexical scoping, + // and we null them out above when the connection is closed. NextProtoNego.put(engine, new NextProtoNego.ServerProvider() { @Override public void unsupported() { AsyncConnectionFactory connectionFactory = getDefaultAsyncConnectionFactory(); + AsyncEndPoint sslEndPoint = sslEndPointRef.get(); AsyncConnection connection = connectionFactory.newAsyncConnection(channel, sslEndPoint, SPDYServerConnector.this); sslEndPoint.setConnection(connection); } @@ -200,6 +220,7 @@ public class SPDYServerConnector extends SelectChannelConnector public void protocolSelected(String protocol) { AsyncConnectionFactory connectionFactory = getAsyncConnectionFactory(protocol); + AsyncEndPoint sslEndPoint = sslEndPointRef.get(); AsyncConnection connection = connectionFactory.newAsyncConnection(channel, sslEndPoint, SPDYServerConnector.this); sslEndPoint.setConnection(connection); } diff --git a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLEngineLeakTest.java b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLEngineLeakTest.java new file mode 100644 index 00000000000..9605162a914 --- /dev/null +++ b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLEngineLeakTest.java @@ -0,0 +1,48 @@ +package org.eclipse.jetty.spdy; + +import java.lang.reflect.Field; +import java.util.Map; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.npn.NextProtoNego; +import org.eclipse.jetty.spdy.api.Session; +import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener; +import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.junit.Assert; +import org.junit.Test; + +public class SSLEngineLeakTest extends AbstractTest +{ + @Override + protected SPDYServerConnector newSPDYServerConnector(ServerSessionFrameListener listener) + { + SslContextFactory sslContextFactory = newSslContextFactory(); + return new SPDYServerConnector(listener, sslContextFactory); + } + + @Override + protected SPDYClient.Factory newSPDYClientFactory(Executor threadPool) + { + SslContextFactory sslContextFactory = newSslContextFactory(); + return new SPDYClient.Factory(threadPool, sslContextFactory); + } + + @Test + public void testSSLEngineLeak() throws Exception + { + avoidStackLocalVariables(); + Thread.sleep(1000); + System.gc(); + Field field = NextProtoNego.class.getDeclaredField("objects"); + field.setAccessible(true); + Map objects = (Map)field.get(null); + Assert.assertEquals(0, objects.size()); + } + + private void avoidStackLocalVariables() throws Exception + { + Session session = startClient(startServer(null), null); + session.goAway().get(5, TimeUnit.SECONDS); + } +} From 44017f18aff450c82545f7e2f2e10197600cf6c1 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 14 Mar 2012 17:49:57 +0100 Subject: [PATCH 016/100] 374258 - SPDY leaks SSLEngines. Made the test more reliable. --- .../eclipse/jetty/spdy/SSLEngineLeakTest.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLEngineLeakTest.java b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLEngineLeakTest.java index 9605162a914..cdb9a7ef6e2 100644 --- a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLEngineLeakTest.java +++ b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLEngineLeakTest.java @@ -31,13 +31,24 @@ public class SSLEngineLeakTest extends AbstractTest @Test public void testSSLEngineLeak() throws Exception { - avoidStackLocalVariables(); - Thread.sleep(1000); System.gc(); + Thread.sleep(1000); + Field field = NextProtoNego.class.getDeclaredField("objects"); field.setAccessible(true); Map objects = (Map)field.get(null); - Assert.assertEquals(0, objects.size()); + int initialSize = objects.size(); + + avoidStackLocalVariables(); + // Allow the close to arrive to the server and the selector to process it + Thread.sleep(1000); + + // Perform GC to be sure that the WeakHashMap is cleared + System.gc(); + Thread.sleep(1000); + + // Check that the WeakHashMap is empty + Assert.assertEquals(initialSize, objects.size()); } private void avoidStackLocalVariables() throws Exception From fef74963af5f84c4945c24c43247572f7b969717 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 14 Mar 2012 19:39:21 +0100 Subject: [PATCH 017/100] Forgotten modifications from Jetty7 --- .../continuation/ContinuationSupport.java | 21 +++++++++---------- .../continuation/Servlet3Continuation.java | 14 ++++++------- .../jetty/http/HttpGeneratorClientTest.java | 14 ++++++------- .../org/eclipse/jetty/io/ByteArrayBuffer.java | 3 ++- .../eclipse/jetty/io/ByteArrayEndPoint.java | 3 ++- .../eclipse/jetty/io/bio/StreamEndPoint.java | 3 ++- 6 files changed, 29 insertions(+), 29 deletions(-) diff --git a/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationSupport.java b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationSupport.java index 6a90a5ad3c9..4dd86193df9 100644 --- a/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationSupport.java +++ b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationSupport.java @@ -14,7 +14,6 @@ package org.eclipse.jetty.continuation; import java.lang.reflect.Constructor; - import javax.servlet.ServletRequest; import javax.servlet.ServletRequestWrapper; import javax.servlet.ServletResponse; @@ -36,7 +35,7 @@ public class ContinuationSupport static { boolean servlet3Support=false; - Constructors3cc=null; + Constructors3cc=null; try { boolean servlet3=ServletRequest.class.getMethod("startAsync")!=null; @@ -52,11 +51,11 @@ public class ContinuationSupport finally { __servlet3=servlet3Support; - __newServlet3Continuation=(Constructor)s3cc; + __newServlet3Continuation=s3cc; } - + boolean jetty6Support=false; - Constructorj6cc=null; + Constructorj6cc=null; try { Class jetty6ContinuationClass = ContinuationSupport.class.getClassLoader().loadClass("org.mortbay.util.ajax.Continuation"); @@ -73,9 +72,9 @@ public class ContinuationSupport finally { __jetty6=jetty6Support; - __newJetty6Continuation=(Constructor)j6cc; + __newJetty6Continuation=j6cc; } - + Class waiting=null; try { @@ -93,12 +92,12 @@ public class ContinuationSupport /* ------------------------------------------------------------ */ /** * Get a Continuation. The type of the Continuation returned may - * vary depending on the container in which the application is + * vary depending on the container in which the application is * deployed. It may be an implementation native to the container (eg * org.eclipse.jetty.server.AsyncContinuation) or one of the utility * implementations provided such as an internal FauxContinuation * or a real implementation like {@link org.eclipse.jetty.continuation.Servlet3Continuation}. - * @param request The request + * @param request The request * @return a Continuation instance */ public static Continuation getContinuation(ServletRequest request) @@ -106,10 +105,10 @@ public class ContinuationSupport Continuation continuation = (Continuation) request.getAttribute(Continuation.ATTRIBUTE); if (continuation!=null) return continuation; - + while (request instanceof ServletRequestWrapper) request=((ServletRequestWrapper)request).getRequest(); - + if (__servlet3 ) { try diff --git a/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Servlet3Continuation.java b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Servlet3Continuation.java index 9486b725ad8..26323372c49 100644 --- a/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Servlet3Continuation.java +++ b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Servlet3Continuation.java @@ -3,7 +3,6 @@ package org.eclipse.jetty.continuation; import java.io.IOException; import java.util.ArrayList; import java.util.List; - import javax.servlet.AsyncContext; import javax.servlet.AsyncEvent; import javax.servlet.AsyncListener; @@ -16,7 +15,7 @@ import javax.servlet.ServletResponseWrapper; /* ------------------------------------------------------------ */ /** * This implementation of Continuation is used by {@link ContinuationSupport} - * when it detects that the application has been deployed in a non-jetty Servlet 3 + * when it detects that the application has been deployed in a non-jetty Servlet 3 * server. */ public class Servlet3Continuation implements Continuation @@ -24,11 +23,11 @@ public class Servlet3Continuation implements Continuation // Exception reused for all continuations // Turn on debug in ContinuationFilter to see real stack trace. private final static ContinuationThrowable __exception = new ContinuationThrowable(); - + private final ServletRequest _request; private ServletResponse _response; private AsyncContext _context; - private List _listeners=new ArrayList(); + private List _listeners=new ArrayList(); private volatile boolean _initial=true; private volatile boolean _resumed=false; private volatile boolean _expired=false; @@ -59,7 +58,6 @@ public class Servlet3Continuation implements Continuation public void onTimeout(AsyncEvent event) throws IOException { _initial=false; - System.err.println("Doing dispatch on timed out continuation for "+_request.getAttribute("FOO")); event.getAsyncContext().dispatch(); } }); @@ -91,7 +89,7 @@ public class Servlet3Continuation implements Continuation listener.onTimeout(Servlet3Continuation.this); } }; - + if (_context!=null) _context.addListener(wrapped); else @@ -171,7 +169,7 @@ public class Servlet3Continuation implements Continuation _expired=false; _context=_request.startAsync(); _context.setTimeout(_timeoutMs); - + for (AsyncListener listener:_listeners) _context.addListener(listener); _listeners.clear(); @@ -184,7 +182,7 @@ public class Servlet3Continuation implements Continuation _expired=false; _context=_request.startAsync(); _context.setTimeout(_timeoutMs); - + for (AsyncListener listener:_listeners) _context.addListener(listener); _listeners.clear(); diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java index 46cfd4e2953..15c53bc9c08 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java @@ -13,9 +13,6 @@ package org.eclipse.jetty.http; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - import java.io.IOException; import java.util.concurrent.atomic.AtomicInteger; @@ -28,6 +25,9 @@ import org.eclipse.jetty.io.SimpleBuffers; import org.eclipse.jetty.io.View; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + public class HttpGeneratorClientTest { public final static String CONTENT="The quick brown fox jumped over the lazy dog.\nNow is the time for all good men to come to the aid of the party\nThe moon is blue to a fish in love.\n"; @@ -52,7 +52,7 @@ public class HttpGeneratorClientTest generator.completeHeader(fields,false); - generator.addContent(new ByteArrayBuffer(content),true); + generator.addContent(new ByteArrayBuffer(content).asMutableBuffer(),true); generator.flushBuffer(); generator.complete(); generator.flushBuffer(); @@ -77,7 +77,7 @@ public class HttpGeneratorClientTest String content = "The quick brown fox jumped over the lazy dog"; - generator.addContent(new ByteArrayBuffer(content),true); + generator.addContent(new ByteArrayBuffer(content).asMutableBuffer(),true); generator.completeHeader(fields,true); generator.flushBuffer(); @@ -106,7 +106,7 @@ public class HttpGeneratorClientTest generator.completeHeader(fields,false); - generator.addContent(new ByteArrayBuffer(content),false); + generator.addContent(new ByteArrayBuffer(content).asMutableBuffer(),false); generator.flushBuffer(); generator.complete(); generator.flushBuffer(); @@ -120,7 +120,7 @@ public class HttpGeneratorClientTest * screw up the chunking by leaving out the second chunk header. */ @Test - public void testChunkedWithBackPressure() throws Exception + public void testChunkedWithBackPressure() throws Exception { final AtomicInteger availableChannelBytes = new AtomicInteger(500); ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayBuffer.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayBuffer.java index f66a52c0018..933dbf98b28 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayBuffer.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayBuffer.java @@ -352,7 +352,8 @@ public class ByteArrayBuffer extends AbstractBuffer throws IOException { out.write(_bytes,getIndex(),length()); - clear(); + if (!isImmutable()) + clear(); } /* ------------------------------------------------------------ */ diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java index 029ed2f84ee..a0e4f8e96df 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java @@ -246,7 +246,8 @@ public class ByteArrayEndPoint implements ConnectedEndPoint } } int len = _out.put(buffer); - buffer.skip(len); + if (!buffer.isImmutable()) + buffer.skip(len); return len; } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StreamEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StreamEndPoint.java index a92e2e83700..0ebab0058d3 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StreamEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StreamEndPoint.java @@ -157,7 +157,8 @@ public class StreamEndPoint implements EndPoint int length=buffer.length(); if (length>0) buffer.writeTo(_out); - buffer.clear(); + if (!buffer.isImmutable()) + buffer.clear(); return length; } From 83ce567e66bc8ef1e1ea03187722b5511b2b2d58 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Thu, 15 Mar 2012 09:53:12 +1100 Subject: [PATCH 018/100] Add missing test from jetty-7 --- .../jetty/webapp/WebAppContextTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java index 52894e37a83..359da247524 100644 --- a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java +++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java @@ -87,6 +87,24 @@ public class WebAppContextTest assertTrue(Arrays.equals(configs,wac.getConfigurations())); } + @Test + public void testRealPathDoesNotExist() throws Exception + { + Server server = new Server(0); + WebAppContext context = new WebAppContext(".", "/"); + server.setHandler(context); + server.start(); + + // When + ServletContext ctx = context.getServletContext(); + + // Then + // This passes: + assertNotNull(ctx.getRealPath("/doesnotexist")); + // This fails: + assertNotNull(ctx.getRealPath("/doesnotexist/")); + } + /** * tests that the servlet context white list works * From 64e526dad4fb4456fd9e301edb2b41ff73b96f04 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Thu, 15 Mar 2012 10:47:16 +1100 Subject: [PATCH 019/100] Remove duplicate websocket entry in start.config --- .../src/main/resources/org/eclipse/jetty/start/start.config | 3 --- 1 file changed, 3 deletions(-) diff --git a/jetty-start/src/main/resources/org/eclipse/jetty/start/start.config b/jetty-start/src/main/resources/org/eclipse/jetty/start/start.config index ca2d0ae5eac..23bb426162f 100644 --- a/jetty-start/src/main/resources/org/eclipse/jetty/start/start.config +++ b/jetty-start/src/main/resources/org/eclipse/jetty/start/start.config @@ -142,9 +142,6 @@ $(jetty.home)/lib/jetty-policy-$(version).jar $(jetty.home)/lib/jetty-http-$(version).jar ! available org.eclipse.jetty.http.HttpParser $(jetty.home)/lib/jetty-client-$(version).jar ! available org.eclipse.jetty.client.HttpClient -[All,websocket] -$(jetty.home)/lib/jetty-websocket-$(version).jar ! available org.eclipse.jetty.websocket.WebSocket - [Client] $(jetty.home)/lib/jetty-http-$(version).jar ! available org.eclipse.jetty.http.HttpParser From f2400e5f78ddff3a1f943725506c803f8b18dfb5 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Thu, 15 Mar 2012 10:54:15 +1100 Subject: [PATCH 020/100] Harmonized jetty-8 with jetty-7 for Ajp13SocketConnector --- .../java/org/eclipse/jetty/ajp/Ajp13SocketConnector.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13SocketConnector.java b/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13SocketConnector.java index 3632b291844..37ff45fac6c 100644 --- a/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13SocketConnector.java +++ b/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13SocketConnector.java @@ -36,10 +36,10 @@ public class Ajp13SocketConnector extends SocketConnector static boolean __allowShutdown = false; public Ajp13SocketConnector() { - super.setRequestHeaderSize(Ajp13Packet.MAX_DATA_SIZE); - super.setResponseHeaderSize(Ajp13Packet.MAX_DATA_SIZE); - super.setRequestBufferSize(Ajp13Packet.MAX_DATA_SIZE); - super.setResponseBufferSize(Ajp13Packet.MAX_DATA_SIZE); + super.setRequestHeaderSize(Ajp13Packet.MAX_PACKET_SIZE); + super.setResponseHeaderSize(Ajp13Packet.MAX_PACKET_SIZE); + super.setRequestBufferSize(Ajp13Packet.MAX_PACKET_SIZE); + super.setResponseBufferSize(Ajp13Packet.MAX_PACKET_SIZE); // IN AJP protocol the socket stay open, so // by default the time out is set to 0 seconds super.setMaxIdleTime(0); From 13f0ae732d2bcfa67549401eb31ed6951e9fe39d Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Thu, 15 Mar 2012 12:12:22 +0100 Subject: [PATCH 021/100] Test fixes. --- .../jetty/server/LocalAsyncContextTest.java | 31 +++++++------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/LocalAsyncContextTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/LocalAsyncContextTest.java index e61cae38672..d44e1f5f7ea 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/LocalAsyncContextTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/LocalAsyncContextTest.java @@ -13,28 +13,19 @@ package org.eclipse.jetty.server; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - import java.io.IOException; -import java.io.InputStream; import java.util.concurrent.atomic.AtomicInteger; -import javax.servlet.AsyncContext; import javax.servlet.AsyncEvent; import javax.servlet.AsyncListener; -import javax.servlet.DispatcherType; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.continuation.Continuation; -import org.eclipse.jetty.continuation.ContinuationListener; -import org.eclipse.jetty.server.handler.HandlerWrapper; import org.eclipse.jetty.server.session.SessionHandler; import org.junit.After; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + public class LocalAsyncContextTest { protected Server _server = new Server(); @@ -53,7 +44,7 @@ public class LocalAsyncContextTest _server.setHandler(session); _server.start(); } - + protected Connector initConnector() { return new LocalConnector(); @@ -112,6 +103,7 @@ public class LocalAsyncContextTest _handler.setResumeAfter(100); _handler.setCompleteAfter(-1); + response=process("wibble"); check(response,"DISPATCHED"); _handler.setResumeAfter(-1); @@ -147,13 +139,14 @@ public class LocalAsyncContextTest check(response,"COMPLETED"); } + @Test public void testTwoCycles() throws Exception { String response; __completed.set(0); __completed1.set(0); - + _handler.setRead(0); _handler.setSuspendFor(1000); _handler.setResumeAfter(100); @@ -178,12 +171,12 @@ public class LocalAsyncContextTest assertTrue(i>=0); i+=m.length(); } - + } private synchronized String process(String content) throws Exception { - String request = "GET / HTTP/1.1\r\n" + + String request = "GET / HTTP/1.1\r\n" + "Host: localhost\r\n"+ "Connection: close\r\n"; @@ -194,7 +187,7 @@ public class LocalAsyncContextTest return getResponse(request); } - + protected String getResponse(String request) throws Exception { return ((LocalConnector)_connector).getResponses(request); @@ -204,7 +197,7 @@ public class LocalAsyncContextTest static AtomicInteger __completed = new AtomicInteger(); static AtomicInteger __completed1 = new AtomicInteger(); - + static AsyncListener __asyncListener = new AsyncListener() { @@ -235,7 +228,7 @@ public class LocalAsyncContextTest } }; - + static AsyncListener __asyncListener1 = new AsyncListener() { From 90ef835825cbb8f218170c2276f1ad7d39a20ec1 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Thu, 15 Mar 2012 15:01:24 +0100 Subject: [PATCH 022/100] Reverted changes to SuspendHandler to make tests pass again. --- .../jetty/server/LocalAsyncContextTest.java | 287 ++++++++++++++++- .../server/SelectChannelTimeoutTest.java | 6 +- .../eclipse/jetty/server/SuspendHandler.java | 304 ++++++------------ 3 files changed, 383 insertions(+), 214 deletions(-) diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/LocalAsyncContextTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/LocalAsyncContextTest.java index d44e1f5f7ea..170060a5c65 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/LocalAsyncContextTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/LocalAsyncContextTest.java @@ -14,10 +14,17 @@ package org.eclipse.jetty.server; import java.io.IOException; +import java.io.InputStream; import java.util.concurrent.atomic.AtomicInteger; +import javax.servlet.AsyncContext; import javax.servlet.AsyncEvent; import javax.servlet.AsyncListener; +import javax.servlet.DispatcherType; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.server.handler.HandlerWrapper; import org.eclipse.jetty.server.session.SessionHandler; import org.junit.After; import org.junit.Before; @@ -193,12 +200,288 @@ public class LocalAsyncContextTest return ((LocalConnector)_connector).getResponses(request); } + private static class SuspendHandler extends HandlerWrapper + { + private int _read; + private long _suspendFor=-1; + private long _resumeAfter=-1; + private long _completeAfter=-1; + private long _suspendFor2=-1; + private long _resumeAfter2=-1; + private long _completeAfter2=-1; + public SuspendHandler() + { + } + + public int getRead() + { + return _read; + } + + public void setRead(int read) + { + _read = read; + } + + public long getSuspendFor() + { + return _suspendFor; + } + + public void setSuspendFor(long suspendFor) + { + _suspendFor = suspendFor; + } + + public long getResumeAfter() + { + return _resumeAfter; + } + + public void setResumeAfter(long resumeAfter) + { + _resumeAfter = resumeAfter; + } + + public long getCompleteAfter() + { + return _completeAfter; + } + + public void setCompleteAfter(long completeAfter) + { + _completeAfter = completeAfter; + } + + + + /* ------------------------------------------------------------ */ + /** Get the suspendFor2. + * @return the suspendFor2 + */ + public long getSuspendFor2() + { + return _suspendFor2; + } + + + /* ------------------------------------------------------------ */ + /** Set the suspendFor2. + * @param suspendFor2 the suspendFor2 to set + */ + public void setSuspendFor2(long suspendFor2) + { + _suspendFor2 = suspendFor2; + } + + + /* ------------------------------------------------------------ */ + /** Get the resumeAfter2. + * @return the resumeAfter2 + */ + public long getResumeAfter2() + { + return _resumeAfter2; + } + + + /* ------------------------------------------------------------ */ + /** Set the resumeAfter2. + * @param resumeAfter2 the resumeAfter2 to set + */ + public void setResumeAfter2(long resumeAfter2) + { + _resumeAfter2 = resumeAfter2; + } + + + /* ------------------------------------------------------------ */ + /** Get the completeAfter2. + * @return the completeAfter2 + */ + public long getCompleteAfter2() + { + return _completeAfter2; + } + + + /* ------------------------------------------------------------ */ + /** Set the completeAfter2. + * @param completeAfter2 the completeAfter2 to set + */ + public void setCompleteAfter2(long completeAfter2) + { + _completeAfter2 = completeAfter2; + } + + + @Override + public void handle(String target, final Request baseRequest, final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException + { + try + { + if (DispatcherType.REQUEST.equals(baseRequest.getDispatcherType())) + { + if (_read>0) + { + byte[] buf=new byte[_read]; + request.getInputStream().read(buf); + } + else if (_read<0) + { + InputStream in = request.getInputStream(); + int b=in.read(); + while(b!=-1) + b=in.read(); + } + + + final AsyncContext asyncContext = baseRequest.startAsync(); + response.getOutputStream().println("STARTASYNC"); + asyncContext.addListener(__asyncListener); + asyncContext.addListener(__asyncListener1); + if (_suspendFor>0) + asyncContext.setTimeout(_suspendFor); + + + if (_completeAfter>0) + { + new Thread() { + @Override + public void run() + { + try + { + Thread.sleep(_completeAfter); + response.getOutputStream().println("COMPLETED"); + response.setStatus(200); + baseRequest.setHandled(true); + asyncContext.complete(); + } + catch(Exception e) + { + e.printStackTrace(); + } + } + }.start(); + } + else if (_completeAfter==0) + { + response.getOutputStream().println("COMPLETED"); + response.setStatus(200); + baseRequest.setHandled(true); + asyncContext.complete(); + } + + if (_resumeAfter>0) + { + new Thread() { + @Override + public void run() + { + try + { + Thread.sleep(_resumeAfter); + if(((HttpServletRequest)asyncContext.getRequest()).getSession(true).getId()!=null) + asyncContext.dispatch(); + } + catch(Exception e) + { + e.printStackTrace(); + } + } + }.start(); + } + else if (_resumeAfter==0) + { + asyncContext.dispatch(); + } + } + else + { + if (request.getAttribute("TIMEOUT")!=null) + response.getOutputStream().println("TIMEOUT"); + else + response.getOutputStream().println("DISPATCHED"); + + if (_suspendFor2>=0) + { + final AsyncContext asyncContext = baseRequest.startAsync(); + response.getOutputStream().println("STARTASYNC2"); + if (_suspendFor2>0) + asyncContext.setTimeout(_suspendFor2); + _suspendFor2=-1; + + if (_completeAfter2>0) + { + new Thread() { + @Override + public void run() + { + try + { + Thread.sleep(_completeAfter2); + response.getOutputStream().println("COMPLETED2"); + response.setStatus(200); + baseRequest.setHandled(true); + asyncContext.complete(); + } + catch(Exception e) + { + e.printStackTrace(); + } + } + }.start(); + } + else if (_completeAfter2==0) + { + response.getOutputStream().println("COMPLETED2"); + response.setStatus(200); + baseRequest.setHandled(true); + asyncContext.complete(); + } + + if (_resumeAfter2>0) + { + new Thread() { + @Override + public void run() + { + try + { + Thread.sleep(_resumeAfter2); + asyncContext.dispatch(); + } + catch(Exception e) + { + e.printStackTrace(); + } + } + }.start(); + } + else if (_resumeAfter2==0) + { + asyncContext.dispatch(); + } + } + else + { + response.setStatus(200); + baseRequest.setHandled(true); + } + } + } + finally + { + } + } + } static AtomicInteger __completed = new AtomicInteger(); static AtomicInteger __completed1 = new AtomicInteger(); - static AsyncListener __asyncListener = new AsyncListener() + private static AsyncListener __asyncListener = new AsyncListener() { @Override @@ -229,7 +512,7 @@ public class LocalAsyncContextTest }; - static AsyncListener __asyncListener1 = new AsyncListener() + private static AsyncListener __asyncListener1 = new AsyncListener() { @Override diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelTimeoutTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelTimeoutTest.java index f7a834f9619..c7c6cbaf5dc 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelTimeoutTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelTimeoutTest.java @@ -13,8 +13,6 @@ package org.eclipse.jetty.server; -import static org.junit.Assert.assertTrue; - import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; @@ -26,6 +24,8 @@ import org.eclipse.jetty.util.IO; import org.junit.BeforeClass; import org.junit.Test; +import static org.junit.Assert.assertTrue; + public class SelectChannelTimeoutTest extends ConnectorTimeoutTest { @@ -49,7 +49,7 @@ public class SelectChannelTimeoutTest extends ConnectorTimeoutTest _handler.setSuspendFor(100); _handler.setResumeAfter(25); - assertTrue(process(null).toUpperCase().contains("DISPATCHED")); + assertTrue(process(null).toUpperCase().contains("RESUMED")); } @Test diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/SuspendHandler.java b/jetty-server/src/test/java/org/eclipse/jetty/server/SuspendHandler.java index db4c297f932..4cde042e98c 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/SuspendHandler.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/SuspendHandler.java @@ -2,8 +2,9 @@ package org.eclipse.jetty.server; import java.io.IOException; import java.io.InputStream; - import javax.servlet.AsyncContext; +import javax.servlet.AsyncEvent; +import javax.servlet.AsyncListener; import javax.servlet.DispatcherType; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -11,15 +12,12 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.server.handler.HandlerWrapper; -class SuspendHandler extends HandlerWrapper +class SuspendHandler extends HandlerWrapper implements AsyncListener { private int _read; private long _suspendFor=-1; private long _resumeAfter=-1; private long _completeAfter=-1; - private long _suspendFor2=-1; - private long _resumeAfter2=-1; - private long _completeAfter2=-1; public SuspendHandler() { @@ -64,227 +62,115 @@ class SuspendHandler extends HandlerWrapper { _completeAfter = completeAfter; } - - - - /* ------------------------------------------------------------ */ - /** Get the suspendFor2. - * @return the suspendFor2 - */ - public long getSuspendFor2() - { - return _suspendFor2; - } - - - /* ------------------------------------------------------------ */ - /** Set the suspendFor2. - * @param suspendFor2 the suspendFor2 to set - */ - public void setSuspendFor2(long suspendFor2) - { - _suspendFor2 = suspendFor2; - } - - - /* ------------------------------------------------------------ */ - /** Get the resumeAfter2. - * @return the resumeAfter2 - */ - public long getResumeAfter2() - { - return _resumeAfter2; - } - - - /* ------------------------------------------------------------ */ - /** Set the resumeAfter2. - * @param resumeAfter2 the resumeAfter2 to set - */ - public void setResumeAfter2(long resumeAfter2) - { - _resumeAfter2 = resumeAfter2; - } - - - /* ------------------------------------------------------------ */ - /** Get the completeAfter2. - * @return the completeAfter2 - */ - public long getCompleteAfter2() - { - return _completeAfter2; - } - - - /* ------------------------------------------------------------ */ - /** Set the completeAfter2. - * @param completeAfter2 the completeAfter2 to set - */ - public void setCompleteAfter2(long completeAfter2) - { - _completeAfter2 = completeAfter2; - } - @Override public void handle(String target, final Request baseRequest, final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException { - try + if (DispatcherType.REQUEST.equals(baseRequest.getDispatcherType())) { - if (DispatcherType.REQUEST.equals(baseRequest.getDispatcherType())) + if (_read>0) { - if (_read>0) - { - byte[] buf=new byte[_read]; - request.getInputStream().read(buf); - } - else if (_read<0) - { - InputStream in = request.getInputStream(); - int b=in.read(); - while(b!=-1) - b=in.read(); - } - - - final AsyncContext asyncContext = baseRequest.startAsync(); - response.getOutputStream().println("STARTASYNC"); - asyncContext.addListener(LocalAsyncContextTest.__asyncListener); - asyncContext.addListener(LocalAsyncContextTest.__asyncListener1); - if (_suspendFor>0) - asyncContext.setTimeout(_suspendFor); - - - if (_completeAfter>0) - { - new Thread() { - @Override - public void run() - { - try - { - Thread.sleep(_completeAfter); - response.getOutputStream().println("COMPLETED"); - response.setStatus(200); - baseRequest.setHandled(true); - asyncContext.complete(); - } - catch(Exception e) - { - e.printStackTrace(); - } - } - }.start(); - } - else if (_completeAfter==0) - { - response.getOutputStream().println("COMPLETED"); - response.setStatus(200); - baseRequest.setHandled(true); - asyncContext.complete(); - } - - if (_resumeAfter>0) - { - new Thread() { - @Override - public void run() - { - try - { - Thread.sleep(_resumeAfter); - if(((HttpServletRequest)asyncContext.getRequest()).getSession(true).getId()!=null) - asyncContext.dispatch(); - } - catch(Exception e) - { - e.printStackTrace(); - } - } - }.start(); - } - else if (_resumeAfter==0) - { - asyncContext.dispatch(); - } + byte[] buf=new byte[_read]; + request.getInputStream().read(buf); } - else + else if (_read<0) { - if (request.getAttribute("TIMEOUT")!=null) - response.getOutputStream().println("TIMEOUT"); - else - response.getOutputStream().println("DISPATCHED"); + InputStream in = request.getInputStream(); + int b=in.read(); + while(b!=-1) + b=in.read(); + } - if (_suspendFor2>=0) - { - final AsyncContext asyncContext = baseRequest.startAsync(); - response.getOutputStream().println("STARTASYNC2"); - if (_suspendFor2>0) - asyncContext.setTimeout(_suspendFor2); - _suspendFor2=-1; + final AsyncContext asyncContext = baseRequest.startAsync(); + asyncContext.addListener(this); + if (_suspendFor>0) + asyncContext.setTimeout(_suspendFor); - if (_completeAfter2>0) + if (_completeAfter>0) + { + new Thread() { + @Override + public void run() { - new Thread() { - @Override - public void run() - { - try - { - Thread.sleep(_completeAfter2); - response.getOutputStream().println("COMPLETED2"); - response.setStatus(200); - baseRequest.setHandled(true); - asyncContext.complete(); - } - catch(Exception e) - { - e.printStackTrace(); - } - } - }.start(); - } - else if (_completeAfter2==0) - { - response.getOutputStream().println("COMPLETED2"); - response.setStatus(200); - baseRequest.setHandled(true); - asyncContext.complete(); + try + { + Thread.sleep(_completeAfter); + response.getOutputStream().println("COMPLETED"); + response.setStatus(200); + baseRequest.setHandled(true); + asyncContext.complete(); + } + catch(Exception e) + { + e.printStackTrace(); + } } + }.start(); + } + else if (_completeAfter==0) + { + response.getOutputStream().println("COMPLETED"); + response.setStatus(200); + baseRequest.setHandled(true); + asyncContext.complete(); + } - if (_resumeAfter2>0) + if (_resumeAfter>0) + { + new Thread() { + @Override + public void run() { - new Thread() { - @Override - public void run() - { - try - { - Thread.sleep(_resumeAfter2); - asyncContext.dispatch(); - } - catch(Exception e) - { - e.printStackTrace(); - } - } - }.start(); + try + { + Thread.sleep(_resumeAfter); + asyncContext.dispatch(); + } + catch(Exception e) + { + e.printStackTrace(); + } } - else if (_resumeAfter2==0) - { - asyncContext.dispatch(); - } - } - else - { - response.setStatus(200); - baseRequest.setHandled(true); - } + }.start(); + } + else if (_resumeAfter==0) + { + asyncContext.dispatch(); } } - finally + else if (request.getAttribute("TIMEOUT")!=null) { + response.setStatus(200); + response.getOutputStream().print("TIMEOUT"); + baseRequest.setHandled(true); + } + else + { + response.setStatus(200); + response.getOutputStream().print("RESUMED"); + baseRequest.setHandled(true); } } -} \ No newline at end of file + + @Override + public void onComplete(AsyncEvent asyncEvent) throws IOException + { + } + + @Override + public void onTimeout(AsyncEvent asyncEvent) throws IOException + { + asyncEvent.getSuppliedRequest().setAttribute("TIMEOUT",Boolean.TRUE); + asyncEvent.getAsyncContext().dispatch(); + } + + @Override + public void onError(AsyncEvent asyncEvent) throws IOException + { + } + + @Override + public void onStartAsync(AsyncEvent asyncEvent) throws IOException + { + } +} From 25213b83fa393a8295af15745f61bcc3eed847f7 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Fri, 16 Mar 2012 09:07:20 +1100 Subject: [PATCH 023/100] 374158: improved test harness --- .../jetty/server/HttpServerTestBase.java | 3 -- .../jetty/server/SelectChannelServerTest.java | 1 - .../ssl/SelectChannelServerSslTest.java | 34 ++++++++++++++++--- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java index ccc53ba9e30..6a872a86f3e 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java @@ -32,18 +32,15 @@ import javax.servlet.http.HttpServletResponse; import junit.framework.Assert; -import org.eclipse.jetty.http.HttpParser; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.StdErrLog; -import org.hamcrest.CoreMatchers; import org.hamcrest.Matchers; import org.junit.Test; import org.junit.matchers.JUnitMatchers; -import org.mockito.internal.matchers.Contains; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.junit.Assert.assertEquals; diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelServerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelServerTest.java index b8f2b2c55a7..030d90a6053 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelServerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelServerTest.java @@ -35,7 +35,6 @@ public class SelectChannelServerTest extends HttpServerTestBase @Override public void testSuspendedPipeline() throws Exception { - // TODO Auto-generated method stub super.testSuspendedPipeline(); } diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java index 2e6883a2968..4e05e3c563c 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java @@ -15,20 +15,29 @@ package org.eclipse.jetty.server.ssl; import static org.junit.Assert.assertEquals; import java.io.FileInputStream; +import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.security.KeyStore; import java.util.Arrays; +import java.util.concurrent.atomic.AtomicInteger; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; import javax.net.ssl.TrustManagerFactory; + +import org.eclipse.jetty.io.AsyncEndPoint; +import org.eclipse.jetty.io.Connection; +import org.eclipse.jetty.io.nio.SslConnection; import org.eclipse.jetty.server.HttpServerTestBase; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; +import static org.junit.Assert.assertThat; +import static org.hamcrest.Matchers.lessThan; /** * HttpServer Tester. @@ -46,11 +55,28 @@ public class SelectChannelServerSslTest extends HttpServerTestBase return __sslContext.getSocketFactory().createSocket(host,port); } + private static final AtomicInteger _handlecount = new AtomicInteger(); @BeforeClass public static void init() throws Exception { - SslSelectChannelConnector connector = new SslSelectChannelConnector(); + SslSelectChannelConnector connector = new SslSelectChannelConnector() + { + @Override + protected SslConnection newSslConnection(AsyncEndPoint endPoint, SSLEngine engine) + { + return new SslConnection(engine, endPoint) + { + @Override + public Connection handle() throws IOException + { + _handlecount.incrementAndGet(); + return super.handle(); + } + }; + } + }; + String keystorePath = System.getProperty("basedir",".") + "/src/test/resources/keystore"; SslContextFactory cf = connector.getSslContextFactory(); cf.setKeyStorePath(keystorePath); @@ -69,7 +95,6 @@ public class SelectChannelServerSslTest extends HttpServerTestBase __sslContext = SSLContext.getInstance("TLS"); __sslContext.init(null, trustManagerFactory.getTrustManagers(), null); - try { HttpsURLConnection.setDefaultHostnameVerifier(__hostnameverifier); @@ -105,7 +130,6 @@ public class SelectChannelServerSslTest extends HttpServerTestBase { OutputStream os=client.getOutputStream(); - int last=0; // Write out the fragments @@ -137,17 +161,17 @@ public class SelectChannelServerSslTest extends HttpServerTestBase } } - @Override @Ignore public void testAvailable() throws Exception { } - @Override public void testSuspendedPipeline() throws Exception { + _handlecount.set(0); super.testSuspendedPipeline(); + assertThat(_handlecount.get(),lessThan(50)); } } From a6eda905943566d863504b283d116c549a1dff11 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Fri, 16 Mar 2012 09:16:46 +1100 Subject: [PATCH 024/100] fixed merge issue --- .../main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java index fa8a02d505a..3a72cd2c1c9 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java @@ -397,12 +397,6 @@ public class ChannelEndPoint implements EndPoint } finally { - // adjust buffer 0 and 1 - if (!header.isImmutable()) - header.setGetIndex(bbuf0.position()); - if (!buffer.isImmutable()) - buffer.setGetIndex(bbuf1.position()); - bbuf0.position(0); bbuf1.position(0); bbuf0.limit(bbuf0.capacity()); From 7842e9c101a693b2c0d7da88f069ade46d2e0296 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Fri, 16 Mar 2012 10:05:38 +1100 Subject: [PATCH 025/100] 374450: use temp read only buffers instead of synchronisation --- .../eclipse/jetty/io/nio/ChannelEndPoint.java | 88 +++++++------------ 1 file changed, 32 insertions(+), 56 deletions(-) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java index 3a72cd2c1c9..828e38e3fcb 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java @@ -280,24 +280,17 @@ public class ChannelEndPoint implements EndPoint if (buf instanceof NIOBuffer) { final NIOBuffer nbuf = (NIOBuffer)buf; - final ByteBuffer bbuf=nbuf.getByteBuffer(); - - //noinspection SynchronizationOnLocalVariableOrMethodParameter - synchronized(bbuf) + final ByteBuffer bbuf=nbuf.getByteBuffer().asReadOnlyBuffer(); + try { - try - { - bbuf.position(buffer.getIndex()); - bbuf.limit(buffer.putIndex()); - len=_channel.write(bbuf); - } - finally - { - if (len>0) - buffer.skip(len); - bbuf.position(0); - bbuf.limit(bbuf.capacity()); - } + bbuf.position(buffer.getIndex()); + bbuf.limit(buffer.putIndex()); + len=_channel.write(bbuf); + } + finally + { + if (len>0) + buffer.skip(len); } } else if (buf instanceof RandomAccessFileBuffer) @@ -363,46 +356,29 @@ public class ChannelEndPoint implements EndPoint synchronized(this) { - // We must sync because buffers may be shared (eg nbuf1 is likely to be cached content). - //noinspection SynchronizationOnLocalVariableOrMethodParameter - synchronized(bbuf0) + // Adjust position indexs of buf0 and buf1 + bbuf0=bbuf0.asReadOnlyBuffer(); + bbuf0.position(header.getIndex()); + bbuf0.limit(header.putIndex()); + bbuf1=bbuf1.asReadOnlyBuffer(); + bbuf1.position(buffer.getIndex()); + bbuf1.limit(buffer.putIndex()); + + _gather2[0]=bbuf0; + _gather2[1]=bbuf1; + + // do the gathering write. + length=(int)((GatheringByteChannel)_channel).write(_gather2); + + int hl=header.length(); + if (length>hl) { - //noinspection SynchronizationOnLocalVariableOrMethodParameter - synchronized(bbuf1) - { - try - { - // Adjust position indexs of buf0 and buf1 - bbuf0.position(header.getIndex()); - bbuf0.limit(header.putIndex()); - bbuf1.position(buffer.getIndex()); - bbuf1.limit(buffer.putIndex()); - - _gather2[0]=bbuf0; - _gather2[1]=bbuf1; - - // do the gathering write. - length=(int)((GatheringByteChannel)_channel).write(_gather2); - - int hl=header.length(); - if (length>hl) - { - header.clear(); - buffer.skip(length-hl); - } - else if (length>0) - { - header.skip(length); - } - } - finally - { - bbuf0.position(0); - bbuf1.position(0); - bbuf0.limit(bbuf0.capacity()); - bbuf1.limit(bbuf1.capacity()); - } - } + header.clear(); + buffer.skip(length-hl); + } + else if (length>0) + { + header.skip(length); } } return length; From 4b2d976f249028b214c3d6497ebb01b945e96333 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Fri, 16 Mar 2012 15:48:02 +1100 Subject: [PATCH 026/100] JETTY-1495 Ensure dynamic servlet addition does not cause servlets to be inited. --- .../src/main/java/org/eclipse/jetty/servlet/ServletHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java index 297751d472f..39d51fe8f24 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java @@ -1224,7 +1224,7 @@ public class ServletHandler extends ScopedHandler try { - if (isStarted()) + if (_contextHandler!=null && _contextHandler.isStarted() || _contextHandler==null && isStarted()) initialize(); } catch (Exception e) From fc1e57a315fe5c2e4bf665b2c4763924483e4ece Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Fri, 16 Mar 2012 12:44:21 -0500 Subject: [PATCH 027/100] fix line in spnego readme --- jetty-security/src/main/config/etc/README.spnego | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/jetty-security/src/main/config/etc/README.spnego b/jetty-security/src/main/config/etc/README.spnego index 6bc2123290e..0b4cc5b7ab5 100644 --- a/jetty-security/src/main/config/etc/README.spnego +++ b/jetty-security/src/main/config/etc/README.spnego @@ -12,7 +12,7 @@ The easiest place to put these lines are in the start.ini file. For debugging the spengo authentication the following options are helpful: -Dorg.eclipse.jetty.LEVEL=debug --Dsun.security.spnego.debug=all +-Dsun.security.spnego.debug=true Spengo Authentication is enabled in the webapp with the following setup. @@ -59,7 +59,4 @@ embedded, via the jetty.xml or in a context file for the webapp. true - - - -8 \ No newline at end of file + \ No newline at end of file From b3ac9235f789bd16647b80af45825876d44aabaf Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Fri, 16 Mar 2012 12:46:47 -0500 Subject: [PATCH 028/100] add spdy to the distribution and make npn-boot test dependency pull from internal to build as opposed to out of a local repository --- jetty-distribution/pom.xml | 47 ++++++++++++++++++- jetty-spdy/pom.xml | 8 ++++ jetty-spdy/spdy-jetty-http-webapp/pom.xml | 27 +++++++++-- .../src/main/config/{ => etc}/jetty-spdy.xml | 0 jetty-spdy/spdy-jetty-http/pom.xml | 31 ++++++++++-- jetty-spdy/spdy-jetty/pom.xml | 26 +++++++++- 6 files changed, 128 insertions(+), 11 deletions(-) rename jetty-spdy/spdy-jetty-http-webapp/src/main/config/{ => etc}/jetty-spdy.xml (100%) diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml index a76dbaa55d6..8d3847060ee 100644 --- a/jetty-distribution/pom.xml +++ b/jetty-distribution/pom.xml @@ -103,6 +103,16 @@ ${assembly-directory}/webapps test.war + + org.eclipse.jetty.spdy + spdy-jetty-http-webapp + ${project.version} + war + true + ** + ${assembly-directory}/webapps + spdy.war + org.eclipse.jetty jetty-start @@ -124,12 +134,24 @@ org.eclipse.jetty - org.eclipse.jetty.orbit + org.eclipse.jetty.orbit,org.eclipse.jetty.spdy jetty-all,jetty-start,jetty-monitor,jetty-jsp jar ${assembly-directory}/lib + + copy-lib-spdy-deps + generate-resources + + copy-dependencies + + + org.eclipse.jetty.spdy + jar + ${assembly-directory}/lib/spdy + + copy-orbit-servlet-api-deps generate-resources @@ -222,7 +244,7 @@ unpack-dependencies - org.eclipse.jetty + org.eclipse.jetty,org.eclipse.jetty.spdy config false META-INF/** @@ -398,6 +420,27 @@ jetty-overlay-deployer ${project.version} + + org.eclipse.jetty.spdy + spdy-core + ${project.version} + + + org.eclipse.jetty.spdy + spdy-jetty + ${project.version} + + + org.eclipse.jetty.spdy + spdy-jetty-http + ${project.version} + + + org.eclipse.jetty.spdy + spdy-jetty-http-webapp + ${project.version} + war + org.eclipse.jetty.aggregate jetty-all diff --git a/jetty-spdy/pom.xml b/jetty-spdy/pom.xml index 081ff878d69..168a701ccf7 100644 --- a/jetty-spdy/pom.xml +++ b/jetty-spdy/pom.xml @@ -12,6 +12,14 @@ pom Jetty :: SPDY :: Parent + + + 7.6.2.v20120308 + + spdy-core spdy-jetty diff --git a/jetty-spdy/spdy-jetty-http-webapp/pom.xml b/jetty-spdy/spdy-jetty-http-webapp/pom.xml index 41188017aec..6c2c2c050f9 100644 --- a/jetty-spdy/spdy-jetty-http-webapp/pom.xml +++ b/jetty-spdy/spdy-jetty-http-webapp/pom.xml @@ -9,10 +9,27 @@ spdy-jetty-http-webapp war Jetty :: SPDY :: Jetty HTTP Web Application - + + + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + + config + + + + + + + \ No newline at end of file diff --git a/jetty-spdy/spdy-jetty-http-webapp/src/main/config/jetty-spdy.xml b/jetty-spdy/spdy-jetty-http-webapp/src/main/config/etc/jetty-spdy.xml similarity index 100% rename from jetty-spdy/spdy-jetty-http-webapp/src/main/config/jetty-spdy.xml rename to jetty-spdy/spdy-jetty-http-webapp/src/main/config/etc/jetty-spdy.xml diff --git a/jetty-spdy/spdy-jetty-http/pom.xml b/jetty-spdy/spdy-jetty-http/pom.xml index 9c35d0babcc..eb6ab126a5c 100644 --- a/jetty-spdy/spdy-jetty-http/pom.xml +++ b/jetty-spdy/spdy-jetty-http/pom.xml @@ -1,5 +1,6 @@ - + org.eclipse.jetty.spdy spdy-parent @@ -10,10 +11,34 @@ Jetty :: SPDY :: Jetty HTTP Layer + + maven-dependency-plugin + + + copy + generate-resources + + copy + + + + + org.mortbay.jetty.npn + npn-boot + ${npn.version} + jar + false + ${build.directory}/npn + + + + + + maven-surefire-plugin - -Xbootclasspath/p:${settings.localRepository}/org/mortbay/jetty/npn/npn-boot/${project.version}/npn-boot-${project.version}.jar + -Xbootclasspath/p:${build.directory}/npn/npn-boot-${npn.version}.jar @@ -26,7 +51,7 @@ maven-surefire-plugin - true + true diff --git a/jetty-spdy/spdy-jetty/pom.xml b/jetty-spdy/spdy-jetty/pom.xml index 6332c18e01e..c6f86c27769 100644 --- a/jetty-spdy/spdy-jetty/pom.xml +++ b/jetty-spdy/spdy-jetty/pom.xml @@ -10,10 +10,34 @@ Jetty :: SPDY :: Jetty Binding + + maven-dependency-plugin + + + copy + generate-resources + + copy + + + + + org.mortbay.jetty.npn + npn-boot + ${npn.version} + jar + false + ${build.directory}/npn + + + + + + maven-surefire-plugin - -Xbootclasspath/p:${settings.localRepository}/org/mortbay/jetty/npn/npn-boot/${project.version}/npn-boot-${project.version}.jar + -Xbootclasspath/p:${build.directory}/npn/npn-boot-${npn.version}.jar From ec2ccec76667fc21959830338779a493085bc407 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Fri, 16 Mar 2012 14:49:17 -0500 Subject: [PATCH 029/100] [Bug 373952] bind called too frequently on refresh --- .../nosql/mongodb/MongoSessionManager.java | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java index e4eab9e057f..5fb218df2d5 100644 --- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java +++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java @@ -245,21 +245,37 @@ public class MongoSessionManager extends NoSqlSessionManager { for (String name : attrs.keySet()) { - if ( __METADATA.equals(name) ) + if (__METADATA.equals(name)) { continue; } - + String attr = decodeName(name); Object value = decodeValue(attrs.get(name)); - session.doPutOrRemove(attr,value); - session.bindValue(attr,value); + + if (attrs.keySet().contains(name)) + { + session.doPutOrRemove(attr,value); + session.bindValue(attr,value); + } + else + { + session.doPutOrRemove(attr,value); + } + } + // cleanup, remove values from session, that don't exist in data anymore: + for (String name : session.getNames()) + { + if (!attrs.keySet().contains(name)) + { + session.doPutOrRemove(name,null); + session.unbindValue(name,session.getAttribute(name)); + } } } session.didActivate(); - - + return version; } catch (Exception e) From d717be14502554ceb31dadac9aab53973c619b08 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Fri, 16 Mar 2012 14:52:49 -0500 Subject: [PATCH 030/100] [Bug 374367] NPE in QueuedThreadPool.dump() with early java6 jvms --- .../eclipse/jetty/util/thread/QueuedThreadPool.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) 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 e3cccc09dd8..a6ae12096f1 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 @@ -465,12 +465,16 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo { final StackTraceElement[] trace=thread.getStackTrace(); boolean inIdleJobPoll=false; - for (StackTraceElement t : trace) + // trace can be null on early java 6 jvms + if (trace != null) { - if ("idleJobPoll".equals(t.getMethodName())) + for (StackTraceElement t : trace) { - inIdleJobPoll=true; - break; + if ("idleJobPoll".equals(t.getMethodName())) + { + inIdleJobPoll = true; + break; + } } } final boolean idle=inIdleJobPoll; From c7a4c80da513d5ff29b354ca202ebd87fe9c8b7d Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Fri, 16 Mar 2012 15:39:10 -0500 Subject: [PATCH 031/100] [Bug 373421] address potential race condition related to the nonce queue removing the same nonce twice --- .../jetty/security/authentication/DigestAuthenticator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java index 51833fad789..d762ebefbcf 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java @@ -254,7 +254,7 @@ public class DigestAuthenticator extends LoginAuthenticator Nonce nonce=_nonceQueue.peek(); while (nonce!=null && nonce._ts Date: Mon, 19 Mar 2012 11:11:48 +1100 Subject: [PATCH 032/100] protect dump from bad object toString()s --- .../jetty/util/component/AggregateLifeCycle.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java index f19407e0d23..917d9ddfc71 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java @@ -350,10 +350,17 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable /* ------------------------------------------------------------ */ public static void dumpObject(Appendable out,Object o) throws IOException { - if (o instanceof LifeCycle) - out.append(String.valueOf(o)).append(" - ").append((AbstractLifeCycle.getState((LifeCycle)o))).append("\n"); - else - out.append(String.valueOf(o)).append("\n"); + try + { + if (o instanceof LifeCycle) + out.append(String.valueOf(o)).append(" - ").append((AbstractLifeCycle.getState((LifeCycle)o))).append("\n"); + else + out.append(String.valueOf(o)).append("\n"); + } + catch(Throwable th) + { + out.append(" => ").append(th.toString()).append('\n'); + } } /* ------------------------------------------------------------ */ From 7e3b8bcfd4bcd96c199986720fa0aa0e6553b291 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Mon, 19 Mar 2012 15:48:39 +1100 Subject: [PATCH 033/100] 374611: do not redispatch if already dispatched when SSL reads content on write --- .../java/org/eclipse/jetty/client/SelectConnector.java | 5 +++++ .../main/java/org/eclipse/jetty/io/AsyncEndPoint.java | 9 ++++++++- .../org/eclipse/jetty/io/nio/SelectChannelEndPoint.java | 6 +----- .../java/org/eclipse/jetty/io/nio/SslConnection.java | 7 ++++++- .../java/org/eclipse/jetty/spdy/EmptyAsyncEndPoint.java | 5 +++++ 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java index e1c282e74db..baf31b1f902 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java @@ -276,6 +276,11 @@ class SelectConnector extends AggregateLifeCycle implements HttpClient.Connector _endp.shutdownOutput(); } + public void dispatch() + { + _endp.asyncDispatch(); + } + public void asyncDispatch() { _endp.asyncDispatch(); diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AsyncEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AsyncEndPoint.java index 992ad7a195a..5a58160ec35 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/AsyncEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AsyncEndPoint.java @@ -19,7 +19,14 @@ public interface AsyncEndPoint extends ConnectedEndPoint { /* ------------------------------------------------------------ */ /** - * Dispatch the endpoint to a thread to attend to it. + * Dispatch the endpoint if it is not already dispatched + * + */ + public void dispatch(); + + /* ------------------------------------------------------------ */ + /** + * Dispatch the endpoint. If it is already dispatched, schedule a redispatch * */ public void asyncDispatch(); diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java index b24ebd8d0d9..8db704b15d5 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java @@ -208,11 +208,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo { synchronized(this) { - if (_dispatched) - { - throw new IllegalStateException("dispatched"); - } - else + if (!_dispatched) { _dispatched = true; boolean dispatched = _manager.dispatch(_handler); diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java index 41fa232af1e..b4e9791b165 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java @@ -412,7 +412,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection // If we are reading into the temp buffer and it has some content, then we should be dispatched. if (toFill==_unwrapBuf && _unwrapBuf.hasContent() && !_connection.isSuspended()) - _aEndp.asyncDispatch(); + _aEndp.dispatch(); } finally { @@ -721,6 +721,11 @@ public class SslConnection extends AbstractConnection implements AsyncConnection process(null, null); } + public void dispatch() + { + _aEndp.dispatch(); + } + public void asyncDispatch() { _aEndp.asyncDispatch(); diff --git a/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/EmptyAsyncEndPoint.java b/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/EmptyAsyncEndPoint.java index 3d4d7f702de..c1fd5e2e251 100644 --- a/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/EmptyAsyncEndPoint.java +++ b/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/EmptyAsyncEndPoint.java @@ -32,6 +32,11 @@ public class EmptyAsyncEndPoint implements AsyncEndPoint private boolean closed; private int maxIdleTime; + @Override + public void dispatch() + { + } + @Override public void asyncDispatch() { From 422b41cfd15adfb0657a91809619a157427ee3f0 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Mon, 19 Mar 2012 08:23:54 -0500 Subject: [PATCH 034/100] fix a typo from bug 373952 --- .../org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java index 5fb218df2d5..085522f270a 100644 --- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java +++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java @@ -364,7 +364,7 @@ public class MongoSessionManager extends NoSqlSessionManager BasicDBObject remove = new BasicDBObject(); BasicDBObject unsets = new BasicDBObject(); unsets.put(getContextKey(),1); - remove.put("$unsets",unsets); + remove.put("$unset",unsets); _sessions.update(key,remove); return true; From 9d54ea4cde3fa30c60252e594d98fd26903c53e1 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Tue, 20 Mar 2012 18:35:21 +1100 Subject: [PATCH 035/100] JETTY-1500 form parameters from multipart request not available via request.getParameter --- .../org/eclipse/jetty/server/Request.java | 35 ++++++++++++- .../org/eclipse/jetty/server/RequestTest.java | 51 ++++++++++++++++++- .../jetty/util/MultiPartInputStream.java | 22 ++++++-- .../jetty/util/MultiPartInputStreamTest.java | 13 ++++- 4 files changed, 112 insertions(+), 9 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java index dd2476e0dd8..a194754dcf0 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java @@ -65,6 +65,7 @@ import org.eclipse.jetty.http.HttpVersions; import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.io.Buffer; import org.eclipse.jetty.io.BufferUtil; +import org.eclipse.jetty.io.ByteArrayBuffer; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.nio.DirectNIOBuffer; import org.eclipse.jetty.io.nio.IndirectNIOBuffer; @@ -1943,12 +1944,28 @@ public class Request implements HttpServletRequest { if (getContentType() == null || !getContentType().startsWith("multipart/form-data")) return null; - + if (_multiPartInputStream == null) { _multiPartInputStream = new MultiPartInputStream(getInputStream(), getContentType(),(MultipartConfigElement)getAttribute(__MULTIPART_CONFIG_ELEMENT), (_context != null?(File)_context.getAttribute("javax.servlet.context.tempdir"):null)); + Collection parts = _multiPartInputStream.getParts(); //causes parsing + for (Part p:parts) + { + MultiPartInputStream.MultiPart mp = (MultiPartInputStream.MultiPart)p; + if (mp.getContentDispositionFilename() == null && mp.getFile() == null) + { + //Servlet Spec 3.0 pg 23, parts without filenames must be put into init params + String charset = null; + if (mp.getContentType() != null) + charset = MimeTypes.getCharsetFromContentType(new ByteArrayBuffer(mp.getContentType())); + + String content=new String(mp.getBytes(),charset==null?StringUtil.__UTF8:charset); + getParameter(""); //cause params to be evaluated + getParameters().add(mp.getName(), content); + } + } } return _multiPartInputStream.getPart(name); } @@ -1964,6 +1981,22 @@ public class Request implements HttpServletRequest _multiPartInputStream = new MultiPartInputStream(getInputStream(), getContentType(),(MultipartConfigElement)getAttribute(__MULTIPART_CONFIG_ELEMENT), (_context != null?(File)_context.getAttribute("javax.servlet.context.tempdir"):null)); + Collection parts = _multiPartInputStream.getParts(); //causes parsing + for (Part p:parts) + { + MultiPartInputStream.MultiPart mp = (MultiPartInputStream.MultiPart)p; + if (mp.getContentDispositionFilename() == null && mp.getFile() == null) + { + //Servlet Spec 3.0 pg 23, parts without filenames must be put into init params + String charset = null; + if (mp.getContentType() != null) + charset = MimeTypes.getCharsetFromContentType(new ByteArrayBuffer(mp.getContentType())); + + String content=new String(mp.getBytes(),charset==null?StringUtil.__UTF8:charset); + getParameter(""); //cause params to be evaluated + getParameters().add(mp.getName(), content); + } + } } return _multiPartInputStream.getParts(); } diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java index 5496c028dce..89f74605563 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java @@ -18,6 +18,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertNotNull; import java.io.BufferedReader; import java.io.File; @@ -35,6 +36,7 @@ import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.Part; import junit.framework.Assert; @@ -122,6 +124,51 @@ public class RequestTest assertTrue(responses.startsWith("HTTP/1.1 200")); } + + @Test + public void testMultiPart() throws Exception + { + _handler._checker = new RequestTester() + { + public boolean check(HttpServletRequest request,HttpServletResponse response) + { + try + { + Part foo = request.getPart("stuff"); + assertNotNull(foo); + String value = request.getParameter("stuff"); + byte[] expected = "000000000000000000000000000000000000000000000000000".getBytes("ISO-8859-1"); + return value.equals(new String(expected, "ISO-8859-1")); + } + catch (Exception e) + { + e.printStackTrace(); + return false; + } + } + }; + + String multipart = "--AaB03x\r\n"+ + "content-disposition: form-data; name=\"field1\"\r\n"+ + "\r\n"+ + "Joe Blow\r\n"+ + "--AaB03x\r\n"+ + "content-disposition: form-data; name=\"stuff\"\r\n"+ + "Content-Type: text/plain;charset=ISO-8859-1\r\n"+ + "\r\n"+ + "000000000000000000000000000000000000000000000000000\r\n"+ + "--AaB03x--\r\n"; + + String request="GET / HTTP/1.1\r\n"+ + "Host: whatever\r\n"+ + "Content-Type: multipart/form-data; boundary=\"AaB03x\"\r\n"+ + "Content-Length: "+multipart.getBytes().length+"\r\n"+ + "\r\n"+ + multipart; + + String responses=_connector.getResponses(request); + assertTrue(responses.startsWith("HTTP/1.1 200")); + } @Test public void testBadUtf8ParamExtraction() throws Exception @@ -833,7 +880,9 @@ public class RequestTest { ((Request)request).setHandled(true); - if (request.getContentLength()>0 && !MimeTypes.FORM_ENCODED.equals(request.getContentType())) + if (request.getContentLength()>0 + && !MimeTypes.FORM_ENCODED.equals(request.getContentType()) + && !request.getContentType().startsWith("multipart/form-data")) _content=IO.toString(request.getInputStream()); if (_checker!=null && _checker.check(request,response)) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStream.java b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStream.java index a8b87de377b..00ceb5d5754 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStream.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStream.java @@ -64,6 +64,7 @@ public class MultiPartInputStream protected String _filename; protected File _file; protected OutputStream _out; + protected ByteArrayOutputStream2 _bout; protected String _contentType; protected MultiMap _headers; protected long _size = 0; @@ -95,7 +96,7 @@ public class MultiPartInputStream { //Write to a buffer in memory until we discover we've exceed the //MultipartConfig fileSizeThreshold - _out = new ByteArrayOutputStream(); + _out = _bout= new ByteArrayOutputStream2(); } } @@ -142,8 +143,9 @@ public class MultiPartInputStream { //already written some bytes, so need to copy them into the file _out.flush(); - ((ByteArrayOutputStream)_out).writeTo(bos); + _bout.writeTo(bos); _out.close(); + _bout = null; } _out = bos; } @@ -199,10 +201,17 @@ public class MultiPartInputStream else { //part content is in a ByteArrayOutputStream - return new ByteArrayInputStream(((ByteArrayOutputStream)_out).toByteArray()); + return new ByteArrayInputStream(_bout.getBuf(),0,_bout.size()); } } + public byte[] getBytes() + { + if (_bout!=null) + return _bout.toByteArray(); + return null; + } + /** * @see javax.servlet.http.Part#getName() */ @@ -232,19 +241,22 @@ public class MultiPartInputStream try { bos = new BufferedOutputStream(new FileOutputStream(_file)); - ((ByteArrayOutputStream)_out).writeTo(bos); + _bout.writeTo(bos); bos.flush(); } finally { if (bos != null) bos.close(); + _bout = null; } } else { //the part data is already written to a temporary file, just rename it - _file.renameTo(new File(_tmpDir, fileName)); + File f = new File(_tmpDir, fileName); + if (_file.renameTo(f)) + _file = f; } } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/MultiPartInputStreamTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/MultiPartInputStreamTest.java index c66a14eac11..826dbcb1bba 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/MultiPartInputStreamTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/MultiPartInputStreamTest.java @@ -131,11 +131,19 @@ public class MultiPartInputStreamTest extends TestCase IO.copy(is, os); assertEquals("Joe Blow", new String(os.toByteArray())); assertEquals(8, field1.getSize()); + + assertNotNull(((MultiPartInputStream.MultiPart)field1).getBytes()); //in internal buffer field1.write("field1.txt"); + assertNull(((MultiPartInputStream.MultiPart)field1).getBytes()); //no longer in internal buffer File f = new File (_dirname+File.separator+"field1.txt"); assertTrue(f.exists()); - field1.delete(); - assertFalse(f.exists()); + field1.write("another_field1.txt"); + File f2 = new File(_dirname+File.separator+"another_field1.txt"); + assertTrue(f2.exists()); + assertFalse(f.exists()); //should have been renamed + field1.delete(); //file should be deleted + assertFalse(f2.exists()); + Part stuff = mpis.getPart("stuff"); assertEquals("text/plain", stuff.getContentType()); @@ -146,6 +154,7 @@ public class MultiPartInputStreamTest extends TestCase assertEquals(51, stuff.getSize()); f = ((MultiPartInputStream.MultiPart)stuff).getFile(); assertNotNull(f); // longer than 100 bytes, should already be a file + assertNull(((MultiPartInputStream.MultiPart)stuff).getBytes()); //not in internal buffer any more assertTrue(f.exists()); assertNotSame("stuff.txt", f.getName()); stuff.write("stuff.txt"); From 2a67ebca955a380e6ad1a25795e9ccfbfd811688 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Tue, 20 Mar 2012 11:25:11 -0500 Subject: [PATCH 036/100] noop change to test commit and push speed --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 8edf9e2e289..ef80c180e0d 100644 --- a/pom.xml +++ b/pom.xml @@ -10,6 +10,7 @@ Jetty :: Project ${jetty.url} pom + UTF-8 http://www.eclipse.org/jetty From 48982ced4af5977790dcaa366926b99676f0a76b Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Wed, 21 Mar 2012 16:39:55 +1100 Subject: [PATCH 037/100] Fix up version number in manifests; reformat code; tidy xml and tweak --- .../jetty-osgi-boot-jsp/META-INF/MANIFEST.MF | 4 +- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../jetty-osgi-boot/META-INF/MANIFEST.MF | 38 +-- .../jettyhome/etc/jetty-osgi-default.xml | 26 +- .../etc/jetty-osgi-nested-default.xml | 14 +- .../webapp/WebBundleDeployerHelper.java | 323 +++++++++--------- .../META-INF/MANIFEST.MF | 18 +- .../META-INF/MANIFEST.MF | 12 +- 9 files changed, 213 insertions(+), 226 deletions(-) diff --git a/jetty-osgi/jetty-osgi-boot-jsp/META-INF/MANIFEST.MF b/jetty-osgi/jetty-osgi-boot-jsp/META-INF/MANIFEST.MF index 08335e141cb..3388173dcd0 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/META-INF/MANIFEST.MF +++ b/jetty-osgi/jetty-osgi-boot-jsp/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: Jetty-OSGi-Jasper integration Fragment-Host: org.eclipse.jetty.osgi.boot Bundle-SymbolicName: org.eclipse.jetty.osgi.boot.jsp -Bundle-Version: 8.1.2.qualifier +Bundle-Version: 8.1.3.qualifier Bundle-Vendor: Mort Bay Consulting Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Import-Package: com.sun.el;version="2.2.0";resolution:=optional, @@ -16,7 +16,7 @@ Import-Package: com.sun.el;version="2.2.0";resolution:=optional, javax.servlet.jsp.jstl.tlv;version="1.2.0";resolution:=optional, javax.servlet.jsp.resources;version="2.1.0", javax.servlet.jsp.tagext;version="2.1.0", - javax.servlet.resources;version="2.5.0", + javax.servlet.resources;version="2.6.0", org.apache.jasper;version="2.2.2";resolution:=optional, org.apache.jasper.compiler;version="2.2.2";resolution:=optional, org.apache.jasper.compiler.tagplugin;version="2.2.2";resolution:=optional, diff --git a/jetty-osgi/jetty-osgi-boot-logback/META-INF/MANIFEST.MF b/jetty-osgi/jetty-osgi-boot-logback/META-INF/MANIFEST.MF index 0400545f14d..39e193236cd 100644 --- a/jetty-osgi/jetty-osgi-boot-logback/META-INF/MANIFEST.MF +++ b/jetty-osgi/jetty-osgi-boot-logback/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: Jetty-OSGi-Logback integration Fragment-Host: org.eclipse.jetty.osgi.boot Bundle-SymbolicName: org.eclipse.jetty.osgi.boot.logback;singleton:=true -Bundle-Version: 8.1.2.qualifier +Bundle-Version: 8.1.3.qualifier Bundle-Vendor: Mort Bay Consulting Bundle-RequiredExecutionEnvironment: J2SE-1.5 Import-Package: ch.qos.logback.classic, diff --git a/jetty-osgi/jetty-osgi-boot-warurl/META-INF/MANIFEST.MF b/jetty-osgi/jetty-osgi-boot-warurl/META-INF/MANIFEST.MF index c8f2dcf1bd6..64712ef5f7e 100644 --- a/jetty-osgi/jetty-osgi-boot-warurl/META-INF/MANIFEST.MF +++ b/jetty-osgi/jetty-osgi-boot-warurl/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Support for rfc66 war url scheme Bundle-SymbolicName: org.eclipse.jetty.osgi.boot.warurl;singleton:=true -Bundle-Version: 8.1.2.qualifier +Bundle-Version: 8.1.3.qualifier Bundle-Activator: org.eclipse.jetty.osgi.boot.warurl.WarUrlActivator Bundle-Vendor: Mort Bay Consulting Bundle-RequiredExecutionEnvironment: JavaSE-1.6 diff --git a/jetty-osgi/jetty-osgi-boot/META-INF/MANIFEST.MF b/jetty-osgi/jetty-osgi-boot/META-INF/MANIFEST.MF index b5390842caf..4cf661c47f0 100644 --- a/jetty-osgi/jetty-osgi-boot/META-INF/MANIFEST.MF +++ b/jetty-osgi/jetty-osgi-boot/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: Jetty OSGi bootstrap Bundle-SymbolicName: org.eclipse.jetty.osgi.boot Bundle-Vendor: Mort Bay Consulting -Bundle-Version: 8.1.2.qualifier +Bundle-Version: 8.1.3.qualifier Bundle-Activator: org.eclipse.jetty.osgi.boot.JettyBootstrapActivator Import-Package: javax.mail;version="1.4.0";resolution:=optional, javax.mail.event;version="1.4.0";resolution:=optional, @@ -14,20 +14,20 @@ Import-Package: javax.mail;version="1.4.0";resolution:=optional, javax.servlet.http;version="2.6", javax.transaction;version="1.1.0";resolution:=optional, javax.transaction.xa;version="1.1.0";resolution:=optional, - org.eclipse.jetty.annotations;version="8.1.2";resolution:=optional, - org.eclipse.jetty.deploy;version="8.1.2", - org.eclipse.jetty.deploy.providers;version="8.1.2", - org.eclipse.jetty.http;version="8.1.2", - org.eclipse.jetty.nested;version="8.1.2";resolution:=optional, - org.eclipse.jetty.server;version="8.1.2", - org.eclipse.jetty.server.handler;version="8.1.2", - org.eclipse.jetty.servlet;version="8.1.2", - org.eclipse.jetty.util;version="8.1.2", - org.eclipse.jetty.util.component;version="8.1.2", - org.eclipse.jetty.util.log;version="8.1.2", - org.eclipse.jetty.util.resource;version="8.1.2", - org.eclipse.jetty.webapp;version="8.1.2", - org.eclipse.jetty.xml;version="8.1.2", + org.eclipse.jetty.annotations;version="8.1.3";resolution:=optional, + org.eclipse.jetty.deploy;version="8.1.3", + org.eclipse.jetty.deploy.providers;version="8.1.3", + org.eclipse.jetty.http;version="8.1.3", + org.eclipse.jetty.nested;version="8.1.3";resolution:=optional, + org.eclipse.jetty.server;version="8.1.3", + org.eclipse.jetty.server.handler;version="8.1.3", + org.eclipse.jetty.servlet;version="8.1.3", + org.eclipse.jetty.util;version="8.1.3", + org.eclipse.jetty.util.component;version="8.1.3", + org.eclipse.jetty.util.log;version="8.1.3", + org.eclipse.jetty.util.resource;version="8.1.3", + org.eclipse.jetty.webapp;version="8.1.3", + org.eclipse.jetty.xml;version="8.1.3", org.osgi.framework, org.osgi.service.cm;version="1.2.0", org.osgi.service.packageadmin, @@ -41,8 +41,8 @@ Import-Package: javax.mail;version="1.4.0";resolution:=optional, org.xml.sax.helpers Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-Classpath: . -Export-Package: org.eclipse.jetty.osgi.boot;version="8.1.2", - org.eclipse.jetty.osgi.nested;version="8.1.2", - org.eclipse.jetty.osgi.boot.utils;version="8.1.2", - org.eclipse.jetty.osgi.annotations;version="8.1.2" +Export-Package: org.eclipse.jetty.osgi.boot;version="8.1.3", + org.eclipse.jetty.osgi.nested;version="8.1.3", + org.eclipse.jetty.osgi.boot.utils;version="8.1.3", + org.eclipse.jetty.osgi.annotations;version="8.1.3" DynamicImport-Package: org.eclipse.jetty.*;version="[8.1,9)" diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-osgi-default.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-osgi-default.xml index 1202ae7023c..f8d1b680645 100644 --- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-osgi-default.xml +++ b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-osgi-default.xml @@ -21,6 +21,7 @@ 10 200 + false @@ -45,19 +46,6 @@ - - - - - - - - - - - - - @@ -82,10 +70,6 @@ - - - - @@ -95,7 +79,7 @@ org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern - .*/jsp-api-[^/]*\.jar$|.*/jsp-[^/]*\.jar$ + .*/servlet-api-[^/]*\.jar$ @@ -126,8 +110,12 @@ true true 1000 + false + false - + + + java.naming.factory.initial diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-osgi-nested-default.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-osgi-nested-default.xml index 67d84e9df8f..b5eeaf3ab06 100644 --- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-osgi-nested-default.xml +++ b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-osgi-nested-default.xml @@ -54,10 +54,6 @@ - - - - @@ -67,7 +63,7 @@ org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern - .*/jsp-api-[^/]*\.jar$|.*/jsp-[^/]*\.jar$ + .*/servlet-api-[^/]*\.jar$ @@ -82,7 +78,7 @@ contain custom tag libraries (*.tld files) if those bundles don't exist or can't be loaded no errors or warning will be issued! this default value is to plug the tld files of the reference implementation of JSF --> - @@ -99,8 +95,12 @@ true true 1000 + false + false - + + + java.naming.factory.initial diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java index 26d3c969d95..b5ead20d1f1 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java @@ -78,7 +78,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper private static Logger __logger = Log.getLogger(WebBundleDeployerHelper.class.getName()); private static boolean INITIALIZED = false; - + /** * By default set to: {@link DefaultBundleClassLoaderHelper}. It supports * equinox and apache-felix fragment bundles that are specific to an OSGi @@ -168,16 +168,16 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper * @throws Exception */ public WebAppContext registerWebapplication(Bundle bundle, - String webappFolderPath, String contextPath, String extraClasspath, - String overrideBundleInstallLocation, - String requireTldBundle, String webXmlPath, - String defaultWebXmlPath, WebAppContext webAppContext) throws Exception - { + String webappFolderPath, String contextPath, String extraClasspath, + String overrideBundleInstallLocation, + String requireTldBundle, String webXmlPath, + String defaultWebXmlPath, WebAppContext webAppContext) throws Exception + { File bundleInstall = overrideBundleInstallLocation == null?BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(bundle):new File( - overrideBundleInstallLocation); + overrideBundleInstallLocation); File webapp = null; URL baseWebappInstallURL = null; - + if (webappFolderPath != null && webappFolderPath.length() != 0 && !webappFolderPath.equals(".")) { if (webappFolderPath.startsWith("/") || webappFolderPath.startsWith("file:")) @@ -204,28 +204,28 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper if (baseWebappInstallURL == null && (webapp == null || !webapp.exists())) { throw new IllegalArgumentException("Unable to locate " + webappFolderPath + " inside " - + (bundleInstall != null?bundleInstall.getAbsolutePath():"unlocated bundle '" + bundle.getSymbolicName() + "'")); + + (bundleInstall != null?bundleInstall.getAbsolutePath():"unlocated bundle '" + bundle.getSymbolicName() + "'")); } if (baseWebappInstallURL == null && webapp != null) { baseWebappInstallURL = webapp.toURI().toURL(); } return registerWebapplication(bundle,webappFolderPath,baseWebappInstallURL,contextPath, - extraClasspath,bundleInstall,requireTldBundle,webXmlPath,defaultWebXmlPath,webAppContext); - } - + extraClasspath,bundleInstall,requireTldBundle,webXmlPath,defaultWebXmlPath,webAppContext); + } + /* (non-Javadoc) * @see org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper#registerWebapplication(org.osgi.framework.Bundle, java.lang.String, java.io.File, java.lang.String, java.lang.String, java.io.File, java.lang.String, java.lang.String) */ private WebAppContext registerWebapplication(Bundle contributor, String pathInBundleToWebApp, - URL baseWebappInstallURL, String contextPath, String extraClasspath, File bundleInstall, - String requireTldBundle, String webXmlPath, String defaultWebXmlPath, WebAppContext context) + URL baseWebappInstallURL, String contextPath, String extraClasspath, File bundleInstall, + String requireTldBundle, String webXmlPath, String defaultWebXmlPath, WebAppContext context) throws Exception { ClassLoader contextCl = Thread.currentThread().getContextClassLoader(); String[] oldServerClasses = null; - + try { // make sure we provide access to all the jetty bundles by going @@ -277,13 +277,13 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper context.setDefaultsDescriptor(defaultWebXml.getAbsolutePath()); } } - + //other parameters that might be defines on the OSGiAppProvider: context.setParentLoaderPriority(_wrapper.getOSGiAppProvider().isParentLoaderPriority()); configureWebappClassLoader(contributor,context,composite, requireTldBundle); configureWebAppContext(context,contributor,requireTldBundle); - + // @see // org.eclipse.jetty.webapp.JettyWebXmlConfiguration#configure(WebAppContext) @@ -292,36 +292,36 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper // through the webapp classloader. oldServerClasses = context.getServerClasses(); context.setServerClasses(null); - + _wrapper.getOSGiAppProvider().addContext(contributor,pathInBundleToWebApp,context); - + //support for patch resources. ideally this should be done inside a configurator. List patchResources = - (List)context.getAttribute(WebInfConfiguration.RESOURCE_URLS+".patch"); + (List)context.getAttribute(WebInfConfiguration.RESOURCE_URLS+".patch"); if (patchResources != null) { - LinkedList resourcesPath = new LinkedList(); - //place the patch resources at the beginning of the lookup path. - resourcesPath.addAll(patchResources); - //then place the ones from the host web bundle. - Resource hostResources = context.getBaseResource(); - if (hostResources instanceof ResourceCollection) - { - for (Resource re : ((ResourceCollection)hostResources).getResources()) - { - resourcesPath.add(re); - } - } - else - { - resourcesPath.add(hostResources); - } - - ResourceCollection rc = new ResourceCollection(resourcesPath.toArray( - new Resource[resourcesPath.size()])); - context.setBaseResource(rc); + LinkedList resourcesPath = new LinkedList(); + //place the patch resources at the beginning of the lookup path. + resourcesPath.addAll(patchResources); + //then place the ones from the host web bundle. + Resource hostResources = context.getBaseResource(); + if (hostResources instanceof ResourceCollection) + { + for (Resource re : ((ResourceCollection)hostResources).getResources()) + { + resourcesPath.add(re); + } + } + else + { + resourcesPath.add(hostResources); + } + + ResourceCollection rc = new ResourceCollection(resourcesPath.toArray( + new Resource[resourcesPath.size()])); + context.setBaseResource(rc); } - + return context; } finally @@ -347,8 +347,8 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper * @see org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper#registerContext(org.osgi.framework.Bundle, java.lang.String, java.lang.String, java.lang.String) */ public ContextHandler registerContext(Bundle contributor, String contextFileRelativePath, String extraClasspath, - String overrideBundleInstallLocation, String requireTldBundle, ContextHandler handler) - throws Exception + String overrideBundleInstallLocation, String requireTldBundle, ContextHandler handler) + throws Exception { File contextsHome = _wrapper.getOSGiAppProvider().getContextXmlDirAsFile(); if (contextsHome != null) @@ -357,12 +357,12 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper if (prodContextFile.exists()) { return registerContext(contributor,contextFileRelativePath,prodContextFile,extraClasspath, - overrideBundleInstallLocation,requireTldBundle,handler); + overrideBundleInstallLocation,requireTldBundle,handler); } } File rootFolder = overrideBundleInstallLocation != null - ? Resource.newResource(overrideBundleInstallLocation).getFile() - : BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(contributor); + ? Resource.newResource(overrideBundleInstallLocation).getFile() + : BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(contributor); File contextFile = rootFolder != null?new File(rootFolder,contextFileRelativePath):null; if (contextFile != null && contextFile.exists()) { @@ -378,7 +378,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper { contextFileRelativePath = "/" + contextFileRelativePath; } - + URL contextURL = contributor.getEntry(contextFileRelativePath); if (contextURL != null) { @@ -386,7 +386,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper return registerContext(contributor,contextFileRelativePath,r.getInputStream(),extraClasspath,overrideBundleInstallLocation,requireTldBundle,handler); } throw new IllegalArgumentException("Could not find the context " + "file " + contextFileRelativePath + " for the bundle " - + contributor.getSymbolicName() + (overrideBundleInstallLocation != null?" using the install location " + overrideBundleInstallLocation:"")); + + contributor.getSymbolicName() + (overrideBundleInstallLocation != null?" using the install location " + overrideBundleInstallLocation:"")); } } @@ -401,21 +401,21 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper * @throws Exception */ private ContextHandler registerContext(Bundle contributor, String pathInBundle, File contextFile, - String extraClasspath, String overrideBundleInstallLocation, - String requireTldBundle, ContextHandler handler) throws Exception - { + String extraClasspath, String overrideBundleInstallLocation, + String requireTldBundle, ContextHandler handler) throws Exception + { InputStream contextFileInputStream = null; try { contextFileInputStream = new BufferedInputStream(new FileInputStream(contextFile)); return registerContext(contributor, pathInBundle, contextFileInputStream, - extraClasspath,overrideBundleInstallLocation,requireTldBundle,handler); + extraClasspath,overrideBundleInstallLocation,requireTldBundle,handler); } finally { IO.close(contextFileInputStream); } - } + } /** * @param contributor @@ -425,10 +425,10 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper * @throws Exception */ private ContextHandler registerContext(Bundle contributor, - String pathInsideBundle, InputStream contextFileInputStream, - String extraClasspath, String overrideBundleInstallLocation, - String requireTldBundle, ContextHandler handler) - throws Exception + String pathInsideBundle, InputStream contextFileInputStream, + String extraClasspath, String overrideBundleInstallLocation, + String requireTldBundle, ContextHandler handler) + throws Exception { ClassLoader contextCl = Thread.currentThread().getContextClassLoader(); String[] oldServerClasses = null; @@ -443,8 +443,8 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper // that the contributor gives access to. Thread.currentThread().setContextClassLoader(composite); ContextHandler context = createContextHandler(handler, contributor, - contextFileInputStream,extraClasspath, - overrideBundleInstallLocation,requireTldBundle); + contextFileInputStream,extraClasspath, + overrideBundleInstallLocation,requireTldBundle); if (context == null) { return null;// did not happen @@ -454,7 +454,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper // that there // was at least one such handler for webapps. //the actual registration must happen via the new Deployment API. -// _ctxtHandler.addHandler(context); + // _ctxtHandler.addHandler(context); configureWebappClassLoader(contributor,context,composite, requireTldBundle); if (context instanceof WebAppContext) @@ -486,8 +486,8 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper * // configure it */ protected void configureWebAppContext(ContextHandler wah, Bundle contributor, - String requireTldBundle) throws IOException - { + String requireTldBundle) throws IOException + { // rfc66 wah.setAttribute(OSGiWebappConstants.RFC66_OSGI_BUNDLE_CONTEXT,contributor.getBundleContext()); @@ -496,12 +496,12 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper //org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext //then we need to do this to: wah.setAttribute("org.springframework.osgi.web." + BundleContext.class.getName(), - contributor.getBundleContext()); - + contributor.getBundleContext()); + //also pass the bundle directly. sometimes a bundle does not have a bundlecontext. //it is still useful to have access to the Bundle from the servlet context. wah.setAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE, contributor); - + //pass the value of the require tld bundle so that the TagLibOSGiConfiguration //can pick it up. wah.setAttribute(OSGiWebappConstants.REQUIRE_TLD_BUNDLE, requireTldBundle); @@ -513,7 +513,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper ((WebAppContext)wah).setConfigurationClasses(_wrapper.getOSGiAppProvider().getConfigurationClasses()); } } - + Bundle[] fragments = PackageAdminServiceTracker.INSTANCE.getFragmentsAndRequiredBundles(contributor); if (fragments != null && fragments.length != 0) { @@ -537,7 +537,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper if (fragUrl == null) { throw new IllegalArgumentException("Unable to locate " + fragFolder + " inside " - + " the fragment '" + frag.getSymbolicName() + "'"); + + " the fragment '" + frag.getSymbolicName() + "'"); } fragUrl = DefaultFileLocatorHelper.getLocalURL(fragUrl); String key = fragFolder.startsWith("/") ? fragFolder.substring(1) : fragFolder; @@ -549,7 +549,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper if (patchFragUrl == null) { throw new IllegalArgumentException("Unable to locate " + patchFragUrl + " inside " - + " the fragment '" + frag.getSymbolicName() + "'"); + + " the fragment '" + frag.getSymbolicName() + "'"); } patchFragUrl = DefaultFileLocatorHelper.getLocalURL(patchFragUrl); String key = patchFragFolder.startsWith("/") ? patchFragFolder.substring(1) : patchFragFolder; @@ -558,93 +558,93 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper } if (!appendedResourcesPath.isEmpty()) { - wah.setAttribute(WebInfConfiguration.RESOURCE_URLS, new ArrayList(appendedResourcesPath.values())); + wah.setAttribute(WebInfConfiguration.RESOURCE_URLS, new ArrayList(appendedResourcesPath.values())); } if (!patchResourcesPath.isEmpty()) { - wah.setAttribute(WebInfConfiguration.RESOURCE_URLS + ".patch", new ArrayList(patchResourcesPath.values())); + wah.setAttribute(WebInfConfiguration.RESOURCE_URLS + ".patch", new ArrayList(patchResourcesPath.values())); } - + if (wah instanceof WebAppContext) { - //This is the equivalent of what MetaInfConfiguration does. For OSGi bundles without the JarScanner - WebAppContext webappCtxt = (WebAppContext)wah; - //take care of the web-fragments, meta-inf resources and tld resources: - //similar to what MetaInfConfiguration does. - List frags = (List)wah.getAttribute(FragmentConfiguration.FRAGMENT_RESOURCES); - List resfrags = (List)wah.getAttribute(WebInfConfiguration.RESOURCE_URLS); - List tldfrags = (List)wah.getAttribute(TagLibConfiguration.TLD_RESOURCES); - for (Bundle frag : fragments) - { - URL webFrag = frag.getEntry("/META-INF/web-fragment.xml"); - Enumeration resEnum = frag.findEntries("/META-INF/resources", "*", true); - Enumeration tldEnum = frag.findEntries("/META-INF", "*.tld", false); - if (webFrag != null || (resEnum != null && resEnum.hasMoreElements()) - || (tldEnum != null && tldEnum.hasMoreElements())) - { - try - { - File fragFile = BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(frag); - //add it to the webinf jars collection: - //no need to check that it was not there yet: it was not there yet for sure. - Resource fragFileAsResource = Resource.newResource(fragFile.toURI()); - webappCtxt.getMetaData().addWebInfJar(fragFileAsResource); - - if (webFrag != null) - { - if (frags == null) - { - frags = new ArrayList(); - wah.setAttribute(FragmentConfiguration.FRAGMENT_RESOURCES, frags); - } - frags.add(fragFileAsResource); - } - if (resEnum != null && resEnum.hasMoreElements()) - { - URL resourcesEntry = frag.getEntry("/META-INF/resources/"); - if (resourcesEntry == null) - { - //probably we found some fragments to a bundle. - //those are already contributed. - //so we skip this. - } - else - { - if (resfrags == null) - { - resfrags = new ArrayList(); - wah.setAttribute(WebInfConfiguration.RESOURCE_URLS, resfrags); - } - resfrags.add(Resource.newResource( - DefaultFileLocatorHelper.getLocalURL(resourcesEntry))); - } - } - if (tldEnum != null && tldEnum.hasMoreElements()) - { - if (tldfrags == null) - { - tldfrags = new ArrayList(); - wah.setAttribute(TagLibConfiguration.TLD_RESOURCES, tldfrags); - } - while (tldEnum.hasMoreElements()) - { - URL tldUrl = tldEnum.nextElement(); - tldfrags.add(Resource.newResource( - DefaultFileLocatorHelper.getLocalURL(tldUrl))); - } - } - } - catch (Exception e) - { - __logger.warn("Unable to locate the bundle " + frag.getBundleId(),e); - } - } - } + //This is the equivalent of what MetaInfConfiguration does. For OSGi bundles without the JarScanner + WebAppContext webappCtxt = (WebAppContext)wah; + //take care of the web-fragments, meta-inf resources and tld resources: + //similar to what MetaInfConfiguration does. + List frags = (List)wah.getAttribute(FragmentConfiguration.FRAGMENT_RESOURCES); + List resfrags = (List)wah.getAttribute(WebInfConfiguration.RESOURCE_URLS); + List tldfrags = (List)wah.getAttribute(TagLibConfiguration.TLD_RESOURCES); + for (Bundle frag : fragments) + { + URL webFrag = frag.getEntry("/META-INF/web-fragment.xml"); + Enumeration resEnum = frag.findEntries("/META-INF/resources", "*", true); + Enumeration tldEnum = frag.findEntries("/META-INF", "*.tld", false); + if (webFrag != null || (resEnum != null && resEnum.hasMoreElements()) + || (tldEnum != null && tldEnum.hasMoreElements())) + { + try + { + File fragFile = BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(frag); + //add it to the webinf jars collection: + //no need to check that it was not there yet: it was not there yet for sure. + Resource fragFileAsResource = Resource.newResource(fragFile.toURI()); + webappCtxt.getMetaData().addWebInfJar(fragFileAsResource); + + if (webFrag != null) + { + if (frags == null) + { + frags = new ArrayList(); + wah.setAttribute(FragmentConfiguration.FRAGMENT_RESOURCES, frags); + } + frags.add(fragFileAsResource); + } + if (resEnum != null && resEnum.hasMoreElements()) + { + URL resourcesEntry = frag.getEntry("/META-INF/resources/"); + if (resourcesEntry == null) + { + //probably we found some fragments to a bundle. + //those are already contributed. + //so we skip this. + } + else + { + if (resfrags == null) + { + resfrags = new ArrayList(); + wah.setAttribute(WebInfConfiguration.RESOURCE_URLS, resfrags); + } + resfrags.add(Resource.newResource( + DefaultFileLocatorHelper.getLocalURL(resourcesEntry))); + } + } + if (tldEnum != null && tldEnum.hasMoreElements()) + { + if (tldfrags == null) + { + tldfrags = new ArrayList(); + wah.setAttribute(TagLibConfiguration.TLD_RESOURCES, tldfrags); + } + while (tldEnum.hasMoreElements()) + { + URL tldUrl = tldEnum.nextElement(); + tldfrags.add(Resource.newResource( + DefaultFileLocatorHelper.getLocalURL(tldUrl))); + } + } + } + catch (Exception e) + { + __logger.warn("Unable to locate the bundle " + frag.getBundleId(),e); + } + } + } } } - - - } + + + } /** * @See {@link ContextDeployer#scan} @@ -652,14 +652,14 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper * @return */ protected ContextHandler createContextHandler(ContextHandler handlerToConfigure, - Bundle bundle, File contextFile, String extraClasspath, - String overrideBundleInstallLocation, String requireTldBundle) + Bundle bundle, File contextFile, String extraClasspath, + String overrideBundleInstallLocation, String requireTldBundle) { try { return createContextHandler(handlerToConfigure,bundle, - new BufferedInputStream(new FileInputStream(contextFile)), - extraClasspath,overrideBundleInstallLocation,requireTldBundle); + new BufferedInputStream(new FileInputStream(contextFile)), + extraClasspath,overrideBundleInstallLocation,requireTldBundle); } catch (FileNotFoundException e) { @@ -675,8 +675,8 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper */ @SuppressWarnings("unchecked") protected ContextHandler createContextHandler(ContextHandler handlerToConfigure, - Bundle bundle, InputStream contextInputStream, String extraClasspath, - String overrideBundleInstallLocation, String requireTldBundle) + Bundle bundle, InputStream contextInputStream, String extraClasspath, + String overrideBundleInstallLocation, String requireTldBundle) { /* * Do something identical to what the ContextProvider would have done: @@ -694,7 +694,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper XmlConfiguration xmlConfiguration = new XmlConfiguration(contextInputStream); HashMap properties = new HashMap(); properties.put("Server",_wrapper.getServer()); - + // insert the bundle's location as a property. setThisBundleHomeProperty(bundle,properties,overrideBundleInstallLocation); xmlConfiguration.getProperties().putAll(properties); @@ -709,7 +709,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper xmlConfiguration.configure(handlerToConfigure); context = handlerToConfigure; } - + if (context instanceof WebAppContext) { ((WebAppContext)context).setExtraClasspath(extraClasspath); @@ -805,7 +805,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper // if this is a real webapp we will set it on it a bit later: once we // know. OSGiWebappClassLoader webappClassLoader = new OSGiWebappClassLoader( - _wrapper.getParentClassLoaderForWebapps(),new WebAppContext(),contributor,BUNDLE_CLASS_LOADER_HELPER); + _wrapper.getParentClassLoaderForWebapps(),new WebAppContext(),contributor,BUNDLE_CLASS_LOADER_HELPER); /* DEBUG try { Class c = webappClassLoader.loadClass("org.glassfish.jsp.api.ResourceInjector"); @@ -817,7 +817,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper System.err.println("LOADED org.apache.jasper.xmlparser.ParserUtils from "+c.getClassLoader()); } catch (Exception e) {e.printStackTrace();} - */ + */ return webappClassLoader; } @@ -831,7 +831,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper try { File location = overrideBundleInstallLocation != null?new File(overrideBundleInstallLocation):BUNDLE_FILE_LOCATOR_HELPER - .getBundleInstallLocation(bundle); + .getBundleInstallLocation(bundle); properties.put("this.bundle.install",location.getCanonicalPath()); properties.put("this.bundle.install.url",bundle.getEntry("/").toString()); } @@ -841,7 +841,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper } } - + private String getPathsToRequiredBundles (ContextHandler context, String requireTldBundle) throws Exception { if (requireTldBundle == null) @@ -851,7 +851,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper Bundle bundle = (Bundle)context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE); PackageAdmin packAdmin = getBundleAdmin(); DefaultFileLocatorHelper fileLocatorHelper = new DefaultFileLocatorHelper(); - + String[] symbNames = requireTldBundle.split(", "); for (String symbName : symbNames) @@ -866,11 +866,10 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper + bundle.getSymbolicName()); } - + File f = fileLocatorHelper.getBundleInstallLocation(bs[0]); if (paths.length() > 0) paths.append(", "); - System.err.println("getPathsToRequiredBundles: bundle path="+bs[0].getLocation()+" uri="+f.toURI()); paths.append(f.toURI().toURL().toString()); } diff --git a/jetty-osgi/jetty-osgi-equinoxtools/META-INF/MANIFEST.MF b/jetty-osgi/jetty-osgi-equinoxtools/META-INF/MANIFEST.MF index d3f9bfb5433..ec9ca0d2b7f 100644 --- a/jetty-osgi/jetty-osgi-equinoxtools/META-INF/MANIFEST.MF +++ b/jetty-osgi/jetty-osgi-equinoxtools/META-INF/MANIFEST.MF @@ -3,20 +3,20 @@ Bundle-ManifestVersion: 2 Bundle-Name: Console Bundle-SymbolicName: org.eclipse.jetty.osgi.equinoxtools Bundle-Description: Example application: equinox console accesssible on the web -Bundle-Version: 8.1.2.qualifier +Bundle-Version: 8.1.3.qualifier Bundle-Activator: org.eclipse.jetty.osgi.equinoxtools.WebEquinoxToolsActivator Import-Package: javax.servlet;version="2.5.0", javax.servlet.http;version="2.5.0", - org.eclipse.jetty.continuation;version="8.1.2", - org.eclipse.jetty.io;version="8.1.2", - org.eclipse.jetty.util;version="8.1.2", - org.eclipse.jetty.util.log;version="8.1.2", - org.eclipse.jetty.websocket;version="8.1.2", + org.eclipse.jetty.continuation;version="8.1.3", + org.eclipse.jetty.io;version="8.1.3", + org.eclipse.jetty.util;version="8.1.3", + org.eclipse.jetty.util.log;version="8.1.3", + org.eclipse.jetty.websocket;version="8.1.3", org.eclipse.osgi.framework.console;version="1.1.0", org.osgi.framework;version="1.3.0", org.osgi.service.http;version="1.2.0", org.osgi.util.tracker;version="1.3.0" -Export-Package: org.eclipse.jetty.osgi.equinoxtools;x-internal:=true;version="8.1.2", - org.eclipse.jetty.osgi.equinoxtools.console;x-internal:=true;version="8.1.2" -Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Export-Package: org.eclipse.jetty.osgi.equinoxtools;x-internal:=true;version="8.1.3", + org.eclipse.jetty.osgi.equinoxtools.console;x-internal:=true;version="8.1.3" +Bundle-RequiredExecutionEnvironment: J2SE-1.6 diff --git a/jetty-osgi/jetty-osgi-httpservice/META-INF/MANIFEST.MF b/jetty-osgi/jetty-osgi-httpservice/META-INF/MANIFEST.MF index a1efdb9faca..66d4fbc7ce7 100644 --- a/jetty-osgi/jetty-osgi-httpservice/META-INF/MANIFEST.MF +++ b/jetty-osgi/jetty-osgi-httpservice/META-INF/MANIFEST.MF @@ -2,15 +2,15 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: OSGi HttpService provided by equinox HttpServiceServlet deployed on jetty Bundle-SymbolicName: org.eclipse.jetty.osgi.httpservice -Bundle-Version: 8.1.2.qualifier +Bundle-Version: 8.1.3.qualifier Bundle-Vendor: Mort Bay Consulting Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Jetty-ContextFilePath: contexts/httpservice.xml Import-Package: javax.servlet;version="2.6.0", javax.servlet.http;version="2.6.0", org.eclipse.equinox.http.servlet, - org.eclipse.jetty.server;version="8.1.2", - org.eclipse.jetty.server.handler;version="8.1.2", - org.eclipse.jetty.servlet;version="8.1.2", - org.eclipse.jetty.util.component;version="8.1.2" -Export-Package: org.eclipse.jetty.osgi.httpservice;version="8.1.2" + org.eclipse.jetty.server;version="8.1.3", + org.eclipse.jetty.server.handler;version="8.1.3", + org.eclipse.jetty.servlet;version="8.1.3", + org.eclipse.jetty.util.component;version="8.1.3" +Export-Package: org.eclipse.jetty.osgi.httpservice;version="8.1.3" From c81dbb86940bab2ce36a4538e9dda17efea49990 Mon Sep 17 00:00:00 2001 From: pgdad Date: Wed, 21 Mar 2012 08:44:02 -0400 Subject: [PATCH 038/100] 374891 - enhancement to how ProxyServlet determines the proxy target --- .../main/java/org/eclipse/jetty/servlets/ProxyServlet.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java index 445a1bf9150..afae2ab946e 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java @@ -414,7 +414,7 @@ public class ProxyServlet implements Servlet if (request.getQueryString() != null) uri += "?" + request.getQueryString(); - HttpURI url = proxyHttpURI(request.getScheme(),request.getServerName(),request.getServerPort(),uri); + HttpURI url = proxyHttpURI(request,uri); if (debug != 0) _log.debug(debug + " proxy " + uri + "-->" + url); @@ -677,6 +677,11 @@ public class ProxyServlet implements Servlet } /* ------------------------------------------------------------ */ + protected HttpURI proxyHttpURI(HttpServletRequest request, String uri) throws MalformedURLException + { + return proxyHttpURI(request.getScheme(), request.getServerName(), request.getServerPort(), uri); + } + protected HttpURI proxyHttpURI(String scheme, String serverName, int serverPort, String uri) throws MalformedURLException { if (!validateDestination(serverName,uri)) From 0f9a898c1c563ede10a5c2cf05bcb27ec3795658 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Thu, 22 Mar 2012 09:59:57 +1100 Subject: [PATCH 039/100] 349110 MultiPartFilter records the content-type in request params --- .../eclipse/jetty/servlets/MultiPartFilter.java | 6 ++++++ .../jetty/servlets/MultipartFilterTest.java | 17 ++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java index d58811f9a26..70dcc7b8109 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java @@ -159,7 +159,11 @@ public class MultiPartFilter implements Filter { request.setAttribute(mp.getName(),mp.getFile()); if (mp.getContentDispositionFilename() != null) + { params.add(mp.getName(), mp.getContentDispositionFilename()); + if (mp.getContentType() != null) + params.add(mp.getName()+CONTENT_TYPE_SUFFIX, mp.getContentType()); + } if (_deleteFiles) { mp.getFile().deleteOnExit(); @@ -178,6 +182,8 @@ public class MultiPartFilter implements Filter ByteArrayOutputStream bytes = new ByteArrayOutputStream(); IO.copy(p.getInputStream(), bytes); params.add(p.getName(), bytes.toByteArray()); + if (p.getContentType() != null) + params.add(p.getName()+CONTENT_TYPE_SUFFIX, p.getContentType()); } } } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java index 97d948a97dd..fad0306325e 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java @@ -47,7 +47,19 @@ public class MultipartFilterTest private ServletTester tester; - + public static class TestServlet extends DumpServlet + { + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + assertNotNull(req.getParameter("fileup")); + assertNotNull(req.getParameter("fileup"+MultiPartFilter.CONTENT_TYPE_SUFFIX)); + assertEquals(req.getParameter("fileup"+MultiPartFilter.CONTENT_TYPE_SUFFIX), "application/octet-stream"); + super.doPost(req, resp); + } + + } @@ -63,7 +75,7 @@ public class MultipartFilterTest tester=new ServletTester(); tester.setContextPath("/context"); tester.setResourceBase(_dir.getCanonicalPath()); - tester.addServlet(DumpServlet.class, "/"); + tester.addServlet(TestServlet.class, "/"); tester.setAttribute("javax.servlet.context.tempdir", _dir); FilterHolder multipartFilter = tester.addFilter(MultiPartFilter.class,"/*", EnumSet.of(DispatcherType.REQUEST)); multipartFilter.setInitParameter("deleteFiles", "true"); @@ -253,7 +265,6 @@ public class MultipartFilterTest protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { assertEquals("How now brown cow.", req.getParameterMap().get("strupContent-Type:")); - super.doPost(req, resp); } From 6a2c5fc9fde44ba966da3dd494ecfdba6954f3e6 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Thu, 22 Mar 2012 13:50:36 +1100 Subject: [PATCH 040/100] 375009 Filter initialization error will throw MultiException --- jetty-server/src/main/java/org/eclipse/jetty/server/Server.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java index 8f154b693dc..9a01f509562 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java @@ -265,7 +265,7 @@ public class Server extends HandlerWrapper implements Attributes mex.add(e); } - if (_connectors!=null) + if (_connectors!=null && mex.size()==0) { for (int i=0;i<_connectors.length;i++) { From 875bcb5bb838ae843266894dc46f5598558d0612 Mon Sep 17 00:00:00 2001 From: Thomas Becker Date: Thu, 22 Mar 2012 12:40:16 +0100 Subject: [PATCH 041/100] 374995: configure jmx rmi port via SystemProperty Change-Id: I35f336d4754c79717b741aea0896bd71b46ed28d 374995: configure jmx rmi host via SystemProperty,change objectname and jmxpath from jettyjmx to jmxrmi Change-Id: Ib469d631682c9fb31aea584c38906aae0958198f 374995: configure jmx rmi host via SystemProperty,change objectname and jmxpath from jettyjmx to jmxrmi Change-Id: I02c88c518810e03c7ae59453fa6752d80108960e --- jetty-jmx/src/main/config/etc/jetty-jmx.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jetty-jmx/src/main/config/etc/jetty-jmx.xml b/jetty-jmx/src/main/config/etc/jetty-jmx.xml index a685eded058..4db0dbb473a 100644 --- a/jetty-jmx/src/main/config/etc/jetty-jmx.xml +++ b/jetty-jmx/src/main/config/etc/jetty-jmx.xml @@ -69,7 +69,7 @@ --> From bb66cfc8774800b41d0d0616a1e33ca159116191 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Thu, 22 Mar 2012 17:08:11 +0100 Subject: [PATCH 042/100] 375083 - Flow control should take in account window size changes from concurrent SETTINGS --- .../java/org/eclipse/jetty/spdy/ISession.java | 2 - .../eclipse/jetty/spdy/StandardSession.java | 16 ++--- .../org/eclipse/jetty/spdy/api/Session.java | 4 +- .../eclipse/jetty/spdy/FlowControlTest.java | 65 +++++++++++++++++++ 4 files changed, 74 insertions(+), 13 deletions(-) diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/ISession.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/ISession.java index 10e64130726..c69af218385 100644 --- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/ISession.java +++ b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/ISession.java @@ -35,6 +35,4 @@ public interface ISession extends Session public void control(IStream stream, ControlFrame frame, long timeout, TimeUnit unit, Handler handler, C context); public void data(IStream stream, DataInfo dataInfo, long timeout, TimeUnit unit, Handler handler, C context); - - public int getWindowSize(); } 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 314695336ac..f8fc892b1cb 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 @@ -18,10 +18,11 @@ package org.eclipse.jetty.spdy; import java.nio.ByteBuffer; import java.nio.channels.InterruptedByTimeoutException; -import java.util.ArrayList; import java.util.Deque; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CopyOnWriteArrayList; @@ -253,9 +254,9 @@ public class StandardSession implements ISession, Parser.Listener, Handler getStreams() + public Set getStreams() { - List result = new ArrayList<>(); + Set result = new HashSet<>(); result.addAll(streams.values()); return result; } @@ -540,7 +541,10 @@ public class StandardSession implements ISession, Parser.Listener, Handler getStreams(); + public Set getStreams(); /** *

Super interface for listeners with callbacks that are invoked on specific session events.

diff --git a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/FlowControlTest.java b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/FlowControlTest.java index 1ee5f8a96c0..526c9a8d81b 100644 --- a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/FlowControlTest.java +++ b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/FlowControlTest.java @@ -23,6 +23,7 @@ import java.util.concurrent.Exchanger; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jetty.spdy.api.BytesDataInfo; import org.eclipse.jetty.spdy.api.DataInfo; @@ -41,6 +42,70 @@ import org.junit.Test; public class FlowControlTest extends AbstractTest { + @Test + public void testFlowControlWithConcurrentSettings() throws Exception + { + // Initial window is 64 KiB. We allow the client to send 1024 B + // then we change the window to 512 B. At this point, the client + // must stop sending data (although the initial window allows it) + + final int size = 512; + final AtomicReference dataInfoRef = new AtomicReference<>(); + final CountDownLatch dataLatch = new CountDownLatch(2); + final CountDownLatch settingsLatch = new CountDownLatch(1); + Session session = startClient(startServer(new ServerSessionFrameListener.Adapter() + { + @Override + public StreamFrameListener onSyn(Stream stream, SynInfo synInfo) + { + stream.reply(new ReplyInfo(true)); + return new StreamFrameListener.Adapter() + { + private final AtomicInteger dataFrames = new AtomicInteger(); + + @Override + public void onData(Stream stream, DataInfo dataInfo) + { + int dataFrameCount = dataFrames.incrementAndGet(); + if (dataFrameCount == 1) + { + dataInfoRef.set(dataInfo); + Settings settings = new Settings(); + settings.put(new Settings.Setting(Settings.ID.INITIAL_WINDOW_SIZE, size)); + stream.getSession().settings(new SettingsInfo(settings)); + } + else if (dataFrameCount > 1) + { + dataInfo.consume(dataInfo.length()); + dataLatch.countDown(); + } + } + }; + } + }), new SessionFrameListener.Adapter() + { + @Override + public void onSettings(Session session, SettingsInfo settingsInfo) + { + settingsLatch.countDown(); + } + }); + + Stream stream = session.syn(new SynInfo(false), null).get(5, TimeUnit.SECONDS); + stream.data(new BytesDataInfo(new byte[size * 2], false)); + settingsLatch.await(5, TimeUnit.SECONDS); + + // Send the second chunk of data, must not arrive since we're flow control stalled now + stream.data(new BytesDataInfo(new byte[size * 2], true)); + Assert.assertFalse(dataLatch.await(1, TimeUnit.SECONDS)); + + // Consume the data arrived to server, this will resume flow control + DataInfo dataInfo = dataInfoRef.get(); + dataInfo.consume(dataInfo.length()); + + Assert.assertTrue(dataLatch.await(5, TimeUnit.SECONDS)); + } + @Test public void testServerFlowControlOneBigWrite() throws Exception { From 65725b00257a0724a06c6d0534c422bb4f9adf5c Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Fri, 23 Mar 2012 09:21:00 +1100 Subject: [PATCH 043/100] 357318: make the cancel key work around conditional on running on windows --- .../jetty/io/nio/SelectChannelEndPoint.java | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java index 8db704b15d5..ca182eadde6 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java @@ -37,6 +37,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo { public static final Logger LOG=Log.getLogger("org.eclipse.jetty.io.nio"); + private final boolean WORK_AROUND_JVM_BUG_6346658 = System.getProperty("os.name").toLowerCase().contains("win"); private final SelectorManager.SelectSet _selectSet; private final SelectorManager _manager; private SelectionKey _key; @@ -681,15 +682,23 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo @Override public void close() throws IOException { - try + // On unix systems there is a JVM issue that if you cancel before closing, it can + // cause the selector to block waiting for a channel to close and that channel can + // block waiting for the remote end. But on windows, if you don't cancel before a + // close, then the selector can block anyway! + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=357318 + if (WORK_AROUND_JVM_BUG_6346658) { - SelectionKey key = _key; - if (key!=null) - key.cancel(); - } - catch (Throwable e) - { - LOG.ignore(e); + try + { + SelectionKey key = _key; + if (key!=null) + key.cancel(); + } + catch (Throwable e) + { + LOG.ignore(e); + } } try From 72951403d35ee2ce5207ba7f657bf3daae2f05fe Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Mon, 26 Mar 2012 22:48:50 +1100 Subject: [PATCH 044/100] 375096 If starting a server instance fails in osgi it is cleaned up. --- .../DefaultJettyAtJettyHomeHelper.java | 345 +++++++++--------- .../JettyServerServiceTracker.java | 100 ++--- .../JettyServersManagedFactory.java | 13 +- .../serverfactory/ServerInstanceWrapper.java | 218 ++++++----- 4 files changed, 336 insertions(+), 340 deletions(-) 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 c07ab027131..d8491eeacbe 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 @@ -39,7 +39,7 @@ import org.osgi.framework.BundleContext; public class DefaultJettyAtJettyHomeHelper { private static final Logger LOG = Log.getLogger(DefaultJettyAtJettyHomeHelper.class); - + /** * contains a comma separated list of pathes to the etc/jetty-*.xml files * used to configure jetty. By default the value is 'etc/jetty.xml' when the @@ -69,7 +69,7 @@ public class DefaultJettyAtJettyHomeHelper { * Usual system property used as the port for https for a typical jetty configuration. */ public static final String SYS_PROP_JETTY_PORT_SSL = "jetty.port.ssl"; - + /** * Called by the JettyBootStrapActivator. * If the system property jetty.home is defined and points to a folder, @@ -88,81 +88,76 @@ public class DefaultJettyAtJettyHomeHelper { * that might use them as part of their properties. *

*/ - public static void startJettyAtJettyHome(BundleContext bundleContext) + public static void startJettyAtJettyHome(BundleContext bundleContext) throws Exception { - String jettyHomeSysProp = System.getProperty(SYS_PROP_JETTY_HOME); - String jettyHomeBundleSysProp = System.getProperty(SYS_PROP_JETTY_HOME_BUNDLE); - File jettyHome = null; - Bundle jettyHomeBundle = null; - if (jettyHomeSysProp != null) - { - jettyHomeSysProp = resolvePropertyValue(jettyHomeSysProp); - //bug 329621 - if (jettyHomeSysProp.startsWith("\"") && jettyHomeSysProp.endsWith("\"") - || (jettyHomeSysProp.startsWith("'") && jettyHomeSysProp.endsWith("'"))) { - jettyHomeSysProp = jettyHomeSysProp.substring(1, jettyHomeSysProp.length() - 1); - } - if (jettyHomeBundleSysProp != null) - { - LOG.warn("Both the jetty.home property and the jetty.home.bundle property are defined." - + " jetty.home.bundle is not taken into account."); - } - jettyHome = new File(jettyHomeSysProp); - if (!jettyHome.exists() || !jettyHome.isDirectory()) - { - LOG.warn("Unable to locate the jetty.home folder " + jettyHomeSysProp); - return; - } - } - else if (jettyHomeBundleSysProp != null) - { - jettyHomeBundleSysProp = resolvePropertyValue(jettyHomeBundleSysProp); - for (Bundle b : bundleContext.getBundles()) - { - if (b.getSymbolicName().equals(jettyHomeBundleSysProp)) - { - jettyHomeBundle = b; - break; - } - } - if (jettyHomeBundle == null) - { - LOG.warn("Unable to find the jetty.home.bundle named " + jettyHomeSysProp); - return; - } - - } - if (jettyHome == null && jettyHomeBundle == null) - { - LOG.warn("No default jetty started."); - return; - } - try - { - Server server = new Server(); - Dictionary properties = new Hashtable(); - properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME); - - String configURLs = jettyHome != null ? getJettyConfigurationURLs(jettyHome) : getJettyConfigurationURLs(jettyHomeBundle); - properties.put(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS, configURLs); + String jettyHomeSysProp = System.getProperty(SYS_PROP_JETTY_HOME); + String jettyHomeBundleSysProp = System.getProperty(SYS_PROP_JETTY_HOME_BUNDLE); + File jettyHome = null; + Bundle jettyHomeBundle = null; + if (jettyHomeSysProp != null) + { + jettyHomeSysProp = resolvePropertyValue(jettyHomeSysProp); + //bug 329621 + if (jettyHomeSysProp.startsWith("\"") && jettyHomeSysProp.endsWith("\"") + || (jettyHomeSysProp.startsWith("'") && jettyHomeSysProp.endsWith("'"))) { + jettyHomeSysProp = jettyHomeSysProp.substring(1, jettyHomeSysProp.length() - 1); + } + if (jettyHomeBundleSysProp != null) + { + LOG.warn("Both the jetty.home property and the jetty.home.bundle property are defined." + + " jetty.home.bundle is not taken into account."); + } + jettyHome = new File(jettyHomeSysProp); + if (!jettyHome.exists() || !jettyHome.isDirectory()) + { + LOG.warn("Unable to locate the jetty.home folder " + jettyHomeSysProp); + return; + } + } + else if (jettyHomeBundleSysProp != null) + { + jettyHomeBundleSysProp = resolvePropertyValue(jettyHomeBundleSysProp); + for (Bundle b : bundleContext.getBundles()) + { + if (b.getSymbolicName().equals(jettyHomeBundleSysProp)) + { + jettyHomeBundle = b; + break; + } + } + if (jettyHomeBundle == null) + { + LOG.warn("Unable to find the jetty.home.bundle named " + jettyHomeSysProp); + return; + } - LOG.info("Configuring the default jetty server with " + configURLs); - - //these properties usually are the ones passed to this type of configuration. - setProperty(properties,SYS_PROP_JETTY_HOME,System.getProperty(SYS_PROP_JETTY_HOME)); - setProperty(properties,SYS_PROP_JETTY_HOST,System.getProperty(SYS_PROP_JETTY_HOST)); - setProperty(properties,SYS_PROP_JETTY_PORT,System.getProperty(SYS_PROP_JETTY_PORT)); - setProperty(properties,SYS_PROP_JETTY_PORT_SSL,System.getProperty(SYS_PROP_JETTY_PORT_SSL)); + } + if (jettyHome == null && jettyHomeBundle == null) + { + LOG.warn("No default jetty started."); + return; + } + + Server server = new Server(); + Dictionary properties = new Hashtable(); + properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME); + + String configURLs = jettyHome != null ? getJettyConfigurationURLs(jettyHome) : getJettyConfigurationURLs(jettyHomeBundle); + properties.put(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS, configURLs); + + LOG.info("Configuring the default jetty server with " + configURLs); + + //these properties usually are the ones passed to this type of configuration. + setProperty(properties,SYS_PROP_JETTY_HOME,System.getProperty(SYS_PROP_JETTY_HOME)); + setProperty(properties,SYS_PROP_JETTY_HOST,System.getProperty(SYS_PROP_JETTY_HOST)); + setProperty(properties,SYS_PROP_JETTY_PORT,System.getProperty(SYS_PROP_JETTY_PORT)); + setProperty(properties,SYS_PROP_JETTY_PORT_SSL,System.getProperty(SYS_PROP_JETTY_PORT_SSL)); + + bundleContext.registerService(Server.class.getName(), server, properties); + // hookNestedConnectorToBridgeServlet(server); - bundleContext.registerService(Server.class.getName(), server, properties); -// hookNestedConnectorToBridgeServlet(server); - } - catch (Throwable t) - { - t.printStackTrace(); - } } - + /** * Minimum setup for the location of the configuration files given a jettyhome folder. * Reads the system property jetty.etc.config.urls and look for the corresponding jetty @@ -172,22 +167,22 @@ public class DefaultJettyAtJettyHomeHelper { */ private static String getJettyConfigurationURLs(File jettyhome) { - String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml"); + String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml"); StringTokenizer tokenizer = new StringTokenizer(jettyetc,";,", false); StringBuilder res = new StringBuilder(); while (tokenizer.hasMoreTokens()) { - String next = tokenizer.nextToken().trim(); - if (!next.startsWith("/") && next.indexOf(':') == -1) - { - try { - next = new File(jettyhome, next).toURI().toURL().toString(); - } catch (MalformedURLException e) { - e.printStackTrace(); - continue; - } - } - appendToCommaSeparatedList(res, next); + String next = tokenizer.nextToken().trim(); + if (!next.startsWith("/") && next.indexOf(':') == -1) + { + try { + next = new File(jettyhome, next).toURI().toURL().toString(); + } catch (MalformedURLException e) { + e.printStackTrace(); + continue; + } + } + appendToCommaSeparatedList(res, next); } return res.toString(); } @@ -202,108 +197,108 @@ public class DefaultJettyAtJettyHomeHelper { */ private static String getJettyConfigurationURLs(Bundle configurationBundle) { - String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml"); + String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml"); StringTokenizer tokenizer = new StringTokenizer(jettyetc,";,", false); StringBuilder res = new StringBuilder(); - + while (tokenizer.hasMoreTokens()) { String etcFile = tokenizer.nextToken().trim(); if (etcFile.startsWith("/") || etcFile.indexOf(":") != -1) { - appendToCommaSeparatedList(res, etcFile); + appendToCommaSeparatedList(res, etcFile); } else { - Enumeration enUrls = BundleFileLocatorHelper.DEFAULT - .findEntries(configurationBundle, etcFile); - - //default for org.eclipse.osgi.boot where we look inside jettyhome for the default embedded configuration. - //default inside jettyhome. this way fragments to the bundle can define their own configuration. - if ((enUrls == null || !enUrls.hasMoreElements()) && etcFile.endsWith("etc/jetty.xml")) - { - enUrls = BundleFileLocatorHelper.DEFAULT - .findEntries(configurationBundle, "/jettyhome/etc/jetty-osgi-default.xml"); - System.err.println("Configuring jetty with the default embedded configuration:" + - "bundle: " + configurationBundle.getSymbolicName() + - " config: /jettyhome/etc/jetty-osgi-default.xml"); - } - if (enUrls == null || !enUrls.hasMoreElements()) - { - System.err.println("Unable to locate a jetty configuration file for " + etcFile); - } - if (enUrls != null) - { - while (enUrls.hasMoreElements()) - { - appendToCommaSeparatedList(res, enUrls.nextElement().toString()); - } - } + Enumeration enUrls = BundleFileLocatorHelper.DEFAULT + .findEntries(configurationBundle, etcFile); + + //default for org.eclipse.osgi.boot where we look inside jettyhome for the default embedded configuration. + //default inside jettyhome. this way fragments to the bundle can define their own configuration. + if ((enUrls == null || !enUrls.hasMoreElements()) && etcFile.endsWith("etc/jetty.xml")) + { + enUrls = BundleFileLocatorHelper.DEFAULT + .findEntries(configurationBundle, "/jettyhome/etc/jetty-osgi-default.xml"); + System.err.println("Configuring jetty with the default embedded configuration:" + + "bundle: " + configurationBundle.getSymbolicName() + + " config: /jettyhome/etc/jetty-osgi-default.xml"); + } + if (enUrls == null || !enUrls.hasMoreElements()) + { + System.err.println("Unable to locate a jetty configuration file for " + etcFile); + } + if (enUrls != null) + { + while (enUrls.hasMoreElements()) + { + appendToCommaSeparatedList(res, enUrls.nextElement().toString()); + } + } } } return res.toString(); } - - private static void appendToCommaSeparatedList(StringBuilder buffer, String value) - { - if (buffer.length() != 0) - { - buffer.append(","); - } - buffer.append(value); - } - - private static void setProperty(Dictionary properties, String key, String value) - { - if (value != null) - { - properties.put(key, value); - } - } - - /** - * recursively substitute the ${sysprop} by their actual system property. - * ${sysprop,defaultvalue} will use 'defaultvalue' as the value if no sysprop is defined. - * Not the most efficient code but we are shooting for simplicity and speed of development here. - * - * @param value - * @return - */ - public static String resolvePropertyValue(String value) - { - int ind = value.indexOf("${"); - if (ind == -1) { - return value; - } - int ind2 = value.indexOf('}', ind); - if (ind2 == -1) { - return value; - } - String sysprop = value.substring(ind+2, ind2); - String defaultValue = null; - int comma = sysprop.indexOf(','); - if (comma != -1 && comma+1 != sysprop.length()) - { - defaultValue = sysprop.substring(comma+1); - defaultValue = resolvePropertyValue(defaultValue); - sysprop = sysprop.substring(0,comma); - } - else - { - defaultValue = "${" + sysprop + "}"; - } - - String v = System.getProperty(sysprop); - - String reminder = value.length() > ind2 + 1 ? value.substring(ind2+1) : ""; - reminder = resolvePropertyValue(reminder); - if (v != null) - { - return value.substring(0, ind) + v + reminder; - } - else - { - return value.substring(0, ind) + defaultValue + reminder; - } - } + + private static void appendToCommaSeparatedList(StringBuilder buffer, String value) + { + if (buffer.length() != 0) + { + buffer.append(","); + } + buffer.append(value); + } + + private static void setProperty(Dictionary properties, String key, String value) + { + if (value != null) + { + properties.put(key, value); + } + } + + /** + * recursively substitute the ${sysprop} by their actual system property. + * ${sysprop,defaultvalue} will use 'defaultvalue' as the value if no sysprop is defined. + * Not the most efficient code but we are shooting for simplicity and speed of development here. + * + * @param value + * @return + */ + public static String resolvePropertyValue(String value) + { + int ind = value.indexOf("${"); + if (ind == -1) { + return value; + } + int ind2 = value.indexOf('}', ind); + if (ind2 == -1) { + return value; + } + String sysprop = value.substring(ind+2, ind2); + String defaultValue = null; + int comma = sysprop.indexOf(','); + if (comma != -1 && comma+1 != sysprop.length()) + { + defaultValue = sysprop.substring(comma+1); + defaultValue = resolvePropertyValue(defaultValue); + sysprop = sysprop.substring(0,comma); + } + else + { + defaultValue = "${" + sysprop + "}"; + } + + String v = System.getProperty(sysprop); + + String reminder = value.length() > ind2 + 1 ? value.substring(ind2+1) : ""; + reminder = resolvePropertyValue(reminder); + if (v != null) + { + return value.substring(0, ind) + v + reminder; + } + else + { + return value.substring(0, ind) + defaultValue + reminder; + } + } } 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 200647cecc9..88f1d7f4f5c 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 @@ -18,50 +18,53 @@ import java.util.Properties; import org.eclipse.jetty.osgi.boot.OSGiServerConstants; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; import org.osgi.framework.Bundle; import org.osgi.framework.ServiceEvent; import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceReference; /** - * Deploy the jetty server instances when they are registered as an OSGi service. + * Deploy the jetty server instances when they are registered as an OSGi + * service. */ public class JettyServerServiceTracker implements ServiceListener, IManagedJettyServerRegistry { - + private static Logger LOG = Log.getLogger(JettyServerServiceTracker.class.getName()); + /** - * Servers indexed by PIDs. PIDs are generated by the ConfigurationAdmin service. + * Servers indexed by PIDs. PIDs are generated by the ConfigurationAdmin + * service. */ private Map _serversIndexedByName = new HashMap(); + /** The context-handler to deactivate indexed by ServerInstanceWrapper */ private Map _indexByServiceReference = new HashMap(); - /** * Stops each one of the registered servers. */ public void stop() { - //not sure that this is really useful but here we go. - for (ServerInstanceWrapper wrapper : _serversIndexedByName.values()) - { - try - { - wrapper.stop(); - } - catch (Throwable t) - { - - } - } + // not sure that this is really useful but here we go. + for (ServerInstanceWrapper wrapper : _serversIndexedByName.values()) + { + try + { + wrapper.stop(); + } + catch (Throwable t) + { + LOG.warn(t); + } + } } - /** * Receives notification that a service has had a lifecycle change. * - * @param ev - * The ServiceEvent object. + * @param ev The ServiceEvent object. */ public void serviceChanged(ServiceEvent ev) { @@ -71,17 +74,16 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty case ServiceEvent.MODIFIED: case ServiceEvent.UNREGISTERING: { - ServerInstanceWrapper instance = unregisterInIndex(ev.getServiceReference()); + ServerInstanceWrapper instance = unregisterInIndex(ev.getServiceReference()); if (instance != null) { try { - instance.stop(); + instance.stop(); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + LOG.warn(e); } } } @@ -96,32 +98,35 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty } case ServiceEvent.REGISTERED: { - Bundle contributor = sr.getBundle(); - Server server = (Server)contributor.getBundleContext().getService(sr); - ServerInstanceWrapper wrapper = registerInIndex(server, sr); - Properties props = new Properties(); - for (String key : sr.getPropertyKeys()) - { - Object value = sr.getProperty(key); - props.put(key, value); - } - wrapper.start(server, props); - break; + try + { + Bundle contributor = sr.getBundle(); + Server server = (Server) contributor.getBundleContext().getService(sr); + ServerInstanceWrapper wrapper = registerInIndex(server, sr); + Properties props = new Properties(); + for (String key : sr.getPropertyKeys()) + { + Object value = sr.getProperty(key); + props.put(key, value); + } + wrapper.start(server, props); + } + catch (Exception e) + { + LOG.warn(e); + } + break; } } } private ServerInstanceWrapper registerInIndex(Server server, ServiceReference sr) { - String name = (String)sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); - if (name == null) - { - throw new IllegalArgumentException("The property " + - OSGiServerConstants.MANAGED_JETTY_SERVER_NAME + " is mandatory"); - } + String name = (String) sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); + if (name == null) { throw new IllegalArgumentException("The property " + OSGiServerConstants.MANAGED_JETTY_SERVER_NAME + " is mandatory"); } ServerInstanceWrapper wrapper = new ServerInstanceWrapper(name); - _indexByServiceReference.put(sr,wrapper); - _serversIndexedByName.put(name,wrapper); + _indexByServiceReference.put(sr, wrapper); + _serversIndexedByName.put(name, wrapper); return wrapper; } @@ -133,7 +138,7 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty */ private ServerInstanceWrapper unregisterInIndex(ServiceReference sr) { - ServerInstanceWrapper handler = _indexByServiceReference.remove(sr); + ServerInstanceWrapper handler = _indexByServiceReference.remove(sr); if (handler == null) { // a warning? @@ -149,13 +154,12 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty /** * @param managedServerName The server name - * @return the corresponding jetty server wrapped with its deployment properties. + * @return the corresponding jetty server wrapped with its deployment + * properties. */ public ServerInstanceWrapper getServerInstanceWrapper(String managedServerName) { - return _serversIndexedByName.get(managedServerName == null - ? OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME : managedServerName); + return _serversIndexedByName.get(managedServerName == null ? OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME : managedServerName); } - - + } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServersManagedFactory.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServersManagedFactory.java index 31ad22534b2..3872fad70ff 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServersManagedFactory.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServersManagedFactory.java @@ -99,14 +99,21 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag String name = (String)properties.get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); if (name == null) { - throw new ConfigurationException(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, - "The name of the server is mandatory"); + throw new ConfigurationException(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, + "The name of the server is mandatory"); } serverInstanceWrapper = new ServerInstanceWrapper(name); _serversIndexedByPID.put(pid, serverInstanceWrapper); _serversNameIndexedByPID.put(pid, name); _serversPIDIndexedByName.put(name, pid); - serverInstanceWrapper.start(new Server(), properties); + try + { + serverInstanceWrapper.start(new Server(), properties); + } + catch (Exception e) + { + throw new ConfigurationException(null, "Error starting jetty server instance", e); + } } public synchronized void deleted(String pid) 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 21d0d6adb7d..bb274fe313e 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 @@ -44,28 +44,29 @@ import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.xml.XmlConfiguration; import org.xml.sax.SAXParseException; - /** * Exposes a Jetty Server to be managed by an OSGi ManagedServiceFactory - * Configure and start it. - * Can also be used from the ManagedServiceFactory + * Configure and start it. Can also be used from the ManagedServiceFactory */ -public class ServerInstanceWrapper { +public class ServerInstanceWrapper +{ - /** The value of this property points to the parent director of - * the jetty.xml configuration file currently executed. - * Everything is passed as a URL to support the - * case where the bundle is zipped. */ + /** + * The value of this property points to the parent director of the jetty.xml + * configuration file currently executed. Everything is passed as a URL to + * 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 Logger __logger = Log.getLogger(ServerInstanceWrapper.class.getName()); - + private static Logger LOG = Log.getLogger(ServerInstanceWrapper.class.getName()); + private final String _managedServerName; - + /** * The managed jetty server */ private Server _server; + private ContextHandlerCollection _ctxtHandler; /** @@ -74,32 +75,34 @@ public class ServerInstanceWrapper { * let the TldScanner find the jars where the tld files are. */ private ClassLoader _commonParentClassLoaderForWebapps; + private DeploymentManager _deploymentManager; + private OSGiAppProvider _provider; - + private WebBundleDeployerHelper _webBundleDeployerHelper; - - + public ServerInstanceWrapper(String managedServerName) { _managedServerName = managedServerName; } - + public String getManagedServerName() { return _managedServerName; } - + /** - * The classloader that should be the parent classloader for - * each webapp deployed on this server. + * The classloader that should be the parent classloader for each webapp + * deployed on this server. + * * @return */ public ClassLoader getParentClassLoaderForWebapps() { return _commonParentClassLoaderForWebapps; } - + /** * @return The deployment manager registered on this server. */ @@ -107,7 +110,7 @@ public class ServerInstanceWrapper { { return _deploymentManager; } - + /** * @return The app provider registered on this server. */ @@ -115,19 +118,17 @@ public class ServerInstanceWrapper { { return _provider; } - - + public Server getServer() { return _server; } - - + public WebBundleDeployerHelper getWebBundleDeployerHelp() { return _webBundleDeployerHelper; } - + /** * @return The collection of context handlers */ @@ -136,8 +137,7 @@ public class ServerInstanceWrapper { return _ctxtHandler; } - - public void start(Server server, Dictionary props) + public void start(Server server, Dictionary props) throws Exception { _server = server; ClassLoader contextCl = Thread.currentThread().getContextClassLoader(); @@ -146,62 +146,61 @@ public class ServerInstanceWrapper { // passing this bundle's classloader as the context classlaoder // makes sure there is access to all the jetty's bundles ClassLoader libExtClassLoader = null; - String sharedURLs = (String)props.get(OSGiServerConstants.MANAGED_JETTY_SHARED_LIB_FOLDER_URLS); - try - { - List shared = sharedURLs != null ? extractFiles(sharedURLs) : null; - libExtClassLoader = LibExtClassLoaderHelper.createLibExtClassLoader( - shared, null, server, JettyBootstrapActivator.class.getClassLoader()); - } - catch (MalformedURLException e) - { - e.printStackTrace(); - } + String sharedURLs = (String) props.get(OSGiServerConstants.MANAGED_JETTY_SHARED_LIB_FOLDER_URLS); + + List shared = sharedURLs != null ? extractFiles(sharedURLs) : null; + libExtClassLoader = LibExtClassLoaderHelper.createLibExtClassLoader(shared, null, server, JettyBootstrapActivator.class.getClassLoader()); Thread.currentThread().setContextClassLoader(libExtClassLoader); - + configure(server, props); init(); - //now that we have an app provider we can call the registration customizer. - try - { - URL[] jarsWithTlds = getJarsWithTlds(); - _commonParentClassLoaderForWebapps = jarsWithTlds == null - ? libExtClassLoader - :new TldLocatableURLClassloader(libExtClassLoader,jarsWithTlds); - } - catch (MalformedURLException e) - { - e.printStackTrace(); - } + // now that we have an app provider we can call the registration + // customizer. + + URL[] jarsWithTlds = getJarsWithTlds(); + _commonParentClassLoaderForWebapps = jarsWithTlds == null ? libExtClassLoader : new TldLocatableURLClassloader(libExtClassLoader, jarsWithTlds); - server.start(); + _webBundleDeployerHelper = new WebBundleDeployerHelper(this); } - catch (Throwable t) + catch (Exception e) { - t.printStackTrace(); + if (server != null) + { + try + { + server.stop(); + } + catch (Exception x) + { + LOG.ignore(x); + } + } + throw e; } finally { Thread.currentThread().setContextClassLoader(contextCl); } - _webBundleDeployerHelper = new WebBundleDeployerHelper(this); + + } - - + public void stop() { - try { + try + { if (_server.isRunning()) { _server.stop(); } - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + } + catch (Exception e) + { + LOG.warn(e); } } @@ -229,14 +228,13 @@ public class ServerInstanceWrapper { private URL[] getJarsWithTlds() throws Exception { ArrayList res = new ArrayList(); - WebBundleDeployerHelper.staticInit();//that is not looking great. + WebBundleDeployerHelper.staticInit();// that is not looking great. for (WebappRegistrationCustomizer regCustomizer : WebBundleDeployerHelper.JSP_REGISTRATION_HELPERS) { URL[] urls = regCustomizer.getJarsWithTlds(_provider, WebBundleDeployerHelper.BUNDLE_FILE_LOCATOR_HELPER); for (URL url : urls) { - if (!res.contains(url)) - res.add(url); + if (!res.contains(url)) res.add(url); } } if (!res.isEmpty()) @@ -244,19 +242,15 @@ public class ServerInstanceWrapper { else return null; } - + private void configure(Server server, Dictionary props) throws Exception { String jettyConfigurationUrls = (String) props.get(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS); - List jettyConfigurations = jettyConfigurationUrls != null - ? extractResources(jettyConfigurationUrls) : null; - if (jettyConfigurations == null || jettyConfigurations.isEmpty()) - { - return; - } - Map id_map = new HashMap(); - id_map.put("Server",server); - Map properties = new HashMap(); + List jettyConfigurations = jettyConfigurationUrls != null ? extractResources(jettyConfigurationUrls) : null; + if (jettyConfigurations == null || jettyConfigurations.isEmpty()) { return; } + Map id_map = new HashMap(); + id_map.put("Server", server); + Map properties = new HashMap(); Enumeration en = props.keys(); while (en.hasMoreElements()) { @@ -275,15 +269,17 @@ public class ServerInstanceWrapper { is = r.getInputStream(); XmlConfiguration config = new XmlConfiguration(is); config.getIdMap().putAll(id_map); - - //#334062 compute the URL of the folder that contains the jetty.xml conf file - //and set it as a property so we can compute relative paths from it. + + // #334062 compute the URL of the folder that contains the + // jetty.xml conf file + // and set it as a property so we can compute relative paths + // from it. String urlPath = jettyConfiguration.toString(); int lastSlash = urlPath.lastIndexOf('/'); if (lastSlash > 4) { urlPath = urlPath.substring(0, lastSlash); - Map properties2 = new HashMap(properties); + Map properties2 = new HashMap(properties); properties2.put(PROPERTY_THIS_JETTY_XML_FOLDER_URL, urlPath); config.getProperties().putAll(properties2); } @@ -292,11 +288,11 @@ public class ServerInstanceWrapper { config.getProperties().putAll(properties); } config.configure(); - id_map=config.getIdMap(); + id_map = config.getIdMap(); } catch (SAXParseException saxparse) { - __logger.warn("Unable to configure the jetty/etc file " + jettyConfiguration,saxparse); + LOG.warn("Unable to configure the jetty/etc file " + jettyConfiguration, saxparse); throw saxparse; } finally @@ -306,8 +302,7 @@ public class ServerInstanceWrapper { } } - - + /** * Must be called after the server is configured. * @@ -319,50 +314,48 @@ public class ServerInstanceWrapper { private void init() { // Get the context handler - _ctxtHandler = (ContextHandlerCollection)_server.getChildHandlerByClass(ContextHandlerCollection.class); - + _ctxtHandler = (ContextHandlerCollection) _server.getChildHandlerByClass(ContextHandlerCollection.class); + // get a deployerManager List deployers = _server.getBeans(DeploymentManager.class); if (deployers != null && !deployers.isEmpty()) { _deploymentManager = deployers.get(0); - + for (AppProvider provider : _deploymentManager.getAppProviders()) { if (provider instanceof OSGiAppProvider) { - _provider=(OSGiAppProvider)provider; + _provider = (OSGiAppProvider) provider; break; } } if (_provider == null) { - //create it on the fly with reasonable default values. + // create it on the fly with reasonable default values. try { _provider = new OSGiAppProvider(); - _provider.setMonitoredDirResource( - Resource.newResource(getDefaultOSGiContextsHome( - new File(System.getProperty("jetty.home"))).toURI())); - } catch (IOException e) { - e.printStackTrace(); + _provider.setMonitoredDirResource(Resource.newResource(getDefaultOSGiContextsHome(new File(System.getProperty("jetty.home"))).toURI())); + } + catch (IOException e) + { + LOG.warn(e); } _deploymentManager.addAppProvider(_provider); } } - if (_ctxtHandler == null || _provider==null) - throw new IllegalStateException("ERROR: No ContextHandlerCollection or OSGiAppProvider configured"); - + if (_ctxtHandler == null || _provider == null) throw new IllegalStateException("ERROR: No ContextHandlerCollection or OSGiAppProvider configured"); } - + /** * @return The default folder in which the context files of the osgi bundles * are located and watched. Or null when the system property - * "jetty.osgi.contexts.home" is not defined. - * If the configuration file defines the OSGiAppProvider's context. - * This will not be taken into account. + * "jetty.osgi.contexts.home" is not defined. If the configuration + * file defines the OSGiAppProvider's context. This will not be + * taken into account. */ File getDefaultOSGiContextsHome(File jettyHome) { @@ -370,20 +363,19 @@ public class ServerInstanceWrapper { if (jettyContextsHome != null) { File contextsHome = new File(jettyContextsHome); - if (!contextsHome.exists() || !contextsHome.isDirectory()) - { - throw new IllegalArgumentException("the ${jetty.osgi.contexts.home} '" + jettyContextsHome + " must exist and be a folder"); - } + if (!contextsHome.exists() || !contextsHome.isDirectory()) { throw new IllegalArgumentException( + "the ${jetty.osgi.contexts.home} '" + jettyContextsHome + + " must exist and be a folder"); } return contextsHome; } return new File(jettyHome, "/contexts"); } - + File getOSGiContextsHome() { return _provider.getContextXmlDirAsFile(); } - + /** * @return the urls in this string. */ @@ -396,19 +388,19 @@ public class ServerInstanceWrapper { String tok = tokenizer.nextToken(); try { - urls.add(((DefaultFileLocatorHelper) WebBundleDeployerHelper - .BUNDLE_FILE_LOCATOR_HELPER).getLocalURL(new URL(tok))); + urls.add(((DefaultFileLocatorHelper) WebBundleDeployerHelper.BUNDLE_FILE_LOCATOR_HELPER).getLocalURL(new URL(tok))); } catch (Throwable mfe) { - + LOG.warn(mfe); } } return urls; } - + /** - * Get the folders that might contain jars for the legacy J2EE shared libraries + * Get the folders that might contain jars for the legacy J2EE shared + * libraries */ private List extractFiles(String propertyValue) { @@ -420,8 +412,7 @@ public class ServerInstanceWrapper { try { URL url = new URL(tok); - url = ((DefaultFileLocatorHelper) WebBundleDeployerHelper - .BUNDLE_FILE_LOCATOR_HELPER).getFileURL(url); + url = ((DefaultFileLocatorHelper) WebBundleDeployerHelper.BUNDLE_FILE_LOCATOR_HELPER).getFileURL(url); if (url.getProtocol().equals("file")) { Resource res = Resource.newResource(url); @@ -434,11 +425,10 @@ public class ServerInstanceWrapper { } catch (Throwable mfe) { - + LOG.warn(mfe); } } return files; } - } From 22f437c36d8c397d9db9d20771d9af4af5c40865 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Wed, 28 Mar 2012 14:47:27 +1100 Subject: [PATCH 045/100] 375490 NPE with --help on command line --- jetty-start/src/main/java/org/eclipse/jetty/start/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java index d625814ba26..70fbe1063f8 100644 --- a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java +++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java @@ -381,7 +381,7 @@ public class Main } else if (info.equals("@STARTINI")) { - List ini = loadStartIni(null); + List ini = loadStartIni(new File(_jettyHome,"start.ini")); if (ini != null && ini.size() > 0) { for (String a : ini) From ef0d6d32f96807599b51d98bfe5e7e99fe4d48b2 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Wed, 28 Mar 2012 19:27:06 +1100 Subject: [PATCH 046/100] 374881 Ensure setCopyWebInf(true) only copies WEB-INF if !setCopyWebDir(true) --- .../jetty/webapp/WebInfConfiguration.java | 74 +++++++++---------- 1 file changed, 33 insertions(+), 41 deletions(-) diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java index 9495f68a923..d7748365c8e 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java @@ -402,8 +402,7 @@ public class WebInfConfiguration extends AbstractConfiguration } if (LOG.isDebugEnabled()) - LOG.debug("Try webapp=" + web_app + ", exists=" + web_app.exists() + ", directory=" + web_app.isDirectory()); - + LOG.debug("Try webapp=" + web_app + ", exists=" + web_app.exists() + ", directory=" + web_app.isDirectory()+" file="+(web_app.getFile())); // Is the WAR usable directly? if (web_app.exists() && !web_app.isDirectory() && !web_app.toString().startsWith("jar:")) { @@ -485,57 +484,50 @@ public class WebInfConfiguration extends AbstractConfiguration LOG.debug("webapp=" + web_app); } - // Do we need to extract WEB-INF/lib? - if (context.isCopyWebInf()) + if (context.isCopyWebInf() && !context.isCopyWebDir()) { Resource web_inf= web_app.addPath("WEB-INF/"); - if (web_inf instanceof ResourceCollection || - web_inf.exists() && - web_inf.isDirectory() && - (web_inf.getFile()==null || !web_inf.getFile().isDirectory())) - { - File extractedWebInfDir= new File(context.getTempDirectory(), "webinf"); - if (extractedWebInfDir.exists()) - IO.delete(extractedWebInfDir); - extractedWebInfDir.mkdir(); - Resource web_inf_lib = web_inf.addPath("lib/"); - File webInfDir=new File(extractedWebInfDir,"WEB-INF"); - webInfDir.mkdir(); + File extractedWebInfDir= new File(context.getTempDirectory(), "webinf"); + if (extractedWebInfDir.exists()) + IO.delete(extractedWebInfDir); + extractedWebInfDir.mkdir(); + Resource web_inf_lib = web_inf.addPath("lib/"); + File webInfDir=new File(extractedWebInfDir,"WEB-INF"); + webInfDir.mkdir(); - if (web_inf_lib.exists()) - { - File webInfLibDir = new File(webInfDir, "lib"); - if (webInfLibDir.exists()) - IO.delete(webInfLibDir); - webInfLibDir.mkdir(); + if (web_inf_lib.exists()) + { + File webInfLibDir = new File(webInfDir, "lib"); + if (webInfLibDir.exists()) + IO.delete(webInfLibDir); + webInfLibDir.mkdir(); - LOG.info("Copying WEB-INF/lib " + web_inf_lib + " to " + webInfLibDir); - web_inf_lib.copyTo(webInfLibDir); - } + LOG.info("Copying WEB-INF/lib " + web_inf_lib + " to " + webInfLibDir); + web_inf_lib.copyTo(webInfLibDir); + } - Resource web_inf_classes = web_inf.addPath("classes/"); - if (web_inf_classes.exists()) - { - File webInfClassesDir = new File(webInfDir, "classes"); - if (webInfClassesDir.exists()) - IO.delete(webInfClassesDir); - webInfClassesDir.mkdir(); - LOG.info("Copying WEB-INF/classes from "+web_inf_classes+" to "+webInfClassesDir.getAbsolutePath()); - web_inf_classes.copyTo(webInfClassesDir); - } + Resource web_inf_classes = web_inf.addPath("classes/"); + if (web_inf_classes.exists()) + { + File webInfClassesDir = new File(webInfDir, "classes"); + if (webInfClassesDir.exists()) + IO.delete(webInfClassesDir); + webInfClassesDir.mkdir(); + LOG.info("Copying WEB-INF/classes from "+web_inf_classes+" to "+webInfClassesDir.getAbsolutePath()); + web_inf_classes.copyTo(webInfClassesDir); + } - web_inf=Resource.newResource(extractedWebInfDir.getCanonicalPath()); + web_inf=Resource.newResource(extractedWebInfDir.getCanonicalPath()); - ResourceCollection rc = new ResourceCollection(web_inf,web_app); + ResourceCollection rc = new ResourceCollection(web_inf,web_app); - if (LOG.isDebugEnabled()) - LOG.debug("context.resourcebase = "+rc); + if (LOG.isDebugEnabled()) + LOG.debug("context.resourcebase = "+rc); - context.setBaseResource(rc); - } + context.setBaseResource(rc); } } From 294c588023bbfa9dbdc184802f0985873a9cb218 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 28 Mar 2012 11:41:06 +0200 Subject: [PATCH 047/100] 375509 - Stalled stream stalls other streams or session control frames. --- .../eclipse/jetty/spdy/StandardSession.java | 19 +++- .../eclipse/jetty/spdy/FlowControlTest.java | 92 +++++++++++++++++++ 2 files changed, 106 insertions(+), 5 deletions(-) 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 f8fc892b1cb..f940b63b1ef 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 @@ -792,12 +792,21 @@ public class StandardSession implements ISession, Parser.Listener, Handler dataInfoRef1 = new AtomicReference<>(); + final AtomicReference dataInfoRef2 = new AtomicReference<>(); + session.syn(new SynInfo(true), new StreamFrameListener.Adapter() + { + private final AtomicInteger dataFrames = new AtomicInteger(); + + @Override + public void onData(Stream stream, DataInfo dataInfo) + { + int frames = dataFrames.incrementAndGet(); + if (frames == 1) + { + // Do not consume it to stall flow control + dataInfoRef1.set(dataInfo); + } + else + { + dataInfo.consume(dataInfo.length()); + if (dataInfo.isClose()) + latch.countDown(); + } + } + }).get(5, TimeUnit.SECONDS); + session.syn(new SynInfo(true), new StreamFrameListener.Adapter() + { + private final AtomicInteger dataFrames = new AtomicInteger(); + + @Override + public void onData(Stream stream, DataInfo dataInfo) + { + int frames = dataFrames.incrementAndGet(); + if (frames == 1) + { + // Do not consume it to stall flow control + dataInfoRef2.set(dataInfo); + } + else + { + dataInfo.consume(dataInfo.length()); + if (dataInfo.isClose()) + latch.countDown(); + } + } + }).get(5, TimeUnit.SECONDS); + session.syn(new SynInfo(true), new StreamFrameListener.Adapter() + { + @Override + public void onData(Stream stream, DataInfo dataInfo) + { + DataInfo dataInfo1 = dataInfoRef1.getAndSet(null); + if (dataInfo1 != null) + dataInfo1.consume(dataInfo1.length()); + DataInfo dataInfo2 = dataInfoRef2.getAndSet(null); + if (dataInfo2 != null) + dataInfo2.consume(dataInfo2.length()); + dataInfo.consume(dataInfo.length()); + if (dataInfo.isClose()) + latch.countDown(); + } + }).get(5, TimeUnit.SECONDS); + + Assert.assertTrue(latch.await(5, TimeUnit.SECONDS)); + } + private void expectException(Class exception, Callable command) { try From fe8b5a6cb329a9318b99d2e483c69ebf8fb84808 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 29 Mar 2012 16:58:56 +1100 Subject: [PATCH 048/100] 374505: ignore , as a cookie separator as per RFC6265 --- .../org/eclipse/jetty/server/CookieCutter.java | 4 ++-- .../org/eclipse/jetty/server/RequestTest.java | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java index 262e7522cb0..67ca6db2898 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java @@ -193,7 +193,7 @@ public class CookieCutter continue; case ';': - case ',': + // case ',': if (tokenstart>=0) value = hdr.substring(tokenstart, tokenend+1); else @@ -239,7 +239,7 @@ public class CookieCutter continue; case ';': - case ',': + // case ',': if (tokenstart>=0) { name = hdr.substring(tokenstart, tokenend+1); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java index a81ad64a20e..c099711b418 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java @@ -669,7 +669,7 @@ public class RequestTest "POST / HTTP/1.1\r\n"+ "Host: whatever\r\n"+ "Cookie: name0=value0; name1 = value1 ; \"\\\"name2\\\"\" = \"\\\"value2\\\"\" \n" + - "Cookie: $Version=2; name3=value3=value3;$path=/path;$domain=acme.com;$port=8080, name4=; name5 = ; name6\n" + + "Cookie: $Version=2; name3=value3=value3;$path=/path;$domain=acme.com;$port=8080; name4=; name5 = ; name6\n" + "Cookie: name7=value7;\n" + "Connection: close\r\n"+ "\r\n"); @@ -694,6 +694,20 @@ public class RequestTest assertEquals("", cookies.get(6).getValue()); assertEquals("name7", cookies.get(7).getName()); assertEquals("value7", cookies.get(7).getValue()); + + cookies.clear(); + response=_connector.getResponses( + "GET /other HTTP/1.1\n"+ + "Host: whatever\n"+ + "Other: header\n"+ + "Cookie: __utmz=14316.133020.1.1.utr=gna.de|ucn=(real)|utd=reral|utct=/games/hen-one,gnt-50-ba-keys:key,2072262.html\n"+ + "\n" + ); + assertTrue(response.startsWith("HTTP/1.1 200 OK")); + assertEquals(1,cookies.size()); + assertEquals("__utmz", cookies.get(0).getName()); + assertEquals("14316.133020.1.1.utr=gna.de|ucn=(real)|utd=reral|utct=/games/hen-one,gnt-50-ba-keys:key,2072262.html", cookies.get(0).getValue()); + } @Test From 50bc8fa400571eb165d6e5a8b635a5f5c17f9b13 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Thu, 29 Mar 2012 12:50:01 +0200 Subject: [PATCH 049/100] 375509 - Stalled stream stalls other streams or session control frames. Additional improvements for thread visibility, and clarified code comment. --- .../eclipse/jetty/spdy/StandardSession.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) 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 f940b63b1ef..a85103ba354 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 @@ -1005,8 +1005,8 @@ public class StandardSession implements ISession, Parser.Listener, Handler handler, C context, IStream stream, DataInfo dataInfo) { @@ -1024,11 +1024,11 @@ public class StandardSession implements ISession, Parser.Listener, Handler windowSize) - length = windowSize; + size = dataInfo.available(); + if (size > windowSize) + size = windowSize; - buffer = generator.data(stream.getId(), length, dataInfo); + buffer = generator.data(stream.getId(), size, dataInfo); return buffer; } catch (Throwable x) @@ -1041,13 +1041,14 @@ public class StandardSession implements ISession, Parser.Listener, Handler 0) { - // If we could not write a full data frame, then we need first - // to finish it, and then process the others (to avoid data garbling) + // We have written a frame out of this DataInfo, but there is more to write. + // We need to keep the correct ordering of frames, to avoid that another + // DataInfo for the same stream is written before this one is finished. enqueueFirst(this); } else From 2278d272353d6c18a40ee5439418d053342fe4a7 Mon Sep 17 00:00:00 2001 From: Thomas Becker Date: Fri, 30 Mar 2012 11:02:44 +0200 Subject: [PATCH 050/100] 375692: GzipFilter support for deflate Change-Id: I4a42d750cfbbb61078adafa1e2bcbc1973198dca --- ...=> AbstractCompressedResponseWrapper.java} | 381 +++++++++--------- .../http/gzip/AbstractCompressedStream.java | 343 ++++++++++++++++ .../http/gzip/CompressedResponseWrapper.java | 58 +++ .../jetty/http/gzip/CompressedStream.java | 77 ++++ .../jetty/http/gzip/CompressionType.java | 48 +++ .../http/gzip/DeflateResponseWrapperImpl.java | 54 +++ .../jetty/http/gzip/DeflateStreamImpl.java | 55 +++ .../http/gzip/GzipResponseWrapperImpl.java | 53 +++ .../eclipse/jetty/http/gzip/GzipStream.java | 305 -------------- .../jetty/http/gzip/GzipStreamImpl.java | 56 +++ .../jetty/server/handler/GzipHandler.java | 12 +- .../eclipse/jetty/servlets/GzipFilter.java | 134 +++--- .../jetty/servlets/IncludableGzipFilter.java | 87 ++-- .../servlets/GzipFilterContentLengthTest.java | 47 ++- .../GzipFilterDefaultNoRecompressTest.java | 54 ++- .../jetty/servlets/GzipFilterDefaultTest.java | 47 ++- .../servlets/GzipWithPipeliningTest.java | 71 +++- .../IncludableGzipFilterMinSizeTest.java | 30 +- .../servlets/IncludableGzipFilterTest.java | 49 ++- .../jetty/servlets/PipelineHelper.java | 10 +- .../jetty/servlets/gzip/GzipTester.java | 42 +- 21 files changed, 1332 insertions(+), 681 deletions(-) rename jetty-http/src/main/java/org/eclipse/jetty/http/gzip/{GzipResponseWrapper.java => AbstractCompressedResponseWrapper.java} (62%) create mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java create mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressedResponseWrapper.java create mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressedStream.java create mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressionType.java create mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/gzip/DeflateResponseWrapperImpl.java create mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/gzip/DeflateStreamImpl.java create mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipResponseWrapperImpl.java delete mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipStream.java create mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipStreamImpl.java diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipResponseWrapper.java b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedResponseWrapper.java similarity index 62% rename from jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipResponseWrapper.java rename to jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedResponseWrapper.java index 093e127d902..95c69109e99 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipResponseWrapper.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedResponseWrapper.java @@ -1,5 +1,5 @@ // ======================================================================== -// Copyright (c) Webtide LLC +// Copyright (c) 2009-2009 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 @@ -11,7 +11,6 @@ // You may elect to redistribute this code under either of these licenses. // ======================================================================== - package org.eclipse.jetty.http.gzip; import java.io.IOException; @@ -28,42 +27,36 @@ import javax.servlet.http.HttpServletResponseWrapper; import org.eclipse.jetty.util.StringUtil; - -/* ------------------------------------------------------------ */ +/*------------------------------------------------------------ */ /** + * Skeletal implementation of the CompressedResponseWrapper interface. + * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper */ -public class GzipResponseWrapper extends HttpServletResponseWrapper +public abstract class AbstractCompressedResponseWrapper extends HttpServletResponseWrapper implements CompressedResponseWrapper { - public static final int DEFAULT_BUFFER_SIZE = 8192; - public static final int DEFAULT_MIN_GZIP_SIZE = 256; - private HttpServletRequest _request; + public static final int DEFAULT_BUFFER_SIZE = 8192; + public static final int DEFAULT_MIN_COMPRESS_SIZE = 256; + private Set _mimeTypes; private int _bufferSize=DEFAULT_BUFFER_SIZE; - private int _minGzipSize=DEFAULT_MIN_GZIP_SIZE; + private int _minCompressSize=DEFAULT_MIN_COMPRESS_SIZE; + private HttpServletRequest _request; private PrintWriter _writer; - private GzipStream _gzStream; + private CompressedStream _compressedStream; private long _contentLength=-1; - private boolean _noGzip; + private boolean _noCompression; - /** - * Instantiates a new gzip response wrapper. - * - * @param request the request - * @param response the response - */ - public GzipResponseWrapper(HttpServletRequest request, HttpServletResponse response) + public AbstractCompressedResponseWrapper(HttpServletRequest request, HttpServletResponse response) { super(response); - _request=request; + _request = request; } /* ------------------------------------------------------------ */ /** - * Sets the mime types. - * - * @param mimeTypes the new mime types + * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setMimeTypes(java.util.Set) */ public void setMimeTypes(Set mimeTypes) { @@ -72,8 +65,9 @@ public class GzipResponseWrapper extends HttpServletResponseWrapper /* ------------------------------------------------------------ */ /** - * @see javax.servlet.ServletResponseWrapper#setBufferSize(int) + * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setBufferSize(int) */ + @Override public void setBufferSize(int bufferSize) { _bufferSize = bufferSize; @@ -81,76 +75,77 @@ public class GzipResponseWrapper extends HttpServletResponseWrapper /* ------------------------------------------------------------ */ /** - * Sets the min gzip size. - * - * @param minGzipSize the new min gzip size + * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setMinCompressSize(int) */ - public void setMinGzipSize(int minGzipSize) + public void setMinCompressSize(int minCompressSize) { - _minGzipSize = minGzipSize; + _minCompressSize = minCompressSize; } /* ------------------------------------------------------------ */ /** - * @see javax.servlet.ServletResponseWrapper#setContentType(java.lang.String) + * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setContentType(java.lang.String) */ + @Override public void setContentType(String ct) { super.setContentType(ct); - + if (ct!=null) { int colon=ct.indexOf(";"); if (colon>0) ct=ct.substring(0,colon); } - - if ((_gzStream==null || _gzStream._out==null) && + + if ((_compressedStream==null || _compressedStream.getOutputStream()==null) && (_mimeTypes==null && ct!=null && ct.contains("gzip") || _mimeTypes!=null && (ct==null||!_mimeTypes.contains(StringUtil.asciiToLowerCase(ct))))) { - noGzip(); + noCompression(); } } /* ------------------------------------------------------------ */ /** - * @see javax.servlet.http.HttpServletResponseWrapper#setStatus(int, java.lang.String) + * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setStatus(int, java.lang.String) */ + @Override public void setStatus(int sc, String sm) { super.setStatus(sc,sm); if (sc<200 || sc==204 || sc==205 || sc>=300) - noGzip(); + noCompression(); } /* ------------------------------------------------------------ */ /** - * @see javax.servlet.http.HttpServletResponseWrapper#setStatus(int) + * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setStatus(int) */ + @Override public void setStatus(int sc) { super.setStatus(sc); if (sc<200 || sc==204 || sc==205 ||sc>=300) - noGzip(); + noCompression(); } /* ------------------------------------------------------------ */ /** - * @see javax.servlet.ServletResponseWrapper#setContentLength(int) + * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setContentLength(int) */ + @Override public void setContentLength(int length) { setContentLength((long)length); } - - /* ------------------------------------------------------------ */ + protected void setContentLength(long length) { _contentLength=length; - if (_gzStream!=null) - _gzStream.setContentLength(length); - else if (_noGzip && _contentLength>=0) + if (_compressedStream!=null) + _compressedStream.setContentLength(length); + else if (_noCompression && _contentLength>=0) { HttpServletResponse response = (HttpServletResponse)getResponse(); if(_contentLength= 0) + { + if (_contentLength < Integer.MAX_VALUE) + _response.setContentLength((int)_contentLength); + else + _response.setHeader("Content-Length",Long.toString(_contentLength)); + } + } + + /* ------------------------------------------------------------ */ + /** + * @see java.io.OutputStream#flush() + */ + @Override + public void flush() throws IOException + { + if (_out == null || _bOut != null) + { + if (_contentLength > 0 && _contentLength < _minCompressSize) + doNotCompress(); + else + doCompress(); + } + + _out.flush(); + } + + /* ------------------------------------------------------------ */ + /** + * @see java.io.OutputStream#close() + */ + @Override + public void close() throws IOException + { + if (_closed) + return; + + if (_request.getAttribute("javax.servlet.include.request_uri") != null) + flush(); + else + { + if (_bOut != null) + { + if (_contentLength < 0) + _contentLength = _bOut.getCount(); + if (_contentLength < _minCompressSize) + doNotCompress(); + else + doCompress(); + } + else if (_out == null) + { + doNotCompress(); + } + + if (_compressedOutputStream != null) + _compressedOutputStream.close(); + else + _out.close(); + _closed = true; + } + } + + /** + * Finish. + * + * @throws IOException + * Signals that an I/O exception has occurred. + */ + public void finish() throws IOException + { + if (!_closed) + { + if (_out == null || _bOut != null) + { + if (_contentLength > 0 && _contentLength < _minCompressSize) + doNotCompress(); + else + doCompress(); + } + + if (_compressedOutputStream != null && !_closed) + { + _closed = true; + _compressedOutputStream.close(); + } + } + } + + /* ------------------------------------------------------------ */ + /** + * @see java.io.OutputStream#write(int) + */ + @Override + public void write(int b) throws IOException + { + checkOut(1); + _out.write(b); + } + + /* ------------------------------------------------------------ */ + /** + * @see java.io.OutputStream#write(byte[]) + */ + @Override + public void write(byte b[]) throws IOException + { + checkOut(b.length); + _out.write(b); + } + + /* ------------------------------------------------------------ */ + /** + * @see java.io.OutputStream#write(byte[], int, int) + */ + @Override + public void write(byte b[], int off, int len) throws IOException + { + checkOut(len); + _out.write(b,off,len); + } + + /** + * Do compress. + * + * @throws IOException Signals that an I/O exception has occurred. + */ + public void doCompress() throws IOException + { + if (_compressedOutputStream==null) + { + if (_response.isCommitted()) + throw new IllegalStateException(); + + if (setContentEncoding()) + { + _out=_compressedOutputStream=createStream(); + + if (_bOut!=null) + { + _out.write(_bOut.getBuf(),0,_bOut.getCount()); + _bOut=null; + } + } + else + doNotCompress(); + } + } + + /** + * Do not compress. + * + * @throws IOException + * Signals that an I/O exception has occurred. + */ + public void doNotCompress() throws IOException + { + if (_compressedOutputStream != null) + throw new IllegalStateException(); + if (_out == null || _bOut != null) + { + _doNotCompress = true; + + _out = _response.getOutputStream(); + setContentLength(_contentLength); + + if (_bOut != null) + _out.write(_bOut.getBuf(),0,_bOut.getCount()); + _bOut = null; + } + } + + /** + * Check out. + * + * @param length + * the length + * @throws IOException + * Signals that an I/O exception has occurred. + */ + private void checkOut(int length) throws IOException + { + if (_closed) + throw new IOException("CLOSED"); + + if (_out == null) + { + if (_response.isCommitted() || (_contentLength >= 0 && _contentLength < _minCompressSize)) + doNotCompress(); + else if (length > _minCompressSize) + doCompress(); + else + _out = _bOut = new ByteArrayOutputStream2(_bufferSize); + } + else if (_bOut != null) + { + if (_response.isCommitted() || (_contentLength >= 0 && _contentLength < _minCompressSize)) + doNotCompress(); + else if (length >= (_bOut.getBuf().length - _bOut.getCount())) + doCompress(); + } + } + + /** + * @see org.eclipse.jetty.http.gzip.CompressedStream#getOutputStream() + */ + public OutputStream getOutputStream() + { + return _out; + } + + /** + * @see org.eclipse.jetty.http.gzip.CompressedStream#isClosed() + */ + public boolean isClosed() + { + return _closed; + } + + /** + * Allows derived implementations to replace PrintWriter implementation. + */ + protected PrintWriter newWriter(OutputStream out, String encoding) throws UnsupportedEncodingException + { + return encoding == null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding)); + } + + /** + * Sets the content encoding. + * + * @return true, if successful + */ + protected abstract boolean setContentEncoding(); + + /** + * Create the stream fitting to the underlying compression type. + * + * @throws IOException + * Signals that an I/O exception has occurred. + */ + protected abstract DeflaterOutputStream createStream() throws IOException; + +} diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressedResponseWrapper.java b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressedResponseWrapper.java new file mode 100644 index 00000000000..14bdc6bb612 --- /dev/null +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressedResponseWrapper.java @@ -0,0 +1,58 @@ +// ======================================================================== +// Copyright (c) 2009-2009 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.http.gzip; + +import java.io.IOException; +import java.util.Set; + +import javax.servlet.http.HttpServletResponse; + +/* ------------------------------------------------------------ */ +/** + * A ResponseWrapper interface that adds compress functionality to a ResponseWrapper + */ +public interface CompressedResponseWrapper extends HttpServletResponse +{ + + /** + * Sets the mime types. + * + * @param mimeTypes + * the new mime types + */ + public void setMimeTypes(Set mimeTypes); + + /** + * Sets the min compress size. + * + * @param minCompressSize + * the new min compress size + */ + public void setMinCompressSize(int minCompressSize); + + /* ------------------------------------------------------------ */ + /** + * No compression. + */ + public void noCompression(); + + /** + * Finish. + * + * @throws IOException + * Signals that an I/O exception has occurred. + */ + public void finish() throws IOException; + +} \ No newline at end of file diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressedStream.java b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressedStream.java new file mode 100644 index 00000000000..751b2f05d1e --- /dev/null +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressedStream.java @@ -0,0 +1,77 @@ +// ======================================================================== +// Copyright (c) 2009-2009 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.http.gzip; + +import java.io.Closeable; +import java.io.Flushable; +import java.io.IOException; +import java.io.OutputStream; + +/* ------------------------------------------------------------ */ +/** +* Interface for compressed streams +*/ +public interface CompressedStream extends Closeable, Flushable +{ + + /** + * Reset buffer. + */ + public void resetBuffer(); + + /** + * Sets the content length. + * + * @param length + * the new content length + */ + public void setContentLength(long length); + + /* ------------------------------------------------------------ */ + /** + * @return true if stream is closed + */ + public boolean isClosed(); + + /** + * Do compress. + * + * @throws IOException + * Signals that an I/O exception has occurred. + */ + public void doCompress() throws IOException; + + /** + * Do not compress. + * + * @throws IOException + * Signals that an I/O exception has occurred. + */ + public void doNotCompress() throws IOException; + + /** + * Finish. + * + * @throws IOException + * Signals that an I/O exception has occurred. + */ + public void finish() throws IOException; + + /* ------------------------------------------------------------ */ + /** + * @return the {@link OutputStream} + */ + public OutputStream getOutputStream(); + +} \ No newline at end of file diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressionType.java b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressionType.java new file mode 100644 index 00000000000..4b75c2631d3 --- /dev/null +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressionType.java @@ -0,0 +1,48 @@ +// ======================================================================== +// Copyright (c) 2009-2009 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.http.gzip; + +public enum CompressionType +{ + GZIP("gzip"), DEFLATE("deflate"), UNSUPPORTED("unsupported"); + + private final String encodingHeader; + + private CompressionType(String encodingHeader) + { + this.encodingHeader = encodingHeader; + } + + public String getEncodingHeader() + { + return encodingHeader; + } + + public static CompressionType getByEncodingHeader(String encodingHeader) + { + // prefer gzip over deflate + if (encodingHeader.toLowerCase().contains(CompressionType.GZIP.encodingHeader)) + { + return CompressionType.GZIP; + } + else if (encodingHeader.toLowerCase().contains(CompressionType.DEFLATE.encodingHeader)) + { + return CompressionType.DEFLATE; + } + else + { + return CompressionType.UNSUPPORTED; + } + } +} \ No newline at end of file diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/DeflateResponseWrapperImpl.java b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/DeflateResponseWrapperImpl.java new file mode 100644 index 00000000000..9cf5fe02673 --- /dev/null +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/DeflateResponseWrapperImpl.java @@ -0,0 +1,54 @@ +// ======================================================================== +// Copyright (c) Webtide LLC +// ------------------------------------------------------------------------ +// 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.http.gzip; + +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/* ------------------------------------------------------------ */ +/** + */ +public class DeflateResponseWrapperImpl extends AbstractCompressedResponseWrapper +{ + /** + * Instantiates a new deflate response wrapper. + * + * @param request the request + * @param response the response + */ + public DeflateResponseWrapperImpl(HttpServletRequest request, HttpServletResponse response) + { + super(request,response); + } + + + /* ------------------------------------------------------------ */ + /** + * @param request the request + * @param response the response + * @param contentLength the content length + * @param bufferSize the buffer size + * @param minCompressSize the min compress size + * @return the deflate stream + * @throws IOException Signals that an I/O exception has occurred. + */ + @Override + protected CompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minCompressSize) throws IOException + { + return new DeflateStreamImpl(request,response,contentLength,bufferSize,minCompressSize); + } +} + diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/DeflateStreamImpl.java b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/DeflateStreamImpl.java new file mode 100644 index 00000000000..16e3d82750d --- /dev/null +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/DeflateStreamImpl.java @@ -0,0 +1,55 @@ +// ======================================================================== +// Copyright (c) Webtide LLC +// ------------------------------------------------------------------------ +// 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.http.gzip; + +import java.io.IOException; +import java.util.zip.DeflaterOutputStream; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + +/* ------------------------------------------------------------ */ +/** + * Compressed Stream implementation using deflate to compress + */ +public class DeflateStreamImpl extends AbstractCompressedStream implements CompressedStream +{ + public DeflateStreamImpl(HttpServletRequest request, HttpServletResponse response, long contentLength, int bufferSize, int minGzipSize) throws IOException + { + super(request,response,contentLength,bufferSize,minGzipSize); + } + + /** + * Sets the Content-Encoding header to deflate. + * + * @return true, if successful + */ + @Override + protected boolean setContentEncoding() + { + _response.setHeader("Content-Encoding", CompressionType.DEFLATE.getEncodingHeader()); + return _response.containsHeader("Content-Encoding"); + } + + /** + * @return a new DeflaterOutputStream backed by _response.getOutputStream() + */ + @Override + protected DeflaterOutputStream createStream() throws IOException + { + return new DeflaterOutputStream(_response.getOutputStream()); + } +} + diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipResponseWrapperImpl.java b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipResponseWrapperImpl.java new file mode 100644 index 00000000000..f434ad27c3f --- /dev/null +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipResponseWrapperImpl.java @@ -0,0 +1,53 @@ +// ======================================================================== +// Copyright (c) Webtide LLC +// ------------------------------------------------------------------------ +// 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.http.gzip; + +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/* ------------------------------------------------------------ */ +/** + */ +public class GzipResponseWrapperImpl extends AbstractCompressedResponseWrapper +{ + /** + * Instantiates a new gzip response wrapper. + * + * @param request the request + * @param response the response + */ + public GzipResponseWrapperImpl(HttpServletRequest request, HttpServletResponse response) + { + super(request,response); + } + + + /* ------------------------------------------------------------ */ + /** + * @param request the request + * @param response the response + * @param contentLength the content length + * @param bufferSize the buffer size + * @param minCompressSize the min gzip size + * @return the gzip stream + * @throws IOException Signals that an I/O exception has occurred. + */ + @Override + protected CompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minCompressSize) throws IOException + { + return new GzipStreamImpl(request,response,contentLength,bufferSize,minCompressSize); + } +} + diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipStream.java b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipStream.java deleted file mode 100644 index aa05a1920e7..00000000000 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipStream.java +++ /dev/null @@ -1,305 +0,0 @@ -// ======================================================================== -// Copyright (c) Webtide LLC -// ------------------------------------------------------------------------ -// 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.http.gzip; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; -import java.util.zip.GZIPOutputStream; - -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.util.ByteArrayOutputStream2; - - -/* ------------------------------------------------------------ */ -/** - */ -public class GzipStream extends ServletOutputStream -{ - protected HttpServletRequest _request; - protected HttpServletResponse _response; - protected OutputStream _out; - protected ByteArrayOutputStream2 _bOut; - protected GZIPOutputStream _gzOut; - protected boolean _closed; - protected int _bufferSize; - protected int _minGzipSize; - protected long _contentLength; - protected boolean _doNotGzip; - - /** - * Instantiates a new gzip stream. - * - * @param request the request - * @param response the response - * @param contentLength the content length - * @param bufferSize the buffer size - * @param minGzipSize the min gzip size - * @throws IOException Signals that an I/O exception has occurred. - */ - public GzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException - { - _request=request; - _response=response; - _contentLength=contentLength; - _bufferSize=bufferSize; - _minGzipSize=minGzipSize; - if (minGzipSize==0) - doGzip(); - } - - /** - * Reset buffer. - */ - public void resetBuffer() - { - if (_response.isCommitted()) - throw new IllegalStateException("Committed"); - _closed=false; - _out=null; - _bOut=null; - if (_gzOut!=null) - _response.setHeader("Content-Encoding",null); - _gzOut=null; - _doNotGzip=false; - } - - /** - * Sets the content length. - * - * @param length the new content length - */ - public void setContentLength(long length) - { - _contentLength=length; - if (_doNotGzip && length>=0) - { - if(_contentLength0 && _contentLength<_minGzipSize) - doNotGzip(); - else - doGzip(); - } - - _out.flush(); - } - - /* ------------------------------------------------------------ */ - /** - * @see java.io.OutputStream#close() - */ - public void close() throws IOException - { - if (_closed) - return; - - if (_request.getAttribute("javax.servlet.include.request_uri")!=null) - flush(); - else - { - if (_bOut!=null) - { - if (_contentLength<0) - _contentLength=_bOut.getCount(); - if (_contentLength<_minGzipSize) - doNotGzip(); - else - doGzip(); - } - else if (_out==null) - { - doNotGzip(); - } - - if (_gzOut!=null) - _gzOut.close(); - else - _out.close(); - _closed=true; - } - } - - /** - * Finish. - * - * @throws IOException Signals that an I/O exception has occurred. - */ - public void finish() throws IOException - { - if (!_closed) - { - if (_out==null || _bOut!=null) - { - if (_contentLength>0 && _contentLength<_minGzipSize) - doNotGzip(); - else - doGzip(); - } - - if (_gzOut!=null && !_closed) - { - _closed=true; - _gzOut.close(); - } - } - } - - /* ------------------------------------------------------------ */ - /** - * @see java.io.OutputStream#write(int) - */ - public void write(int b) throws IOException - { - checkOut(1); - _out.write(b); - } - - /* ------------------------------------------------------------ */ - /** - * @see java.io.OutputStream#write(byte[]) - */ - public void write(byte b[]) throws IOException - { - checkOut(b.length); - _out.write(b); - } - - /* ------------------------------------------------------------ */ - /** - * @see java.io.OutputStream#write(byte[], int, int) - */ - public void write(byte b[], int off, int len) throws IOException - { - checkOut(len); - _out.write(b,off,len); - } - - /** - * Sets the content encoding gzip. - * - * @return true, if successful - */ - protected boolean setContentEncodingGzip() - { - _response.setHeader("Content-Encoding", "gzip"); - return _response.containsHeader("Content-Encoding"); - } - - /** - * Do gzip. - * - * @throws IOException Signals that an I/O exception has occurred. - */ - public void doGzip() throws IOException - { - if (_gzOut==null) - { - if (_response.isCommitted()) - throw new IllegalStateException(); - - if (setContentEncodingGzip()) - { - _out=_gzOut=new GZIPOutputStream(_response.getOutputStream(),_bufferSize); - - if (_bOut!=null) - { - _out.write(_bOut.getBuf(),0,_bOut.getCount()); - _bOut=null; - } - } - else - doNotGzip(); - } - } - - /** - * Do not gzip. - * - * @throws IOException Signals that an I/O exception has occurred. - */ - public void doNotGzip() throws IOException - { - if (_gzOut!=null) - throw new IllegalStateException(); - if (_out==null || _bOut!=null ) - { - _doNotGzip = true; - - _out=_response.getOutputStream(); - setContentLength(_contentLength); - - if (_bOut!=null) - _out.write(_bOut.getBuf(),0,_bOut.getCount()); - _bOut=null; - } - } - - /** - * Check out. - * - * @param length the length - * @throws IOException Signals that an I/O exception has occurred. - */ - private void checkOut(int length) throws IOException - { - if (_closed) - throw new IOException("CLOSED"); - - if (_out==null) - { - if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize)) - doNotGzip(); - else if (length>_minGzipSize) - doGzip(); - else - _out=_bOut=new ByteArrayOutputStream2(_bufferSize); - } - else if (_bOut!=null) - { - if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize)) - doNotGzip(); - else if (length>=(_bOut.getBuf().length -_bOut.getCount())) - doGzip(); - } - } - - /** - * Allows derived implementations to replace PrintWriter implementation. - */ - protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException - { - return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding)); - } -} - diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipStreamImpl.java b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipStreamImpl.java new file mode 100644 index 00000000000..218aebca38d --- /dev/null +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipStreamImpl.java @@ -0,0 +1,56 @@ +// ======================================================================== +// Copyright (c) Webtide LLC +// ------------------------------------------------------------------------ +// 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.http.gzip; + +import java.io.IOException; +import java.util.zip.DeflaterOutputStream; +import java.util.zip.GZIPOutputStream; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + +/* ------------------------------------------------------------ */ +/** + * Compressed Stream implementation using gzip to compress + */ +public class GzipStreamImpl extends AbstractCompressedStream implements CompressedStream +{ + public GzipStreamImpl(HttpServletRequest request, HttpServletResponse response, long contentLength, int bufferSize, int minGzipSize) throws IOException + { + super(request,response,contentLength,bufferSize,minGzipSize); + } + + /** + * Sets the Content-Encoding header to gzip. + * + * @return true, if successful + */ + @Override + protected boolean setContentEncoding() + { + _response.setHeader("Content-Encoding", CompressionType.GZIP.getEncodingHeader()); + return _response.containsHeader("Content-Encoding"); + } + + /** + * @return a new GZIPOutputStream backed by _response.getOutputStream() + */ + @Override + protected DeflaterOutputStream createStream() throws IOException + { + return new GZIPOutputStream(_response.getOutputStream(),_bufferSize); + } +} + diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java index 81198f5299d..83bd42e152b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java @@ -30,7 +30,7 @@ import org.eclipse.jetty.continuation.Continuation; import org.eclipse.jetty.continuation.ContinuationListener; import org.eclipse.jetty.continuation.ContinuationSupport; import org.eclipse.jetty.http.HttpMethods; -import org.eclipse.jetty.http.gzip.GzipResponseWrapper; +import org.eclipse.jetty.http.gzip.GzipResponseWrapperImpl; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -222,7 +222,7 @@ public class GzipHandler extends HandlerWrapper } } - final GzipResponseWrapper wrappedResponse = newGzipResponseWrapper(request,response); + final GzipResponseWrapperImpl wrappedResponse = newGzipResponseWrapper(request,response); boolean exceptional=true; try @@ -256,7 +256,7 @@ public class GzipHandler extends HandlerWrapper else if (exceptional && !response.isCommitted()) { wrappedResponse.resetBuffer(); - wrappedResponse.noGzip(); + wrappedResponse.noCompression(); } else wrappedResponse.finish(); @@ -276,14 +276,14 @@ public class GzipHandler extends HandlerWrapper * @param response the response * @return the gzip response wrapper */ - protected GzipResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response) + protected GzipResponseWrapperImpl newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response) { - return new GzipResponseWrapper(request, response) + return new GzipResponseWrapperImpl(request, response) { { super.setMimeTypes(GzipHandler.this._mimeTypes); super.setBufferSize(GzipHandler.this._bufferSize); - super.setMinGzipSize(GzipHandler.this._minGzipSize); + super.setMinCompressSize(GzipHandler.this._minGzipSize); } @Override diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java index 1b993e6eedf..266b71887bc 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java @@ -13,10 +13,6 @@ package org.eclipse.jetty.servlets; import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; import java.util.HashSet; import java.util.Set; import java.util.StringTokenizer; @@ -34,14 +30,18 @@ import org.eclipse.jetty.continuation.Continuation; import org.eclipse.jetty.continuation.ContinuationListener; import org.eclipse.jetty.continuation.ContinuationSupport; import org.eclipse.jetty.http.HttpMethods; -import org.eclipse.jetty.http.gzip.GzipResponseWrapper; +import org.eclipse.jetty.http.gzip.CompressedResponseWrapper; +import org.eclipse.jetty.http.gzip.CompressionType; +import org.eclipse.jetty.http.gzip.DeflateResponseWrapperImpl; +import org.eclipse.jetty.http.gzip.GzipResponseWrapperImpl; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; /* ------------------------------------------------------------ */ /** GZIP Filter - * This filter will gzip the content of a response iff:
    + * This filter will gzip or deflate the content of a response if:
      *
    • The filter is mapped to a matching path
    • + *
    • accept-encoding header is set to either gzip, deflate or a combination of those
    • *
    • The response status code is >=200 and <300 *
    • The content length is unknown or more than the minGzipSize initParameter or the minGzipSize is 0(default)
    • *
    • The content-type is in the comma separated list of mimeTypes set in the mimeTypes initParameter or @@ -50,8 +50,11 @@ import org.eclipse.jetty.util.log.Logger; *
    * *

    + * If both gzip and deflate are specified in the accept-encoding header, then gzip will be used. + *

    + *

    * Compressing the content can greatly improve the network bandwidth usage, but at a cost of memory and - * CPU cycles. If this filter is mapped for static content, then use of efficient direct NIO may be + * CPU cycles. If this filter is mapped for static content, then use of efficient direct NIO may be * prevented, thus use of the gzip mechanism of the {@link org.eclipse.jetty.servlet.DefaultServlet} is * advised instead. *

    @@ -157,7 +160,8 @@ public class GzipFilter extends UserAgentFilter HttpServletResponse response=(HttpServletResponse)res; String ae = request.getHeader("accept-encoding"); - if (ae != null && ae.indexOf("gzip")>=0 && !response.containsHeader("Content-Encoding") + CompressionType compressionType = CompressionType.getByEncodingHeader(ae); + if (ae != null && !compressionType.equals(CompressionType.UNSUPPORTED) && !response.containsHeader("Content-Encoding") && !HttpMethods.HEAD.equalsIgnoreCase(request.getMethod())) { String ua = getUserAgent(request); @@ -172,8 +176,8 @@ public class GzipFilter extends UserAgentFilter super.doFilter(request,response,chain); return; } - - final GzipResponseWrapper wrappedResponse=newGzipResponseWrapper(request,response); + + CompressedResponseWrapper wrappedResponse = createWrappedResponse(request,response,compressionType); boolean exceptional=true; try @@ -186,28 +190,12 @@ public class GzipFilter extends UserAgentFilter Continuation continuation = ContinuationSupport.getContinuation(request); if (continuation.isSuspended() && continuation.isResponseWrapped()) { - continuation.addContinuationListener(new ContinuationListener() - { - public void onComplete(Continuation continuation) - { - try - { - wrappedResponse.finish(); - } - catch(IOException e) - { - LOG.warn(e); - } - } - - public void onTimeout(Continuation continuation) - {} - }); + continuation.addContinuationListener(new ContinuationListenerWaitingForWrappedResponseToFinish(wrappedResponse)); } else if (exceptional && !response.isCommitted()) { wrappedResponse.resetBuffer(); - wrappedResponse.noGzip(); + wrappedResponse.noCompression(); } else wrappedResponse.finish(); @@ -218,7 +206,59 @@ public class GzipFilter extends UserAgentFilter super.doFilter(request,response,chain); } } + + protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, CompressionType compressionType) + { + CompressedResponseWrapper wrappedResponse = null; + if (compressionType.equals(CompressionType.GZIP)) + { + wrappedResponse = new GzipResponseWrapperImpl(request,response); + } + else if (compressionType.equals(CompressionType.DEFLATE)) + { + wrappedResponse = new DeflateResponseWrapperImpl(request,response); + } + else + { + throw new IllegalStateException(compressionType + " not supported"); + } + configureWrappedResponse(wrappedResponse); + return wrappedResponse; + } + + private void configureWrappedResponse(CompressedResponseWrapper wrappedResponse) + { + wrappedResponse.setMimeTypes(_mimeTypes); + wrappedResponse.setBufferSize(_bufferSize); + wrappedResponse.setMinCompressSize(_minGzipSize); + } + private class ContinuationListenerWaitingForWrappedResponseToFinish implements ContinuationListener{ + + private CompressedResponseWrapper wrappedResponse; + + public ContinuationListenerWaitingForWrappedResponseToFinish(CompressedResponseWrapper wrappedResponse) + { + this.wrappedResponse = wrappedResponse; + } + + public void onComplete(Continuation continuation) + { + try + { + wrappedResponse.finish(); + } + catch (IOException e) + { + LOG.warn(e); + } + } + + public void onTimeout(Continuation continuation) + { + } + } + /** * Checks to see if the UserAgent is excluded * @@ -275,42 +315,4 @@ public class GzipFilter extends UserAgentFilter } return false; } - - /** - * Allows derived implementations to replace ResponseWrapper implementation. - * - * @param request the request - * @param response the response - * @return the gzip response wrapper - */ - protected GzipResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response) - { - return new GzipResponseWrapper(request, response) - { - { - setMimeTypes(GzipFilter.this._mimeTypes); - setBufferSize(GzipFilter.this._bufferSize); - setMinGzipSize(GzipFilter.this._minGzipSize); - } - - @Override - protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException - { - return GzipFilter.this.newWriter(out,encoding); - } - }; - } - - /** - * Allows derived implementations to replace PrintWriter implementation. - * - * @param out the out - * @param encoding the encoding - * @return the prints the writer - * @throws UnsupportedEncodingException - */ - protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException - { - return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding)); - } } 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 7d9a24ac58a..a325dee3a99 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 @@ -24,12 +24,14 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.http.gzip.GzipResponseWrapper; -import org.eclipse.jetty.http.gzip.GzipStream; +import org.eclipse.jetty.http.gzip.CompressedResponseWrapper; +import org.eclipse.jetty.http.gzip.CompressedStream; +import org.eclipse.jetty.http.gzip.CompressionType; +import org.eclipse.jetty.http.gzip.DeflateStreamImpl; +import org.eclipse.jetty.http.gzip.GzipResponseWrapperImpl; +import org.eclipse.jetty.http.gzip.GzipStreamImpl; import org.eclipse.jetty.io.UncheckedPrintWriter; - - /* ------------------------------------------------------------ */ /** Includable GZip Filter. * This extension to the {@link GzipFilter} that uses Jetty features to allow @@ -57,36 +59,52 @@ public class IncludableGzipFilter extends GzipFilter } @Override - protected GzipResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response) + protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, CompressionType compressionType) { return new IncludableResponseWrapper(request,response); } - public class IncludableResponseWrapper extends GzipResponseWrapper + public class IncludableResponseWrapper extends GzipResponseWrapperImpl { public IncludableResponseWrapper(HttpServletRequest request, HttpServletResponse response) { super(request,response); - + super.setMimeTypes(IncludableGzipFilter.this._mimeTypes); super.setBufferSize(IncludableGzipFilter.this._bufferSize); - super.setMinGzipSize(IncludableGzipFilter.this._minGzipSize); + super.setMinCompressSize(IncludableGzipFilter.this._minGzipSize); } @Override - protected GzipStream newGzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException + protected CompressedStream newCompressedStream(HttpServletRequest request, HttpServletResponse response, long contentLength, int bufferSize, + int minGzipSize) throws IOException { - return new IncludableGzipStream(request,response,contentLength,bufferSize,minGzipSize); + String encodingHeader = request.getHeader("accept-encoding"); + CompressionType compressionType = CompressionType.getByEncodingHeader(encodingHeader); + if (compressionType.equals(CompressionType.GZIP)) + { + return new IncludableGzipStream(request,response,contentLength,bufferSize,minGzipSize); + } + else if (compressionType.equals(CompressionType.DEFLATE)) + { + return new IncludableDeflateStream(request,response,contentLength,bufferSize,minGzipSize); + } + else + { + throw new IllegalStateException(compressionType.name() + " not supported."); + } } @Override - protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException + protected PrintWriter newWriter(OutputStream out, String encoding) throws UnsupportedEncodingException { - return IncludableGzipFilter.this.newWriter(out,encoding); + if (_uncheckedPrintWriter) + return encoding == null?new UncheckedPrintWriter(out):new UncheckedPrintWriter(new OutputStreamWriter(out,encoding)); + return super.newWriter(out,encoding); } } - - public class IncludableGzipStream extends GzipStream + + public class IncludableGzipStream extends GzipStreamImpl { public IncludableGzipStream(HttpServletRequest request, HttpServletResponse response, long contentLength, int bufferSize, int minGzipSize) throws IOException @@ -95,22 +113,43 @@ public class IncludableGzipFilter extends GzipFilter } @Override - protected boolean setContentEncodingGzip() + protected boolean setContentEncoding() { - if (_request.getAttribute("javax.servlet.include.request_uri")!=null) - _response.setHeader("org.eclipse.jetty.server.include.Content-Encoding", "gzip"); + if (_request.getAttribute("javax.servlet.include.request_uri") != null) + { + _response.setHeader("org.eclipse.jetty.server.include.Content-Encoding","gzip"); + } else - _response.setHeader("Content-Encoding", "gzip"); - + { + _response.setHeader("Content-Encoding","gzip"); + } + return _response.containsHeader("Content-Encoding"); } } - @Override - protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException + public class IncludableDeflateStream extends DeflateStreamImpl { - if (_uncheckedPrintWriter) - return encoding==null?new UncheckedPrintWriter(out):new UncheckedPrintWriter(new OutputStreamWriter(out,encoding)); - return super.newWriter(out,encoding); + public IncludableDeflateStream(HttpServletRequest request, HttpServletResponse response, long contentLength, int bufferSize, int minGzipSize) + throws IOException + { + super(request,response,contentLength,bufferSize,minGzipSize); + } + + @Override + protected boolean setContentEncoding() + { + if (_request.getAttribute("javax.servlet.include.request_uri") != null) + { + _response.setHeader("org.eclipse.jetty.server.include.Content-Encoding","deflate"); + } + else + { + _response.setHeader("Content-Encoding","deflate"); + } + + return _response.containsHeader("Content-Encoding"); + } } + } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterContentLengthTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterContentLengthTest.java index 109fe2675f2..b636583c716 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterContentLengthTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterContentLengthTest.java @@ -6,7 +6,8 @@ import java.util.List; import javax.servlet.Servlet; import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.http.gzip.GzipResponseWrapper; +import org.eclipse.jetty.http.gzip.CompressionType; +import org.eclipse.jetty.http.gzip.GzipResponseWrapperImpl; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlets.gzip.GzipTester; import org.eclipse.jetty.servlets.gzip.TestServletLengthStreamTypeWrite; @@ -48,32 +49,42 @@ public class GzipFilterContentLengthTest { return Arrays.asList(new Object[][] { - { TestServletLengthStreamTypeWrite.class }, - { TestServletLengthTypeStreamWrite.class }, - { TestServletStreamLengthTypeWrite.class }, - { TestServletStreamTypeLengthWrite.class }, - { TestServletTypeLengthStreamWrite.class }, - { TestServletTypeStreamLengthWrite.class } }); + { TestServletLengthStreamTypeWrite.class, CompressionType.GZIP }, + { TestServletLengthTypeStreamWrite.class, CompressionType.GZIP }, + { TestServletStreamLengthTypeWrite.class, CompressionType.GZIP }, + { TestServletStreamTypeLengthWrite.class, CompressionType.GZIP }, + { TestServletTypeLengthStreamWrite.class, CompressionType.GZIP }, + { TestServletTypeStreamLengthWrite.class, CompressionType.GZIP }, + { TestServletLengthStreamTypeWrite.class, CompressionType.DEFLATE }, + { TestServletLengthTypeStreamWrite.class, CompressionType.DEFLATE }, + { TestServletStreamLengthTypeWrite.class, CompressionType.DEFLATE }, + { TestServletStreamTypeLengthWrite.class, CompressionType.DEFLATE }, + { TestServletTypeLengthStreamWrite.class, CompressionType.DEFLATE }, + { TestServletTypeStreamLengthWrite.class, CompressionType.DEFLATE } + }); } - private static final int LARGE = GzipResponseWrapper.DEFAULT_BUFFER_SIZE * 8; - private static final int MEDIUM = GzipResponseWrapper.DEFAULT_BUFFER_SIZE; - private static final int SMALL = GzipResponseWrapper.DEFAULT_BUFFER_SIZE / 4; - private static final int TINY = GzipResponseWrapper.DEFAULT_MIN_GZIP_SIZE / 2; + private static final int LARGE = GzipResponseWrapperImpl.DEFAULT_BUFFER_SIZE * 8; + private static final int MEDIUM = GzipResponseWrapperImpl.DEFAULT_BUFFER_SIZE; + private static final int SMALL = GzipResponseWrapperImpl.DEFAULT_BUFFER_SIZE / 4; + private static final int TINY = GzipResponseWrapperImpl.DEFAULT_MIN_COMPRESS_SIZE/ 2; + + private CompressionType compressionType; + public GzipFilterContentLengthTest(Class testServlet, CompressionType compressionType) + { + this.testServlet = testServlet; + this.compressionType = compressionType; + } + @Rule public TestingDir testingdir = new TestingDir(); private Class testServlet; - public GzipFilterContentLengthTest(Class testServlet) - { - this.testServlet = testServlet; - } - private void assertIsGzipCompressed(String filename, int filesize) throws Exception { - GzipTester tester = new GzipTester(testingdir); + GzipTester tester = new GzipTester(testingdir, compressionType); File testfile = tester.prepareServerFile(testServlet.getSimpleName() + "-" + filename,filesize); @@ -93,7 +104,7 @@ public class GzipFilterContentLengthTest private void assertIsNotGzipCompressed(String filename, int filesize) throws Exception { - GzipTester tester = new GzipTester(testingdir); + GzipTester tester = new GzipTester(testingdir, compressionType); File testfile = tester.prepareServerFile(testServlet.getSimpleName() + "-" + filename,filesize); diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultNoRecompressTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultNoRecompressTest.java index ec5aab410be..996e26a0547 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultNoRecompressTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultNoRecompressTest.java @@ -5,6 +5,7 @@ import java.io.IOException; import java.util.Arrays; import java.util.List; +import org.eclipse.jetty.http.gzip.CompressionType; import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlets.gzip.GzipTester; @@ -31,22 +32,41 @@ public class GzipFilterDefaultNoRecompressTest return Arrays.asList(new Object[][] { // Some already compressed files - { "test_quotes.gz", "application/gzip" }, - { "test_quotes.bz2", "application/bzip2" }, - { "test_quotes.zip", "application/zip" }, - { "test_quotes.rar", "application/octet-stream" }, + { "test_quotes.gz", "application/gzip", CompressionType.GZIP }, + { "test_quotes.bz2", "application/bzip2", CompressionType.GZIP }, + { "test_quotes.zip", "application/zip", CompressionType.GZIP }, + { "test_quotes.rar", "application/octet-stream", CompressionType.GZIP }, // Some images (common first) - { "jetty_logo.png", "image/png" }, - { "jetty_logo.gif", "image/gif" }, - { "jetty_logo.jpeg", "image/jpeg" }, - { "jetty_logo.jpg", "image/jpeg" }, + { "jetty_logo.png", "image/png", CompressionType.GZIP }, + { "jetty_logo.gif", "image/gif", CompressionType.GZIP }, + { "jetty_logo.jpeg", "image/jpeg", CompressionType.GZIP }, + { "jetty_logo.jpg", "image/jpeg", CompressionType.GZIP }, // Lesser encountered images (usually found being requested from non-browser clients) - { "jetty_logo.bmp", "image/bmp" }, - { "jetty_logo.tga", "application/tga" }, - { "jetty_logo.tif", "image/tiff" }, - { "jetty_logo.tiff", "image/tiff" }, - { "jetty_logo.xcf", "image/xcf" }, - { "jetty_logo.jp2", "image/jpeg2000" } }); + { "jetty_logo.bmp", "image/bmp", CompressionType.GZIP }, + { "jetty_logo.tga", "application/tga", CompressionType.GZIP }, + { "jetty_logo.tif", "image/tiff", CompressionType.GZIP }, + { "jetty_logo.tiff", "image/tiff", CompressionType.GZIP }, + { "jetty_logo.xcf", "image/xcf", CompressionType.GZIP }, + { "jetty_logo.jp2", "image/jpeg2000", CompressionType.GZIP }, + + // Same tests again for deflate + // Some already compressed files + { "test_quotes.gz", "application/gzip", CompressionType.DEFLATE }, + { "test_quotes.bz2", "application/bzip2", CompressionType.DEFLATE }, + { "test_quotes.zip", "application/zip", CompressionType.DEFLATE }, + { "test_quotes.rar", "application/octet-stream", CompressionType.DEFLATE }, + // Some images (common first) + { "jetty_logo.png", "image/png", CompressionType.DEFLATE }, + { "jetty_logo.gif", "image/gif", CompressionType.DEFLATE }, + { "jetty_logo.jpeg", "image/jpeg", CompressionType.DEFLATE }, + { "jetty_logo.jpg", "image/jpeg", CompressionType.DEFLATE }, + // Lesser encountered images (usually found being requested from non-browser clients) + { "jetty_logo.bmp", "image/bmp", CompressionType.DEFLATE }, + { "jetty_logo.tga", "application/tga", CompressionType.DEFLATE }, + { "jetty_logo.tif", "image/tiff", CompressionType.DEFLATE }, + { "jetty_logo.tiff", "image/tiff", CompressionType.DEFLATE }, + { "jetty_logo.xcf", "image/xcf", CompressionType.DEFLATE }, + { "jetty_logo.jp2", "image/jpeg2000", CompressionType.DEFLATE } }); } @Rule @@ -54,17 +74,19 @@ public class GzipFilterDefaultNoRecompressTest private String alreadyCompressedFilename; private String expectedContentType; + private CompressionType compressionType; - public GzipFilterDefaultNoRecompressTest(String testFilename, String expectedContentType) + public GzipFilterDefaultNoRecompressTest(String testFilename, String expectedContentType, CompressionType compressionType) { this.alreadyCompressedFilename = testFilename; this.expectedContentType = expectedContentType; + this.compressionType = compressionType; } @Test public void testNotGzipFiltered_Default_AlreadyCompressed() throws Exception { - GzipTester tester = new GzipTester(testingdir); + GzipTester tester = new GzipTester(testingdir, compressionType); copyTestFileToServer(alreadyCompressedFilename); diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java index 82fd54dc11f..47f637150cd 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java @@ -1,6 +1,8 @@ package org.eclipse.jetty.servlets; import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -8,23 +10,48 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.http.gzip.GzipResponseWrapper; +import org.eclipse.jetty.http.gzip.CompressionType; +import org.eclipse.jetty.http.gzip.GzipResponseWrapperImpl; import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlets.gzip.GzipTester; import org.eclipse.jetty.toolchain.test.TestingDir; import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; /** * Test the GzipFilter support built into the {@link DefaultServlet} */ +@RunWith(Parameterized.class) public class GzipFilterDefaultTest { + @Parameters + public static Collection data() + { + CompressionType[][] data = new CompressionType[][] + { + { CompressionType.GZIP }, + { CompressionType.DEFLATE } + }; + + return Arrays.asList(data); + } + + private CompressionType compressionType; + + public GzipFilterDefaultTest(CompressionType compressionType) + { + this.compressionType = compressionType; + } public static class HttpStatusServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + private int _status = 204; public HttpStatusServlet() @@ -50,10 +77,10 @@ public class GzipFilterDefaultTest @Test public void testIsGzipCompressedTiny() throws Exception { - GzipTester tester = new GzipTester(testingdir); + GzipTester tester = new GzipTester(testingdir, compressionType); // Test content that is smaller than the buffer. - int filesize = GzipResponseWrapper.DEFAULT_BUFFER_SIZE / 4; + int filesize = GzipResponseWrapperImpl.DEFAULT_BUFFER_SIZE / 4; tester.prepareServerFile("file.txt",filesize); FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class); @@ -73,10 +100,10 @@ public class GzipFilterDefaultTest @Test public void testIsGzipCompressedLarge() throws Exception { - GzipTester tester = new GzipTester(testingdir); + GzipTester tester = new GzipTester(testingdir, compressionType); // Test content that is smaller than the buffer. - int filesize = GzipResponseWrapper.DEFAULT_BUFFER_SIZE * 4; + int filesize = GzipResponseWrapperImpl.DEFAULT_BUFFER_SIZE * 4; tester.prepareServerFile("file.txt",filesize); FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class); @@ -96,10 +123,10 @@ public class GzipFilterDefaultTest @Test public void testIsNotGzipCompressed() throws Exception { - GzipTester tester = new GzipTester(testingdir); + GzipTester tester = new GzipTester(testingdir, compressionType); // Test content that is smaller than the buffer. - int filesize = GzipResponseWrapper.DEFAULT_BUFFER_SIZE * 4; + int filesize = GzipResponseWrapperImpl.DEFAULT_BUFFER_SIZE * 4; tester.prepareServerFile("file.mp3",filesize); FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class); @@ -119,7 +146,7 @@ public class GzipFilterDefaultTest @Test public void testIsNotGzipCompressedHttpStatus() throws Exception { - GzipTester tester = new GzipTester(testingdir); + GzipTester tester = new GzipTester(testingdir, compressionType); // Test error code 204 FilterHolder holder = tester.setContentServlet(HttpStatusServlet.class); @@ -140,13 +167,13 @@ public class GzipFilterDefaultTest @Test public void testUserAgentExclusion() throws Exception { - GzipTester tester = new GzipTester(testingdir); + GzipTester tester = new GzipTester(testingdir, compressionType); FilterHolder holder = tester.setContentServlet(DefaultServlet.class); holder.setInitParameter("excludedAgents", "foo"); tester.setUserAgent("foo"); - int filesize = GzipResponseWrapper.DEFAULT_BUFFER_SIZE * 4; + int filesize = GzipResponseWrapperImpl.DEFAULT_BUFFER_SIZE * 4; tester.prepareServerFile("file.txt",filesize); try diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipWithPipeliningTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipWithPipeliningTest.java index b6a030ab894..65a66898fc4 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipWithPipeliningTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipWithPipeliningTest.java @@ -1,18 +1,24 @@ package org.eclipse.jetty.servlets; import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.net.URI; import java.security.DigestOutputStream; import java.security.MessageDigest; +import java.util.Arrays; +import java.util.Collection; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.GZIPInputStream; +import java.util.zip.InflaterInputStream; +import org.eclipse.jetty.http.gzip.CompressionType; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.DefaultServlet; @@ -25,21 +31,46 @@ import org.eclipse.jetty.toolchain.test.IO; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.TestingDir; import org.junit.After; -import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; /** * Test the effects of Gzip filtering when in the context of HTTP/1.1 Pipelining. */ +@RunWith(Parameterized.class) public class GzipWithPipeliningTest { + @Parameters + public static Collection data() + { + // Test different Content-Encoding header combinations. So implicitly testing that gzip is preferred oder deflate + String[][] data = new String[][] + { + { CompressionType.GZIP.getEncodingHeader() }, + { CompressionType.DEFLATE.getEncodingHeader() + ", " + CompressionType.GZIP.getEncodingHeader() }, + { CompressionType.GZIP.getEncodingHeader() + ", " + CompressionType.DEFLATE.getEncodingHeader() }, + { CompressionType.DEFLATE.getEncodingHeader() } + }; + + return Arrays.asList(data); + } + @Rule public TestingDir testingdir = new TestingDir(); private Server server; private URI serverUri; + private String encodingHeader; + + + public GzipWithPipeliningTest(String encodingHeader) + { + this.encodingHeader = encodingHeader; + } @Before public void startServer() throws Exception @@ -86,7 +117,7 @@ public class GzipWithPipeliningTest testingdir.ensureEmpty(); File outputDir = testingdir.getDir(); - PipelineHelper client = new PipelineHelper(serverUri); + PipelineHelper client = new PipelineHelper(serverUri, encodingHeader); try { @@ -95,7 +126,7 @@ public class GzipWithPipeliningTest // Size of content, as it exists on disk, without gzip compression. long rawsize = txtFile.length() + pngFile.length(); - Assert.assertThat("Ensure that we have sufficient file size to trigger chunking",rawsize,greaterThan(300000L)); + assertThat("Ensure that we have sufficient file size to trigger chunking",rawsize,greaterThan(300000L)); String respHeader; @@ -106,8 +137,9 @@ public class GzipWithPipeliningTest respHeader = client.readResponseHeader(); System.out.println("Response Header #1 --\n" + respHeader); - Assert.assertThat("Content-Encoding should be gzipped",respHeader,containsString("Content-Encoding: gzip\r\n")); - Assert.assertThat("Transfer-Encoding should be chunked",respHeader,containsString("Transfer-Encoding: chunked\r\n")); + String expectedEncodingHeader = encodingHeader.equals(CompressionType.DEFLATE.getEncodingHeader()) ? CompressionType.DEFLATE.getEncodingHeader() : CompressionType.GZIP.getEncodingHeader(); + assertThat("Content-Encoding should be gzipped",respHeader,containsString("Content-Encoding: " + expectedEncodingHeader + "\r\n")); + assertThat("Transfer-Encoding should be chunked",respHeader,containsString("Transfer-Encoding: chunked\r\n")); // Raw output / gzipped, writted to disk (checked for sha1sum later) File rawOutputFile = new File(outputDir, "response-1.gz"); @@ -118,7 +150,7 @@ public class GzipWithPipeliningTest // Read only 20% - intentionally a partial read. System.out.println("Attempting to read partial content ..."); - int readBytes = client.readBody(rawOutputStream,(int)((float)chunkSize * 0.20f)); + int readBytes = client.readBody(rawOutputStream,(int)(chunkSize * 0.20f)); System.out.printf("Read %,d bytes%n",readBytes); // Issue another request @@ -133,14 +165,14 @@ public class GzipWithPipeliningTest readBytes = client.readBody(rawOutputStream,(int)chunkSize); System.out.printf("Read %,d bytes%n",readBytes); line = client.readLine(); - Assert.assertThat("Chunk delim should be an empty line with CR+LF",line,is("")); + assertThat("Chunk delim should be an empty line with CR+LF",line,is("")); chunkSize = client.readChunkSize(); System.out.printf("Next Chunk: (0x%X) %,d bytes%n",chunkSize,chunkSize); } // Inter-pipeline delim line = client.readLine(); - Assert.assertThat("Inter-pipeline delim should be an empty line with CR+LF",line,is("")); + assertThat("Inter-pipeline delim should be an empty line with CR+LF",line,is("")); // Sha1tracking for 1st Request MessageDigest digestTxt = MessageDigest.getInstance("SHA1"); @@ -149,14 +181,23 @@ public class GzipWithPipeliningTest // Decompress 1st request and calculate sha1sum IO.close(rawOutputStream); FileInputStream rawInputStream = new FileInputStream(rawOutputFile); - GZIPInputStream ungzipStream = new GZIPInputStream(rawInputStream); - IO.copy(ungzipStream, digesterTxt); + InputStream uncompressedStream = null; + if (CompressionType.DEFLATE.getEncodingHeader().equals(encodingHeader)) + { + uncompressedStream = new InflaterInputStream(rawInputStream); + } + else + { + uncompressedStream = new GZIPInputStream(rawInputStream); + } + + IO.copy(uncompressedStream, digesterTxt); // Read 2nd request http response header respHeader = client.readResponseHeader(); System.out.println("Response Header #2 --\n" + respHeader); - Assert.assertThat("Content-Encoding should NOT be gzipped",respHeader,not(containsString("Content-Encoding: gzip\r\n"))); - Assert.assertThat("Transfer-Encoding should NOT be chunked",respHeader,not(containsString("Transfer-Encoding: chunked\r\n"))); + assertThat("Content-Encoding should NOT be gzipped",respHeader,not(containsString("Content-Encoding: gzip\r\n"))); + assertThat("Transfer-Encoding should NOT be chunked",respHeader,not(containsString("Transfer-Encoding: chunked\r\n"))); // Sha1tracking for 2nd Request MessageDigest digestImg = MessageDigest.getInstance("SHA1"); @@ -164,7 +205,7 @@ public class GzipWithPipeliningTest // Read 2nd request body int contentLength = client.getContentLength(respHeader); - Assert.assertThat("Image Content Length",(long)contentLength,is(pngFile.length())); + assertThat("Image Content Length",(long)contentLength,is(pngFile.length())); client.readBody(digesterImg,contentLength); // Validate checksums @@ -183,7 +224,7 @@ public class GzipWithPipeliningTest { String expectedSha1 = loadSha1sum(testResourceFile + ".sha1"); String actualSha1 = Hex.asHex(digest.digest()); - Assert.assertEquals(testResourceFile + " / SHA1Sum of content",expectedSha1,actualSha1); + assertEquals(testResourceFile + " / SHA1Sum of content",expectedSha1,actualSha1); } private String loadSha1sum(String testResourceSha1Sum) throws IOException @@ -192,7 +233,7 @@ public class GzipWithPipeliningTest String contents = IO.readToString(sha1File); Pattern pat = Pattern.compile("^[0-9A-Fa-f]*"); Matcher mat = pat.matcher(contents); - Assert.assertTrue("Should have found HEX code in SHA1 file: " + sha1File,mat.find()); + assertTrue("Should have found HEX code in SHA1 file: " + sha1File,mat.find()); return mat.group(); } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterMinSizeTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterMinSizeTest.java index 6e37eb311fb..e12abff667a 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterMinSizeTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterMinSizeTest.java @@ -13,14 +13,21 @@ package org.eclipse.jetty.servlets; +import java.util.Arrays; +import java.util.Collection; + import javax.servlet.Servlet; +import org.eclipse.jetty.http.gzip.CompressionType; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlets.gzip.GzipTester; import org.eclipse.jetty.servlets.gzip.TestMinGzipSizeServlet; import org.eclipse.jetty.toolchain.test.TestingDir; import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; /** * Perform specific tests on the IncludableGzipFilter's ability to manage @@ -28,17 +35,36 @@ import org.junit.Test; * * @see http://bugs.eclipse.org/366106 */ +@RunWith(Parameterized.class) public class IncludableGzipFilterMinSizeTest { + @Parameters + public static Collection data() + { + CompressionType[][] data = new CompressionType[][] + { + { CompressionType.GZIP }, + { CompressionType.DEFLATE } + }; + + return Arrays.asList(data); + } + + public IncludableGzipFilterMinSizeTest(CompressionType compressionType) + { + this.compressionType = compressionType; + } + @Rule public TestingDir testdir = new TestingDir(); + private CompressionType compressionType; private Class testServlet = TestMinGzipSizeServlet.class; @Test public void testUnderMinSize() throws Exception { - GzipTester tester = new GzipTester(testdir); + GzipTester tester = new GzipTester(testdir, compressionType); // Use IncludableGzipFilter tester.setGzipFilterClass(IncludableGzipFilter.class); @@ -64,7 +90,7 @@ public class IncludableGzipFilterMinSizeTest @Test public void testOverMinSize() throws Exception { - GzipTester tester = new GzipTester(testdir); + GzipTester tester = new GzipTester(testdir, compressionType); // Use IncludableGzipFilter tester.setGzipFilterClass(IncludableGzipFilter.class); diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java index 63b0dd9d262..49459e4e2ef 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java @@ -22,10 +22,14 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; +import java.util.Arrays; +import java.util.Collection; import java.util.zip.GZIPInputStream; +import java.util.zip.InflaterInputStream; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.gzip.CompressionType; import org.eclipse.jetty.io.ByteArrayBuffer; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.testing.HttpTester; @@ -36,9 +40,28 @@ import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; +@RunWith(Parameterized.class) public class IncludableGzipFilterTest { + @Parameters + public static Collection data() + { + CompressionType[][] data = new CompressionType[][] + { + { CompressionType.GZIP }, + { CompressionType.DEFLATE } + }; + + return Arrays.asList(data); + } + + @Rule + public TestingDir testdir = new TestingDir(); + private static String __content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "+ "Quisque suscipit mauris et ante auctor ornare rhoncus lacus aliquet. Pellentesque "+ @@ -53,11 +76,14 @@ public class IncludableGzipFilterTest "Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse "+ "et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque."; - @Rule - public TestingDir testdir = new TestingDir(); - private ServletTester tester; - + private CompressionType compressionType; + + public IncludableGzipFilterTest(CompressionType compressionType) + { + this.compressionType = compressionType; + } + @Before public void setUp() throws Exception { @@ -95,7 +121,7 @@ public class IncludableGzipFilterTest request.setMethod("GET"); request.setVersion("HTTP/1.0"); request.setHeader("Host","tester"); - request.setHeader("accept-encoding","gzip"); + request.setHeader("accept-encoding", compressionType.getEncodingHeader()); request.setURI("/context/file.txt"); ByteArrayBuffer reqsBuff = new ByteArrayBuffer(request.generate().getBytes()); @@ -103,10 +129,19 @@ public class IncludableGzipFilterTest response.parse(respBuff.asArray()); assertTrue(response.getMethod()==null); - assertTrue(response.getHeader("Content-Encoding").equalsIgnoreCase("gzip")); + assertTrue(response.getHeader("Content-Encoding").equalsIgnoreCase(compressionType.getEncodingHeader())); assertEquals(HttpServletResponse.SC_OK,response.getStatus()); - InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes())); + InputStream testIn = null; + ByteArrayInputStream compressedResponseStream = new ByteArrayInputStream(response.getContentBytes()); + if (compressionType.equals(CompressionType.GZIP)) + { + testIn = new GZIPInputStream(compressedResponseStream); + } + else if (compressionType.equals(CompressionType.DEFLATE)) + { + testIn = new InflaterInputStream(compressedResponseStream); + } ByteArrayOutputStream testOut = new ByteArrayOutputStream(); IO.copy(testIn,testOut); diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PipelineHelper.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PipelineHelper.java index 3f0e039b3e8..ad58c1bad6e 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PipelineHelper.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PipelineHelper.java @@ -25,8 +25,9 @@ public class PipelineHelper private Socket socket; private OutputStream outputStream; private InputStream inputStream; + private String encodingHeader; - public PipelineHelper(URI uri) + public PipelineHelper(URI uri, String encodingHeader) { if (LOG instanceof StdErrLog) { @@ -34,6 +35,7 @@ public class PipelineHelper } this.uri = uri; this.endpoint = new InetSocketAddress(uri.getHost(),uri.getPort()); + this.encodingHeader = encodingHeader; } /** @@ -76,7 +78,7 @@ public class PipelineHelper req.append("Accept-Language: en-us\r\n"); if (acceptGzipped) { - req.append("Accept-Encoding: gzip, deflate\r\n"); + req.append("Accept-Encoding: " + encodingHeader + "\r\n"); } req.append("Cookie: JSESSIONID=spqx8v8szylt1336t96vc6mw0\r\n"); if ( close ) @@ -134,7 +136,7 @@ public class PipelineHelper while (!(foundCR && foundLF)) { b = inputStream.read(); - Assert.assertThat("Should not have hit EOL (yet) during chunk size read",(int)b,not(-1)); + Assert.assertThat("Should not have hit EOL (yet) during chunk size read",b,not(-1)); if (b == 0x0D) { foundCR = true; @@ -163,7 +165,7 @@ public class PipelineHelper while (!(foundCR && foundLF)) { b = inputStream.read(); - Assert.assertThat("Should not have hit EOL (yet) during chunk size read",(int)b,not(-1)); + Assert.assertThat("Should not have hit EOL (yet) during chunk size read",b,not(-1)); if (b == 0x0D) { foundCR = true; diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java index d4e101775ff..91cc374c893 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java @@ -1,5 +1,13 @@ package org.eclipse.jetty.servlets.gzip; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -12,9 +20,12 @@ import java.util.Enumeration; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.GZIPInputStream; +import java.util.zip.InflaterInputStream; + import javax.servlet.Servlet; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.gzip.CompressionType; import org.eclipse.jetty.io.ByteArrayBuffer; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletHolder; @@ -26,12 +37,6 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.TestingDir; import org.junit.Assert; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.nullValue; - public class GzipTester { private Class gzipFilterClass = GzipFilter.class; @@ -39,10 +44,12 @@ public class GzipTester private String userAgent = null; private ServletTester servletTester; private TestingDir testdir; + private CompressionType compressionType; - public GzipTester(TestingDir testingdir) + public GzipTester(TestingDir testingdir, CompressionType compressionType) { this.testdir = testingdir; + this.compressionType = compressionType; // Make sure we start with a clean testing directory. // DOES NOT WORK IN WINDOWS - this.testdir.ensureEmpty(); } @@ -61,7 +68,7 @@ public class GzipTester request.setMethod("GET"); request.setVersion("HTTP/1.0"); request.setHeader("Host","tester"); - request.setHeader("Accept-Encoding","gzip"); + request.setHeader("Accept-Encoding",compressionType.getEncodingHeader()); if (this.userAgent != null) request.setHeader("User-Agent", this.userAgent); request.setURI("/context/" + requestedFilename); @@ -76,7 +83,7 @@ public class GzipTester Assert.assertThat("Response.method",response.getMethod(),nullValue()); Assert.assertThat("Response.status",response.getStatus(),is(HttpServletResponse.SC_OK)); Assert.assertThat("Response.header[Content-Length]",response.getHeader("Content-Length"),notNullValue()); - Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),containsString("gzip")); + Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),containsString(compressionType.getEncodingHeader())); // Assert that the decompressed contents are what we expect. File serverFile = testdir.getFile(serverFilename); @@ -89,12 +96,19 @@ public class GzipTester try { bais = new ByteArrayInputStream(response.getContentBytes()); - in = new GZIPInputStream(bais); + if (compressionType.equals(CompressionType.GZIP)) + { + in = new GZIPInputStream(bais); + } + else if (compressionType.equals(CompressionType.DEFLATE)) + { + in = new InflaterInputStream(bais); + } out = new ByteArrayOutputStream(); IO.copy(in,out); actual = out.toString(encoding); - Assert.assertEquals("Uncompressed contents",expected,actual); + assertThat("Uncompressed contents",actual,equalTo(expected)); } finally { @@ -128,7 +142,7 @@ public class GzipTester request.setMethod("GET"); request.setVersion("HTTP/1.0"); request.setHeader("Host","tester"); - request.setHeader("Accept-Encoding","gzip"); + request.setHeader("Accept-Encoding",compressionType.getEncodingHeader()); if (this.userAgent != null) request.setHeader("User-Agent", this.userAgent); request.setURI("/context/" + requestedFilename); @@ -215,7 +229,7 @@ public class GzipTester request.setMethod("GET"); request.setVersion("HTTP/1.0"); request.setHeader("Host","tester"); - request.setHeader("Accept-Encoding","gzip"); + request.setHeader("Accept-Encoding",compressionType.getEncodingHeader()); if (this.userAgent != null) request.setHeader("User-Agent", this.userAgent); if (filename == null) @@ -238,7 +252,7 @@ public class GzipTester int serverLength = Integer.parseInt(response.getHeader("Content-Length")); Assert.assertThat("Response.header[Content-Length]",serverLength,is(expectedFilesize)); } - Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),not(containsString("gzip"))); + Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),not(containsString(compressionType.getEncodingHeader()))); // Assert that the contents are what we expect. if (filename != null) From 2a44fa5c220b911b5dc54b51239b8f91e5bca008 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Fri, 30 Mar 2012 18:46:53 +0200 Subject: [PATCH 051/100] Cosmetics. --- .../java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/jetty-spdy/spdy-jetty-http/src/test/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYTest.java b/jetty-spdy/spdy-jetty-http/src/test/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYTest.java index 59370e5ce8e..b7932133d07 100644 --- a/jetty-spdy/spdy-jetty-http/src/test/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYTest.java +++ b/jetty-spdy/spdy-jetty-http/src/test/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYTest.java @@ -519,7 +519,6 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest @Override public void onData(Stream stream, DataInfo dataInfo) { - contentBytes.addAndGet(dataInfo.asByteBuffer(true).remaining()); if (dataInfo.isClose()) { From b0a3d031aaf2e91b3ef0dff2337054bacc044dca Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Fri, 30 Mar 2012 18:47:47 +0200 Subject: [PATCH 052/100] 375509 - Stalled stream stalls other streams or session control frames. Additional fixes to the implementation of flush(). Also implemented frame priority. --- .../eclipse/jetty/spdy/StandardSession.java | 114 +++++++++++------- 1 file changed, 72 insertions(+), 42 deletions(-) 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 a85103ba354..42f5ba0ef44 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 @@ -18,7 +18,6 @@ package org.eclipse.jetty.spdy; import java.nio.ByteBuffer; import java.nio.channels.InterruptedByTimeoutException; -import java.util.Deque; import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -79,7 +78,7 @@ public class StandardSession implements ISession, Parser.Listener, Handler listeners = new CopyOnWriteArrayList<>(); private final ConcurrentMap streams = new ConcurrentHashMap<>(); - private final Deque queue = new LinkedList<>(); + private final LinkedList queue = new LinkedList<>(); private final ByteBufferPool bufferPool; private final Executor threadPool; private final ScheduledExecutorService scheduler; @@ -732,10 +731,10 @@ public class StandardSession implements ISession, Parser.Listener, Handler frameBytes = new ControlFrameBytes<>(handler, context, frame, buffer); + ControlFrameBytes frameBytes = new ControlFrameBytes<>(stream, handler, context, frame, buffer); if (timeout > 0) frameBytes.task = scheduler.schedule(frameBytes, timeout, unit); - enqueueLast(frameBytes); + append(frameBytes); } flush(); @@ -766,10 +765,10 @@ public class StandardSession implements ISession, Parser.Listener, Handler void data(IStream stream, DataInfo dataInfo, long timeout, TimeUnit unit, Handler handler, C context) { logger.debug("Queuing {} on {}", dataInfo, stream); - DataFrameBytes frameBytes = new DataFrameBytes<>(handler, context, stream, dataInfo); + DataFrameBytes frameBytes = new DataFrameBytes<>(stream, handler, context, dataInfo); if (timeout > 0) frameBytes.task = scheduler.schedule(frameBytes, timeout, unit); - enqueueLast(frameBytes); + append(frameBytes); flush(); } @@ -781,56 +780,68 @@ public class StandardSession implements ISession, Parser.Listener, Handler stalledStreams = null; + for (int i = 0; i < queue.size(); ++i) { + frameBytes = queue.get(i); + + if (stalledStreams != null && stalledStreams.contains(frameBytes.getStream())) + continue; + buffer = frameBytes.getByteBuffer(); if (buffer != null) + { + queue.remove(i); break; + } + + if (stalledStreams == null) + stalledStreams = new HashSet<>(); + stalledStreams.add(frameBytes.getStream()); - // We are stalled: enqueue as last so other frames can be flushed - enqueueLast(frameBytes); - if (stalled == null) - stalled = frameBytes; - else if (stalled == frameBytes) - return; logger.debug("Flush stalled for {}, {} frame(s) in queue", frameBytes, queue.size()); - frameBytes = queue.poll(); } + if (buffer == null) + return; + flushing = true; logger.debug("Flushing {}, {} frame(s) in queue", frameBytes, queue.size()); } - - logger.debug("Writing {} frame bytes of {}", buffer.remaining(), frameBytes); write(buffer, this, frameBytes); } - private void enqueueLast(FrameBytes frameBytes) + private void append(FrameBytes frameBytes) { - // TODO: handle priority; e.g. use queues to prioritize the buffers ? - synchronized (queue) - { - queue.offerLast(frameBytes); - } + enqueue(frameBytes, false); } - private void enqueueFirst(FrameBytes frameBytes) + private void prepend(FrameBytes frameBytes) + { + enqueue(frameBytes, true); + } + + private void enqueue(FrameBytes frameBytes, boolean prepend) { synchronized (queue) { - queue.offerFirst(frameBytes); + int index = 0; + while (index < queue.size()) + { + FrameBytes element = queue.get(index); + int comparison = element.compareTo(frameBytes); + if (comparison > 0 || prepend && comparison == 0) + break; + ++index; + } + queue.add(index, frameBytes); } } @@ -854,7 +865,10 @@ public class StandardSession implements ISession, Parser.Listener, Handler handler, FrameBytes frameBytes) { if (controller != null) + { + logger.debug("Writing {} frame bytes of {}", buffer.remaining(), frameBytes); controller.write(buffer, handler, frameBytes); + } } private void complete(final Handler handler, final C context) @@ -920,8 +934,10 @@ public class StandardSession implements ISession, Parser.Listener, Handler { + public IStream getStream(); + public abstract ByteBuffer getByteBuffer(); public abstract void complete(); @@ -929,16 +945,30 @@ public class StandardSession implements ISession, Parser.Listener, Handler implements FrameBytes, Runnable { + private final IStream stream; private final Handler handler; private final C context; protected volatile ScheduledFuture task; - protected AbstractFrameBytes(Handler handler, C context) + protected AbstractFrameBytes(IStream stream, Handler handler, C context) { + this.stream = stream; this.handler = handler; this.context = context; } + @Override + public IStream getStream() + { + return stream; + } + + @Override + public int compareTo(FrameBytes that) + { + return getStream().getPriority() - that.getStream().getPriority(); + } + @Override public void complete() { @@ -966,9 +996,9 @@ public class StandardSession implements ISession, Parser.Listener, Handler handler, C context, ControlFrame frame, ByteBuffer buffer) + private ControlFrameBytes(IStream stream, Handler handler, C context, ControlFrame frame, ByteBuffer buffer) { - super(handler, context); + super(stream, handler, context); this.frame = frame; this.buffer = buffer; } @@ -1003,15 +1033,13 @@ public class StandardSession implements ISession, Parser.Listener, Handler extends AbstractFrameBytes { - private final IStream stream; private final DataInfo dataInfo; private int size; private volatile ByteBuffer buffer; - private DataFrameBytes(Handler handler, C context, IStream stream, DataInfo dataInfo) + private DataFrameBytes(IStream stream, Handler handler, C context, DataInfo dataInfo) { - super(handler, context); - this.stream = stream; + super(stream, handler, context); this.dataInfo = dataInfo; } @@ -1020,6 +1048,7 @@ public class StandardSession implements ISession, Parser.Listener, Handler 0) @@ -1049,7 +1079,7 @@ public class StandardSession implements ISession, Parser.Listener, Handler Date: Mon, 2 Apr 2012 12:09:03 +1000 Subject: [PATCH 053/100] 375692: simplified gzipfilter --- .../AbstractCompressedResponseWrapper.java | 412 ------------------ .../http/gzip/AbstractCompressedStream.java | 22 +- .../http/gzip/CompressedResponseWrapper.java | 401 ++++++++++++++++- .../jetty/http/gzip/CompressedStream.java | 77 ---- .../jetty/http/gzip/CompressionType.java | 48 -- .../http/gzip/DeflateResponseWrapperImpl.java | 54 --- .../jetty/http/gzip/DeflateStreamImpl.java | 55 --- .../http/gzip/GzipResponseWrapperImpl.java | 53 --- .../jetty/http/gzip/GzipStreamImpl.java | 56 --- .../jetty/server/handler/GzipHandler.java | 24 +- .../eclipse/jetty/servlets/GzipFilter.java | 70 ++- .../jetty/servlets/IncludableGzipFilter.java | 138 +++--- .../servlets/GzipFilterContentLengthTest.java | 39 +- .../GzipFilterDefaultNoRecompressTest.java | 61 ++- .../jetty/servlets/GzipFilterDefaultTest.java | 23 +- .../servlets/GzipWithPipeliningTest.java | 13 +- .../IncludableGzipFilterMinSizeTest.java | 13 +- .../servlets/IncludableGzipFilterTest.java | 21 +- .../jetty/servlets/gzip/GzipTester.java | 19 +- 19 files changed, 618 insertions(+), 981 deletions(-) delete mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedResponseWrapper.java delete mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressedStream.java delete mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressionType.java delete mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/gzip/DeflateResponseWrapperImpl.java delete mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/gzip/DeflateStreamImpl.java delete mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipResponseWrapperImpl.java delete mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipStreamImpl.java diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedResponseWrapper.java b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedResponseWrapper.java deleted file mode 100644 index 95c69109e99..00000000000 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedResponseWrapper.java +++ /dev/null @@ -1,412 +0,0 @@ -// ======================================================================== -// Copyright (c) 2009-2009 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.http.gzip; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; -import java.util.Set; - -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; - -import org.eclipse.jetty.util.StringUtil; - -/*------------------------------------------------------------ */ -/** - * Skeletal implementation of the CompressedResponseWrapper interface. - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper - */ -public abstract class AbstractCompressedResponseWrapper extends HttpServletResponseWrapper implements CompressedResponseWrapper -{ - - public static final int DEFAULT_BUFFER_SIZE = 8192; - public static final int DEFAULT_MIN_COMPRESS_SIZE = 256; - - private Set _mimeTypes; - private int _bufferSize=DEFAULT_BUFFER_SIZE; - private int _minCompressSize=DEFAULT_MIN_COMPRESS_SIZE; - private HttpServletRequest _request; - - private PrintWriter _writer; - private CompressedStream _compressedStream; - private long _contentLength=-1; - private boolean _noCompression; - - public AbstractCompressedResponseWrapper(HttpServletRequest request, HttpServletResponse response) - { - super(response); - _request = request; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setMimeTypes(java.util.Set) - */ - public void setMimeTypes(Set mimeTypes) - { - _mimeTypes = mimeTypes; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setBufferSize(int) - */ - @Override - public void setBufferSize(int bufferSize) - { - _bufferSize = bufferSize; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setMinCompressSize(int) - */ - public void setMinCompressSize(int minCompressSize) - { - _minCompressSize = minCompressSize; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setContentType(java.lang.String) - */ - @Override - public void setContentType(String ct) - { - super.setContentType(ct); - - if (ct!=null) - { - int colon=ct.indexOf(";"); - if (colon>0) - ct=ct.substring(0,colon); - } - - if ((_compressedStream==null || _compressedStream.getOutputStream()==null) && - (_mimeTypes==null && ct!=null && ct.contains("gzip") || - _mimeTypes!=null && (ct==null||!_mimeTypes.contains(StringUtil.asciiToLowerCase(ct))))) - { - noCompression(); - } - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setStatus(int, java.lang.String) - */ - @Override - public void setStatus(int sc, String sm) - { - super.setStatus(sc,sm); - if (sc<200 || sc==204 || sc==205 || sc>=300) - noCompression(); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setStatus(int) - */ - @Override - public void setStatus(int sc) - { - super.setStatus(sc); - if (sc<200 || sc==204 || sc==205 ||sc>=300) - noCompression(); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setContentLength(int) - */ - @Override - public void setContentLength(int length) - { - setContentLength((long)length); - } - - protected void setContentLength(long length) - { - _contentLength=length; - if (_compressedStream!=null) - _compressedStream.setContentLength(length); - else if (_noCompression && _contentLength>=0) - { - HttpServletResponse response = (HttpServletResponse)getResponse(); - if(_contentLength _mimeTypes; + private int _bufferSize=DEFAULT_BUFFER_SIZE; + private int _minCompressSize=DEFAULT_MIN_COMPRESS_SIZE; + protected HttpServletRequest _request; - /** - * Sets the mime types. - * - * @param mimeTypes - * the new mime types - */ - public void setMimeTypes(Set mimeTypes); + private PrintWriter _writer; + private AbstractCompressedStream _compressedStream; + private long _contentLength=-1; + private boolean _noCompression; - /** - * Sets the min compress size. - * - * @param minCompressSize - * the new min compress size - */ - public void setMinCompressSize(int minCompressSize); + public CompressedResponseWrapper(HttpServletRequest request, HttpServletResponse response) + { + super(response); + _request = request; + } /* ------------------------------------------------------------ */ /** - * No compression. + * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setMimeTypes(java.util.Set) */ - public void noCompression(); + public void setMimeTypes(Set mimeTypes) + { + _mimeTypes = mimeTypes; + } + /* ------------------------------------------------------------ */ /** - * Finish. - * - * @throws IOException - * Signals that an I/O exception has occurred. + * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setBufferSize(int) */ - public void finish() throws IOException; + @Override + public void setBufferSize(int bufferSize) + { + _bufferSize = bufferSize; + } + + /* ------------------------------------------------------------ */ + /** + * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setMinCompressSize(int) + */ + public void setMinCompressSize(int minCompressSize) + { + _minCompressSize = minCompressSize; + } + + /* ------------------------------------------------------------ */ + /** + * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setContentType(java.lang.String) + */ + @Override + public void setContentType(String ct) + { + super.setContentType(ct); + + if (ct!=null) + { + int colon=ct.indexOf(";"); + if (colon>0) + ct=ct.substring(0,colon); + } + + if ((_compressedStream==null || _compressedStream.getOutputStream()==null) && + (_mimeTypes==null && ct!=null && ct.contains("gzip") || + _mimeTypes!=null && (ct==null||!_mimeTypes.contains(StringUtil.asciiToLowerCase(ct))))) + { + noCompression(); + } + } + + /* ------------------------------------------------------------ */ + /** + * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setStatus(int, java.lang.String) + */ + @Override + public void setStatus(int sc, String sm) + { + super.setStatus(sc,sm); + if (sc<200 || sc==204 || sc==205 || sc>=300) + noCompression(); + } + + /* ------------------------------------------------------------ */ + /** + * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setStatus(int) + */ + @Override + public void setStatus(int sc) + { + super.setStatus(sc); + if (sc<200 || sc==204 || sc==205 ||sc>=300) + noCompression(); + } + + /* ------------------------------------------------------------ */ + /** + * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setContentLength(int) + */ + @Override + public void setContentLength(int length) + { + setContentLength((long)length); + } + + /* ------------------------------------------------------------ */ + protected void setContentLength(long length) + { + _contentLength=length; + if (_compressedStream!=null) + _compressedStream.setContentLength(length); + else if (_noCompression && _contentLength>=0) + { + HttpServletResponse response = (HttpServletResponse)getResponse(); + if(_contentLength _mimeTypes; protected int _bufferSize=8192; @@ -147,7 +149,22 @@ public class GzipFilter extends UserAgentFilter public void destroy() { } - + + /* ------------------------------------------------------------ */ + public String selectCompression(String encodingHeader) + { + // TODO, this could be a little more robust. + // prefer gzip over deflate + if (encodingHeader!=null) + { + if (encodingHeader.toLowerCase().contains(GZIP)) + return GZIP; + if (encodingHeader.toLowerCase().contains(DEFLATE)) + return DEFLATE; + } + return null; + } + /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.servlets.UserAgentFilter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) @@ -160,9 +177,8 @@ public class GzipFilter extends UserAgentFilter HttpServletResponse response=(HttpServletResponse)res; String ae = request.getHeader("accept-encoding"); - CompressionType compressionType = CompressionType.getByEncodingHeader(ae); - if (ae != null && !compressionType.equals(CompressionType.UNSUPPORTED) && !response.containsHeader("Content-Encoding") - && !HttpMethods.HEAD.equalsIgnoreCase(request.getMethod())) + String compressionType = selectCompression(request.getHeader("accept-encoding")); + if (compressionType!=null && !response.containsHeader("Content-Encoding") && !HttpMethods.HEAD.equalsIgnoreCase(request.getMethod())) { String ua = getUserAgent(request); if (isExcludedAgent(ua)) @@ -207,16 +223,44 @@ public class GzipFilter extends UserAgentFilter } } - protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, CompressionType compressionType) + protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, final String compressionType) { CompressedResponseWrapper wrappedResponse = null; - if (compressionType.equals(CompressionType.GZIP)) + if (compressionType.equals(GZIP)) { - wrappedResponse = new GzipResponseWrapperImpl(request,response); + wrappedResponse = new CompressedResponseWrapper(request,response) + { + @Override + protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minCompressSize) throws IOException + { + return new AbstractCompressedStream(compressionType,request,response,contentLength,bufferSize,minCompressSize) + { + @Override + protected DeflaterOutputStream createStream() throws IOException + { + return new GZIPOutputStream(_response.getOutputStream(),_bufferSize); + } + }; + } + }; } - else if (compressionType.equals(CompressionType.DEFLATE)) + else if (compressionType.equals(DEFLATE)) { - wrappedResponse = new DeflateResponseWrapperImpl(request,response); + wrappedResponse = new CompressedResponseWrapper(request,response) + { + @Override + protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minCompressSize) throws IOException + { + return new AbstractCompressedStream(compressionType,request,response,contentLength,bufferSize,minCompressSize) + { + @Override + protected DeflaterOutputStream createStream() throws IOException + { + return new DeflaterOutputStream(_response.getOutputStream()); + } + }; + } + }; } else { @@ -226,7 +270,7 @@ public class GzipFilter extends UserAgentFilter return wrappedResponse; } - private void configureWrappedResponse(CompressedResponseWrapper wrappedResponse) + protected void configureWrappedResponse(CompressedResponseWrapper wrappedResponse) { wrappedResponse.setMimeTypes(_mimeTypes); wrappedResponse.setBufferSize(_bufferSize); 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 a325dee3a99..972393e1644 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 @@ -18,6 +18,8 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; +import java.util.zip.DeflaterOutputStream; +import java.util.zip.GZIPOutputStream; import javax.servlet.FilterConfig; import javax.servlet.ServletException; @@ -25,11 +27,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.gzip.CompressedResponseWrapper; -import org.eclipse.jetty.http.gzip.CompressedStream; -import org.eclipse.jetty.http.gzip.CompressionType; -import org.eclipse.jetty.http.gzip.DeflateStreamImpl; -import org.eclipse.jetty.http.gzip.GzipResponseWrapperImpl; -import org.eclipse.jetty.http.gzip.GzipStreamImpl; +import org.eclipse.jetty.http.gzip.AbstractCompressedStream; import org.eclipse.jetty.io.UncheckedPrintWriter; /* ------------------------------------------------------------ */ @@ -58,43 +56,75 @@ public class IncludableGzipFilter extends GzipFilter _uncheckedPrintWriter=Boolean.valueOf(tmp).booleanValue(); } + /* ------------------------------------------------------------ */ + /** + * @see org.eclipse.jetty.servlets.GzipFilter#createWrappedResponse(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.String) + */ @Override - protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, CompressionType compressionType) + protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, final String compressionType) { - return new IncludableResponseWrapper(request,response); + CompressedResponseWrapper wrappedResponse = null; + if (compressionType.equals(GZIP)) + { + wrappedResponse = new IncludableResponseWrapper(request,response) + { + @Override + protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minCompressSize) throws IOException + { + return new AbstractCompressedStream(compressionType,request,response,contentLength,bufferSize,minCompressSize) + { + @Override + protected DeflaterOutputStream createStream() throws IOException + { + return new GZIPOutputStream(_response.getOutputStream(),_bufferSize); + } + }; + } + }; + } + else if (compressionType.equals(DEFLATE)) + { + wrappedResponse = new IncludableResponseWrapper(request,response) + { + @Override + protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minCompressSize) throws IOException + { + return new AbstractCompressedStream(compressionType,request,response,contentLength,bufferSize,minCompressSize) + { + @Override + protected DeflaterOutputStream createStream() throws IOException + { + return new DeflaterOutputStream(_response.getOutputStream()); + } + }; + } + }; + } + else + { + throw new IllegalStateException(compressionType + " not supported"); + } + configureWrappedResponse(wrappedResponse); + return wrappedResponse; } - - public class IncludableResponseWrapper extends GzipResponseWrapperImpl + + + // Extend CompressedResponseWrapper to be able to set headers during include and to create unchecked printwriters + private abstract class IncludableResponseWrapper extends CompressedResponseWrapper { public IncludableResponseWrapper(HttpServletRequest request, HttpServletResponse response) { super(request,response); - - super.setMimeTypes(IncludableGzipFilter.this._mimeTypes); - super.setBufferSize(IncludableGzipFilter.this._bufferSize); - super.setMinCompressSize(IncludableGzipFilter.this._minGzipSize); } @Override - protected CompressedStream newCompressedStream(HttpServletRequest request, HttpServletResponse response, long contentLength, int bufferSize, - int minGzipSize) throws IOException + public void setHeader(String name,String value) { - String encodingHeader = request.getHeader("accept-encoding"); - CompressionType compressionType = CompressionType.getByEncodingHeader(encodingHeader); - if (compressionType.equals(CompressionType.GZIP)) - { - return new IncludableGzipStream(request,response,contentLength,bufferSize,minGzipSize); - } - else if (compressionType.equals(CompressionType.DEFLATE)) - { - return new IncludableDeflateStream(request,response,contentLength,bufferSize,minGzipSize); - } - else - { - throw new IllegalStateException(compressionType.name() + " not supported."); - } + super.setHeader(name,value); + HttpServletResponse response = (HttpServletResponse)getResponse(); + if (!response.containsHeader(name)) + response.setHeader("org.eclipse.jetty.server.include."+name,value);; } - @Override protected PrintWriter newWriter(OutputStream out, String encoding) throws UnsupportedEncodingException { @@ -104,52 +134,4 @@ public class IncludableGzipFilter extends GzipFilter } } - public class IncludableGzipStream extends GzipStreamImpl - { - public IncludableGzipStream(HttpServletRequest request, HttpServletResponse response, long contentLength, int bufferSize, int minGzipSize) - throws IOException - { - super(request,response,contentLength,bufferSize,minGzipSize); - } - - @Override - protected boolean setContentEncoding() - { - if (_request.getAttribute("javax.servlet.include.request_uri") != null) - { - _response.setHeader("org.eclipse.jetty.server.include.Content-Encoding","gzip"); - } - else - { - _response.setHeader("Content-Encoding","gzip"); - } - - return _response.containsHeader("Content-Encoding"); - } - } - - public class IncludableDeflateStream extends DeflateStreamImpl - { - public IncludableDeflateStream(HttpServletRequest request, HttpServletResponse response, long contentLength, int bufferSize, int minGzipSize) - throws IOException - { - super(request,response,contentLength,bufferSize,minGzipSize); - } - - @Override - protected boolean setContentEncoding() - { - if (_request.getAttribute("javax.servlet.include.request_uri") != null) - { - _response.setHeader("org.eclipse.jetty.server.include.Content-Encoding","deflate"); - } - else - { - _response.setHeader("Content-Encoding","deflate"); - } - - return _response.containsHeader("Content-Encoding"); - } - } - } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterContentLengthTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterContentLengthTest.java index b636583c716..c752591bc25 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterContentLengthTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterContentLengthTest.java @@ -6,8 +6,7 @@ import java.util.List; import javax.servlet.Servlet; import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.http.gzip.CompressionType; -import org.eclipse.jetty.http.gzip.GzipResponseWrapperImpl; +import org.eclipse.jetty.http.gzip.CompressedResponseWrapper; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlets.gzip.GzipTester; import org.eclipse.jetty.servlets.gzip.TestServletLengthStreamTypeWrite; @@ -49,29 +48,29 @@ public class GzipFilterContentLengthTest { return Arrays.asList(new Object[][] { - { TestServletLengthStreamTypeWrite.class, CompressionType.GZIP }, - { TestServletLengthTypeStreamWrite.class, CompressionType.GZIP }, - { TestServletStreamLengthTypeWrite.class, CompressionType.GZIP }, - { TestServletStreamTypeLengthWrite.class, CompressionType.GZIP }, - { TestServletTypeLengthStreamWrite.class, CompressionType.GZIP }, - { TestServletTypeStreamLengthWrite.class, CompressionType.GZIP }, - { TestServletLengthStreamTypeWrite.class, CompressionType.DEFLATE }, - { TestServletLengthTypeStreamWrite.class, CompressionType.DEFLATE }, - { TestServletStreamLengthTypeWrite.class, CompressionType.DEFLATE }, - { TestServletStreamTypeLengthWrite.class, CompressionType.DEFLATE }, - { TestServletTypeLengthStreamWrite.class, CompressionType.DEFLATE }, - { TestServletTypeStreamLengthWrite.class, CompressionType.DEFLATE } + { TestServletLengthStreamTypeWrite.class, GzipFilter.GZIP }, + { TestServletLengthTypeStreamWrite.class, GzipFilter.GZIP }, + { TestServletStreamLengthTypeWrite.class, GzipFilter.GZIP }, + { TestServletStreamTypeLengthWrite.class, GzipFilter.GZIP }, + { TestServletTypeLengthStreamWrite.class, GzipFilter.GZIP }, + { TestServletTypeStreamLengthWrite.class, GzipFilter.GZIP }, + { TestServletLengthStreamTypeWrite.class, GzipFilter.DEFLATE }, + { TestServletLengthTypeStreamWrite.class, GzipFilter.DEFLATE }, + { TestServletStreamLengthTypeWrite.class, GzipFilter.DEFLATE }, + { TestServletStreamTypeLengthWrite.class, GzipFilter.DEFLATE }, + { TestServletTypeLengthStreamWrite.class, GzipFilter.DEFLATE }, + { TestServletTypeStreamLengthWrite.class, GzipFilter.DEFLATE } }); } - private static final int LARGE = GzipResponseWrapperImpl.DEFAULT_BUFFER_SIZE * 8; - private static final int MEDIUM = GzipResponseWrapperImpl.DEFAULT_BUFFER_SIZE; - private static final int SMALL = GzipResponseWrapperImpl.DEFAULT_BUFFER_SIZE / 4; - private static final int TINY = GzipResponseWrapperImpl.DEFAULT_MIN_COMPRESS_SIZE/ 2; + private static final int LARGE = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE * 8; + private static final int MEDIUM = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE; + private static final int SMALL = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE / 4; + private static final int TINY = CompressedResponseWrapper.DEFAULT_MIN_COMPRESS_SIZE/ 2; - private CompressionType compressionType; + private String compressionType; - public GzipFilterContentLengthTest(Class testServlet, CompressionType compressionType) + public GzipFilterContentLengthTest(Class testServlet, String compressionType) { this.testServlet = testServlet; this.compressionType = compressionType; diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultNoRecompressTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultNoRecompressTest.java index 996e26a0547..a890b96b628 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultNoRecompressTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultNoRecompressTest.java @@ -5,7 +5,6 @@ import java.io.IOException; import java.util.Arrays; import java.util.List; -import org.eclipse.jetty.http.gzip.CompressionType; import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlets.gzip.GzipTester; @@ -32,41 +31,41 @@ public class GzipFilterDefaultNoRecompressTest return Arrays.asList(new Object[][] { // Some already compressed files - { "test_quotes.gz", "application/gzip", CompressionType.GZIP }, - { "test_quotes.bz2", "application/bzip2", CompressionType.GZIP }, - { "test_quotes.zip", "application/zip", CompressionType.GZIP }, - { "test_quotes.rar", "application/octet-stream", CompressionType.GZIP }, + { "test_quotes.gz", "application/gzip", GzipFilter.GZIP }, + { "test_quotes.bz2", "application/bzip2", GzipFilter.GZIP }, + { "test_quotes.zip", "application/zip", GzipFilter.GZIP }, + { "test_quotes.rar", "application/octet-stream", GzipFilter.GZIP }, // Some images (common first) - { "jetty_logo.png", "image/png", CompressionType.GZIP }, - { "jetty_logo.gif", "image/gif", CompressionType.GZIP }, - { "jetty_logo.jpeg", "image/jpeg", CompressionType.GZIP }, - { "jetty_logo.jpg", "image/jpeg", CompressionType.GZIP }, + { "jetty_logo.png", "image/png", GzipFilter.GZIP }, + { "jetty_logo.gif", "image/gif", GzipFilter.GZIP }, + { "jetty_logo.jpeg", "image/jpeg", GzipFilter.GZIP }, + { "jetty_logo.jpg", "image/jpeg", GzipFilter.GZIP }, // Lesser encountered images (usually found being requested from non-browser clients) - { "jetty_logo.bmp", "image/bmp", CompressionType.GZIP }, - { "jetty_logo.tga", "application/tga", CompressionType.GZIP }, - { "jetty_logo.tif", "image/tiff", CompressionType.GZIP }, - { "jetty_logo.tiff", "image/tiff", CompressionType.GZIP }, - { "jetty_logo.xcf", "image/xcf", CompressionType.GZIP }, - { "jetty_logo.jp2", "image/jpeg2000", CompressionType.GZIP }, + { "jetty_logo.bmp", "image/bmp", GzipFilter.GZIP }, + { "jetty_logo.tga", "application/tga", GzipFilter.GZIP }, + { "jetty_logo.tif", "image/tiff", GzipFilter.GZIP }, + { "jetty_logo.tiff", "image/tiff", GzipFilter.GZIP }, + { "jetty_logo.xcf", "image/xcf", GzipFilter.GZIP }, + { "jetty_logo.jp2", "image/jpeg2000", GzipFilter.GZIP }, // Same tests again for deflate // Some already compressed files - { "test_quotes.gz", "application/gzip", CompressionType.DEFLATE }, - { "test_quotes.bz2", "application/bzip2", CompressionType.DEFLATE }, - { "test_quotes.zip", "application/zip", CompressionType.DEFLATE }, - { "test_quotes.rar", "application/octet-stream", CompressionType.DEFLATE }, + { "test_quotes.gz", "application/gzip", GzipFilter.DEFLATE }, + { "test_quotes.bz2", "application/bzip2", GzipFilter.DEFLATE }, + { "test_quotes.zip", "application/zip", GzipFilter.DEFLATE }, + { "test_quotes.rar", "application/octet-stream", GzipFilter.DEFLATE }, // Some images (common first) - { "jetty_logo.png", "image/png", CompressionType.DEFLATE }, - { "jetty_logo.gif", "image/gif", CompressionType.DEFLATE }, - { "jetty_logo.jpeg", "image/jpeg", CompressionType.DEFLATE }, - { "jetty_logo.jpg", "image/jpeg", CompressionType.DEFLATE }, + { "jetty_logo.png", "image/png", GzipFilter.DEFLATE }, + { "jetty_logo.gif", "image/gif", GzipFilter.DEFLATE }, + { "jetty_logo.jpeg", "image/jpeg", GzipFilter.DEFLATE }, + { "jetty_logo.jpg", "image/jpeg", GzipFilter.DEFLATE }, // Lesser encountered images (usually found being requested from non-browser clients) - { "jetty_logo.bmp", "image/bmp", CompressionType.DEFLATE }, - { "jetty_logo.tga", "application/tga", CompressionType.DEFLATE }, - { "jetty_logo.tif", "image/tiff", CompressionType.DEFLATE }, - { "jetty_logo.tiff", "image/tiff", CompressionType.DEFLATE }, - { "jetty_logo.xcf", "image/xcf", CompressionType.DEFLATE }, - { "jetty_logo.jp2", "image/jpeg2000", CompressionType.DEFLATE } }); + { "jetty_logo.bmp", "image/bmp", GzipFilter.DEFLATE }, + { "jetty_logo.tga", "application/tga", GzipFilter.DEFLATE }, + { "jetty_logo.tif", "image/tiff", GzipFilter.DEFLATE }, + { "jetty_logo.tiff", "image/tiff", GzipFilter.DEFLATE }, + { "jetty_logo.xcf", "image/xcf", GzipFilter.DEFLATE }, + { "jetty_logo.jp2", "image/jpeg2000", GzipFilter.DEFLATE } }); } @Rule @@ -74,9 +73,9 @@ public class GzipFilterDefaultNoRecompressTest private String alreadyCompressedFilename; private String expectedContentType; - private CompressionType compressionType; + private String compressionType; - public GzipFilterDefaultNoRecompressTest(String testFilename, String expectedContentType, CompressionType compressionType) + public GzipFilterDefaultNoRecompressTest(String testFilename, String expectedContentType, String compressionType) { this.alreadyCompressedFilename = testFilename; this.expectedContentType = expectedContentType; diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java index 47f637150cd..6c6faba5198 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java @@ -10,8 +10,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.http.gzip.CompressionType; -import org.eclipse.jetty.http.gzip.GzipResponseWrapperImpl; +import org.eclipse.jetty.http.gzip.CompressedResponseWrapper; import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlets.gzip.GzipTester; @@ -29,20 +28,20 @@ import org.junit.runners.Parameterized.Parameters; public class GzipFilterDefaultTest { @Parameters - public static Collection data() + public static Collection data() { - CompressionType[][] data = new CompressionType[][] + String[][] data = new String[][] { - { CompressionType.GZIP }, - { CompressionType.DEFLATE } + { GzipFilter.GZIP }, + { GzipFilter.DEFLATE } }; return Arrays.asList(data); } - private CompressionType compressionType; + private String compressionType; - public GzipFilterDefaultTest(CompressionType compressionType) + public GzipFilterDefaultTest(String compressionType) { this.compressionType = compressionType; } @@ -80,7 +79,7 @@ public class GzipFilterDefaultTest GzipTester tester = new GzipTester(testingdir, compressionType); // Test content that is smaller than the buffer. - int filesize = GzipResponseWrapperImpl.DEFAULT_BUFFER_SIZE / 4; + int filesize = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE / 4; tester.prepareServerFile("file.txt",filesize); FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class); @@ -103,7 +102,7 @@ public class GzipFilterDefaultTest GzipTester tester = new GzipTester(testingdir, compressionType); // Test content that is smaller than the buffer. - int filesize = GzipResponseWrapperImpl.DEFAULT_BUFFER_SIZE * 4; + int filesize = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE * 4; tester.prepareServerFile("file.txt",filesize); FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class); @@ -126,7 +125,7 @@ public class GzipFilterDefaultTest GzipTester tester = new GzipTester(testingdir, compressionType); // Test content that is smaller than the buffer. - int filesize = GzipResponseWrapperImpl.DEFAULT_BUFFER_SIZE * 4; + int filesize = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE * 4; tester.prepareServerFile("file.mp3",filesize); FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class); @@ -173,7 +172,7 @@ public class GzipFilterDefaultTest holder.setInitParameter("excludedAgents", "foo"); tester.setUserAgent("foo"); - int filesize = GzipResponseWrapperImpl.DEFAULT_BUFFER_SIZE * 4; + int filesize = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE * 4; tester.prepareServerFile("file.txt",filesize); try diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipWithPipeliningTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipWithPipeliningTest.java index 65a66898fc4..4144b0702d1 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipWithPipeliningTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipWithPipeliningTest.java @@ -18,7 +18,6 @@ import java.util.regex.Pattern; import java.util.zip.GZIPInputStream; import java.util.zip.InflaterInputStream; -import org.eclipse.jetty.http.gzip.CompressionType; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.DefaultServlet; @@ -50,10 +49,10 @@ public class GzipWithPipeliningTest // Test different Content-Encoding header combinations. So implicitly testing that gzip is preferred oder deflate String[][] data = new String[][] { - { CompressionType.GZIP.getEncodingHeader() }, - { CompressionType.DEFLATE.getEncodingHeader() + ", " + CompressionType.GZIP.getEncodingHeader() }, - { CompressionType.GZIP.getEncodingHeader() + ", " + CompressionType.DEFLATE.getEncodingHeader() }, - { CompressionType.DEFLATE.getEncodingHeader() } + { GzipFilter.GZIP }, + { GzipFilter.DEFLATE + ", " + GzipFilter.GZIP }, + { GzipFilter.GZIP + ", " + GzipFilter.DEFLATE }, + { GzipFilter.DEFLATE } }; return Arrays.asList(data); @@ -137,7 +136,7 @@ public class GzipWithPipeliningTest respHeader = client.readResponseHeader(); System.out.println("Response Header #1 --\n" + respHeader); - String expectedEncodingHeader = encodingHeader.equals(CompressionType.DEFLATE.getEncodingHeader()) ? CompressionType.DEFLATE.getEncodingHeader() : CompressionType.GZIP.getEncodingHeader(); + String expectedEncodingHeader = encodingHeader.equals(GzipFilter.DEFLATE) ? GzipFilter.DEFLATE : GzipFilter.GZIP; assertThat("Content-Encoding should be gzipped",respHeader,containsString("Content-Encoding: " + expectedEncodingHeader + "\r\n")); assertThat("Transfer-Encoding should be chunked",respHeader,containsString("Transfer-Encoding: chunked\r\n")); @@ -182,7 +181,7 @@ public class GzipWithPipeliningTest IO.close(rawOutputStream); FileInputStream rawInputStream = new FileInputStream(rawOutputFile); InputStream uncompressedStream = null; - if (CompressionType.DEFLATE.getEncodingHeader().equals(encodingHeader)) + if (GzipFilter.DEFLATE.equals(encodingHeader)) { uncompressedStream = new InflaterInputStream(rawInputStream); } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterMinSizeTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterMinSizeTest.java index e12abff667a..6d37b0f1e6d 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterMinSizeTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterMinSizeTest.java @@ -18,7 +18,6 @@ import java.util.Collection; import javax.servlet.Servlet; -import org.eclipse.jetty.http.gzip.CompressionType; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlets.gzip.GzipTester; import org.eclipse.jetty.servlets.gzip.TestMinGzipSizeServlet; @@ -39,18 +38,18 @@ import org.junit.runners.Parameterized.Parameters; public class IncludableGzipFilterMinSizeTest { @Parameters - public static Collection data() + public static Collection data() { - CompressionType[][] data = new CompressionType[][] + String[][] data = new String[][] { - { CompressionType.GZIP }, - { CompressionType.DEFLATE } + { GzipFilter.GZIP }, + { GzipFilter.DEFLATE } }; return Arrays.asList(data); } - public IncludableGzipFilterMinSizeTest(CompressionType compressionType) + public IncludableGzipFilterMinSizeTest(String compressionType) { this.compressionType = compressionType; } @@ -58,7 +57,7 @@ public class IncludableGzipFilterMinSizeTest @Rule public TestingDir testdir = new TestingDir(); - private CompressionType compressionType; + private String compressionType; private Class testServlet = TestMinGzipSizeServlet.class; @Test diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java index 49459e4e2ef..9872c198014 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java @@ -29,7 +29,6 @@ import java.util.zip.InflaterInputStream; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.http.gzip.CompressionType; import org.eclipse.jetty.io.ByteArrayBuffer; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.testing.HttpTester; @@ -48,12 +47,12 @@ import org.junit.runners.Parameterized.Parameters; public class IncludableGzipFilterTest { @Parameters - public static Collection data() + public static Collection data() { - CompressionType[][] data = new CompressionType[][] + String[][] data = new String[][] { - { CompressionType.GZIP }, - { CompressionType.DEFLATE } + { GzipFilter.GZIP }, + { GzipFilter.DEFLATE } }; return Arrays.asList(data); @@ -77,9 +76,9 @@ public class IncludableGzipFilterTest "et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque."; private ServletTester tester; - private CompressionType compressionType; + private String compressionType; - public IncludableGzipFilterTest(CompressionType compressionType) + public IncludableGzipFilterTest(String compressionType) { this.compressionType = compressionType; } @@ -121,7 +120,7 @@ public class IncludableGzipFilterTest request.setMethod("GET"); request.setVersion("HTTP/1.0"); request.setHeader("Host","tester"); - request.setHeader("accept-encoding", compressionType.getEncodingHeader()); + request.setHeader("accept-encoding", compressionType); request.setURI("/context/file.txt"); ByteArrayBuffer reqsBuff = new ByteArrayBuffer(request.generate().getBytes()); @@ -129,16 +128,16 @@ public class IncludableGzipFilterTest response.parse(respBuff.asArray()); assertTrue(response.getMethod()==null); - assertTrue(response.getHeader("Content-Encoding").equalsIgnoreCase(compressionType.getEncodingHeader())); + assertTrue(response.getHeader("Content-Encoding").equalsIgnoreCase(compressionType)); assertEquals(HttpServletResponse.SC_OK,response.getStatus()); InputStream testIn = null; ByteArrayInputStream compressedResponseStream = new ByteArrayInputStream(response.getContentBytes()); - if (compressionType.equals(CompressionType.GZIP)) + if (compressionType.equals(GzipFilter.GZIP)) { testIn = new GZIPInputStream(compressedResponseStream); } - else if (compressionType.equals(CompressionType.DEFLATE)) + else if (compressionType.equals(GzipFilter.DEFLATE)) { testIn = new InflaterInputStream(compressedResponseStream); } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java index 91cc374c893..36cec8037b9 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java @@ -25,7 +25,6 @@ import java.util.zip.InflaterInputStream; import javax.servlet.Servlet; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.http.gzip.CompressionType; import org.eclipse.jetty.io.ByteArrayBuffer; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletHolder; @@ -44,9 +43,9 @@ public class GzipTester private String userAgent = null; private ServletTester servletTester; private TestingDir testdir; - private CompressionType compressionType; + private String compressionType; - public GzipTester(TestingDir testingdir, CompressionType compressionType) + public GzipTester(TestingDir testingdir, String compressionType) { this.testdir = testingdir; this.compressionType = compressionType; @@ -68,7 +67,7 @@ public class GzipTester request.setMethod("GET"); request.setVersion("HTTP/1.0"); request.setHeader("Host","tester"); - request.setHeader("Accept-Encoding",compressionType.getEncodingHeader()); + request.setHeader("Accept-Encoding",compressionType); if (this.userAgent != null) request.setHeader("User-Agent", this.userAgent); request.setURI("/context/" + requestedFilename); @@ -83,7 +82,7 @@ public class GzipTester Assert.assertThat("Response.method",response.getMethod(),nullValue()); Assert.assertThat("Response.status",response.getStatus(),is(HttpServletResponse.SC_OK)); Assert.assertThat("Response.header[Content-Length]",response.getHeader("Content-Length"),notNullValue()); - Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),containsString(compressionType.getEncodingHeader())); + Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),containsString(compressionType)); // Assert that the decompressed contents are what we expect. File serverFile = testdir.getFile(serverFilename); @@ -96,11 +95,11 @@ public class GzipTester try { bais = new ByteArrayInputStream(response.getContentBytes()); - if (compressionType.equals(CompressionType.GZIP)) + if (compressionType.equals(GzipFilter.GZIP)) { in = new GZIPInputStream(bais); } - else if (compressionType.equals(CompressionType.DEFLATE)) + else if (compressionType.equals(GzipFilter.DEFLATE)) { in = new InflaterInputStream(bais); } @@ -142,7 +141,7 @@ public class GzipTester request.setMethod("GET"); request.setVersion("HTTP/1.0"); request.setHeader("Host","tester"); - request.setHeader("Accept-Encoding",compressionType.getEncodingHeader()); + request.setHeader("Accept-Encoding",compressionType); if (this.userAgent != null) request.setHeader("User-Agent", this.userAgent); request.setURI("/context/" + requestedFilename); @@ -229,7 +228,7 @@ public class GzipTester request.setMethod("GET"); request.setVersion("HTTP/1.0"); request.setHeader("Host","tester"); - request.setHeader("Accept-Encoding",compressionType.getEncodingHeader()); + request.setHeader("Accept-Encoding",compressionType); if (this.userAgent != null) request.setHeader("User-Agent", this.userAgent); if (filename == null) @@ -252,7 +251,7 @@ public class GzipTester int serverLength = Integer.parseInt(response.getHeader("Content-Length")); Assert.assertThat("Response.header[Content-Length]",serverLength,is(expectedFilesize)); } - Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),not(containsString(compressionType.getEncodingHeader()))); + Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),not(containsString(compressionType))); // Assert that the contents are what we expect. if (filename != null) From 28de69760a768ee537191e5631cccc76fa3ba3bb Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Mon, 2 Apr 2012 12:35:12 +1000 Subject: [PATCH 054/100] JETTY-1504 HttpServletResponseWrapper ignored when using asyncContext? --- .../jetty/server/AsyncContinuation.java | 1 + .../jetty/servlet/AsyncContextTest.java | 24 ++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContinuation.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContinuation.java index 7c68dfa3793..382d0ed12c8 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContinuation.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContinuation.java @@ -819,6 +819,7 @@ public class AsyncContinuation implements AsyncContext, Continuation { synchronized (this) { + _responseWrapped=!(response instanceof Response); doSuspend(context,request,response); if (request instanceof HttpServletRequest) { diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncContextTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncContextTest.java index bf38fb92b46..f10d24fa93a 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncContextTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncContextTest.java @@ -3,6 +3,7 @@ package org.eclipse.jetty.servlet; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import java.io.BufferedReader; import java.io.IOException; @@ -12,6 +13,7 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; import junit.framework.Assert; @@ -223,17 +225,20 @@ public class AsyncContextTest } else { + boolean wrapped = false; final AsyncContext asyncContext; if (request.getParameter("dispatchRequestResponse") != null) { - asyncContext = request.startAsync(request,response); + wrapped = true; + asyncContext = request.startAsync(request, new Wrapper(response)); } else { asyncContext = request.startAsync(); } - new Thread(new DispatchingRunnable(asyncContext)).start(); + + new Thread(new DispatchingRunnable(asyncContext, wrapped)).start(); } } } @@ -241,14 +246,18 @@ public class AsyncContextTest private class DispatchingRunnable implements Runnable { private AsyncContext asyncContext; + private boolean wrapped; - public DispatchingRunnable(AsyncContext asyncContext) + public DispatchingRunnable(AsyncContext asyncContext, boolean wrapped) { this.asyncContext = asyncContext; + this.wrapped = wrapped; } public void run() { + if (wrapped) + assertTrue(asyncContext.getResponse() instanceof Wrapper); asyncContext.dispatch(); } } @@ -347,4 +356,13 @@ public class AsyncContextTest } } + private class Wrapper extends HttpServletResponseWrapper + { + public Wrapper (HttpServletResponse response) + { + super(response); + } + } + + } From 2c4ea64f3b2e57f9e49bc5e4e32f6dda687a1d84 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Mon, 2 Apr 2012 14:48:38 +1000 Subject: [PATCH 055/100] 372678 Embedded Examples need updates for new LoginService requirement --- .../org/eclipse/jetty/embedded/OneWebApp.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/OneWebApp.java b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/OneWebApp.java index 86453ae9e4f..9ebba4e49fd 100644 --- a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/OneWebApp.java +++ b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/OneWebApp.java @@ -29,7 +29,11 @@ public class OneWebApp server.setConnectors(new Connector[] { connector }); - String war = args.length > 0?args[0]: "../test-jetty-webapp/target/test-jetty-webapp-" + Server.getVersion(); + + //If you're running this from inside Eclipse, then Server.getVersion will not provide + //the correct number as there is no manifest. Use the command line instead to provide the path to the + //test webapp + String war = args.length > 0?args[0]: "../test-jetty-webapp/target/test-jetty-webapp-"+Server.getVersion(); String path = args.length > 1?args[1]:"/"; System.err.println(war + " " + path); @@ -37,6 +41,15 @@ public class OneWebApp WebAppContext webapp = new WebAppContext(); webapp.setContextPath(path); webapp.setWar(war); + + //If the webapp contains security constraints, you will need to configure a LoginService + if (war.contains("test-jetty-webapp")) + { + org.eclipse.jetty.security.HashLoginService loginService = new org.eclipse.jetty.security.HashLoginService(); + loginService.setName("Test Realm"); + loginService.setConfig("src/test/resources/realm.properties"); + webapp.getSecurityHandler().setLoginService(loginService); + } server.setHandler(webapp); From 830557f018d63e4883068119dc1bcfb267670e4a Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Mon, 2 Apr 2012 10:06:35 +0200 Subject: [PATCH 056/100] Fixed infinite recursive loop. --- .../src/main/java/org/eclipse/jetty/client/HttpClient.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 0b5581ed984..4de850fa627 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 @@ -171,7 +171,7 @@ public class HttpClient extends AggregateLifeCycle implements HttpBuffers, Attri /* ------------------------------------------------------------ */ /** Set the ThreadPool. - * The threadpool passed is added via {@link #addBean(Object)} so that + * The threadpool passed is added via {@link #addBean(Object)} so that * it's lifecycle may be managed as a {@link AggregateLifeCycle}. * @param threadPool the threadPool to set */ @@ -878,7 +878,7 @@ public class HttpClient extends AggregateLifeCycle implements HttpBuffers, Attri @Deprecated public void setProvider(String provider) { - setProvider(provider); + _sslContextFactory.setProvider(provider); } /* ------------------------------------------------------------ */ From fff059f7a99ba53c8aaa2ea9837ac47868362afc Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Mon, 2 Apr 2012 10:07:25 +0200 Subject: [PATCH 057/100] Making sure bytes are masked when doing int operations. --- .../org/eclipse/jetty/spdy/generator/SettingsGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/SettingsGenerator.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/SettingsGenerator.java index 7a8496eb4bd..c61846ebd84 100644 --- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/SettingsGenerator.java +++ b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/SettingsGenerator.java @@ -65,7 +65,7 @@ public class SettingsGenerator extends ControlFrameGenerator case SPDY.V2: { // In v2 the format is 24 bits of ID + 8 bits of flag - int idAndFlags = (id << 8) + flags; + int idAndFlags = (id << 8) + (flags & 0xFF); // A bug in the Chromium implementation forces v2 to have // the 3 ID bytes little endian, so we swap first and third int result = idAndFlags & 0x00_FF_00_FF; From 00b31b6577e1419fa5fe84d55c92e31297ea7627 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Mon, 2 Apr 2012 10:07:51 +0200 Subject: [PATCH 058/100] Added defaults in switches. --- .../org/eclipse/jetty/spdy/parser/GoAwayBodyParser.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/GoAwayBodyParser.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/GoAwayBodyParser.java index dc948968f3d..753ad804d4d 100644 --- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/GoAwayBodyParser.java +++ b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/GoAwayBodyParser.java @@ -58,6 +58,10 @@ public class GoAwayBodyParser extends ControlFrameBodyParser state = State.STATUS_CODE; break; } + default: + { + throw new IllegalStateException(); + } } } else @@ -87,6 +91,10 @@ public class GoAwayBodyParser extends ControlFrameBodyParser state = State.STATUS_CODE; break; } + default: + { + throw new IllegalStateException(); + } } } break; From bb429a7f186d3812e3305e88d15a139800f210ef Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Mon, 2 Apr 2012 10:09:55 +0200 Subject: [PATCH 059/100] 375509 - Stalled stream stalls other streams or session control frames. Now using a "death pill" instead of a boolean in order to avoid race conditions where DataInfos were read from the queue (but the boolean not updated yet), and viceversa. --- .../http/ServerHTTPSPDYAsyncConnection.java | 56 ++++++++++++------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYAsyncConnection.java b/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYAsyncConnection.java index e263654af16..f782d656467 100644 --- a/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYAsyncConnection.java +++ b/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYAsyncConnection.java @@ -57,6 +57,7 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem { private static final Logger logger = LoggerFactory.getLogger(ServerHTTPSPDYAsyncConnection.class); private static final ByteBuffer ZERO_BYTES = ByteBuffer.allocate(0); + private static final DataInfo END_OF_CONTENT = new ByteBufferDataInfo(ZERO_BYTES, true); private final Queue tasks = new LinkedList<>(); private final BlockingQueue dataInfos = new LinkedBlockingQueue<>(); @@ -65,7 +66,6 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem private Headers headers; // No need for volatile, guarded by state private DataInfo dataInfo; // No need for volatile, guarded by state private NIOBuffer buffer; // No need for volatile, guarded by state - private boolean complete; // No need for volatile, guarded by state private volatile State state = State.INITIAL; private boolean dispatched; // Guarded by synchronization on tasks @@ -160,7 +160,7 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem logger.debug("HTTP > {} {} {}", new Object[]{m, u, v}); startRequest(new ByteArrayBuffer(m), new ByteArrayBuffer(u), new ByteArrayBuffer(v)); - state = State.HEADERS; + updateState(State.HEADERS); handle(); break; } @@ -261,6 +261,12 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem { } + private void updateState(State newState) + { + logger.debug("State update {} -> {}", state, newState); + state = newState; + } + public void beginRequest(final Headers headers) { this.headers = headers.isEmpty() ? null : headers; @@ -270,7 +276,7 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem public void run() { if (!headers.isEmpty()) - state = State.REQUEST; + updateState(State.REQUEST); handle(); } }); @@ -284,7 +290,7 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem @Override public void run() { - state = state == State.INITIAL ? State.REQUEST : State.HEADERS; + updateState(state == State.INITIAL ? State.REQUEST : State.HEADERS); handle(); } }); @@ -292,7 +298,10 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem public void content(final DataInfo dataInfo, boolean endRequest) { - dataInfos.offer(new ByteBufferDataInfo(dataInfo.asByteBuffer(false), dataInfo.isClose(), dataInfo.isCompress()) + // We need to copy the dataInfo since we do not know when its bytes + // will be consumed. When the copy is consumed, we consume also the + // original, so the implementation can send a window update. + ByteBufferDataInfo copyDataInfo = new ByteBufferDataInfo(dataInfo.asByteBuffer(false), dataInfo.isClose(), dataInfo.isCompress()) { @Override public void consume(int delta) @@ -300,8 +309,11 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem super.consume(delta); dataInfo.consume(delta); } - }); - complete = endRequest; + }; + logger.debug("Queuing last={} content {}", endRequest, copyDataInfo); + dataInfos.offer(copyDataInfo); + if (endRequest) + dataInfos.offer(END_OF_CONTENT); post(new Runnable() { @Override @@ -310,10 +322,10 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem logger.debug("HTTP > {} bytes of content", dataInfo.length()); if (state == State.HEADERS) { - state = State.HEADERS_COMPLETE; + updateState(State.HEADERS_COMPLETE); handle(); } - state = State.CONTENT; + updateState(State.CONTENT); handle(); } }); @@ -327,10 +339,10 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem { if (state == State.HEADERS) { - state = State.HEADERS_COMPLETE; + updateState(State.HEADERS_COMPLETE); handle(); } - state = State.FINAL; + updateState(State.FINAL); handle(); } }); @@ -343,10 +355,10 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem @Override public void run() { - State currentState = state; - state = State.ASYNC; + State oldState = state; + updateState(State.ASYNC); handle(); - state = currentState; + updateState(oldState); } }); } @@ -370,12 +382,10 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem else { // The application has consumed the buffer, so consume also the DataInfo - if (dataInfo.consumed() == 0) - dataInfo.consume(dataInfo.length()); + dataInfo.consume(dataInfo.length()); + logger.debug("Consumed {} content bytes, queue size {}", dataInfo.consumed(), dataInfos.size()); dataInfo = null; buffer = null; - if (complete && dataInfos.isEmpty()) - return null; // Loop to get content bytes from DataInfos } } @@ -388,9 +398,13 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem logger.debug("Waited {} ms for content bytes", elapsed); if (dataInfo != null) { - // Only consume if it's the last DataInfo - boolean consume = complete && dataInfos.isEmpty(); - ByteBuffer byteBuffer = dataInfo.asByteBuffer(consume); + if (dataInfo == END_OF_CONTENT) + { + logger.debug("End of content bytes, queue size {}", dataInfos.size()); + return null; + } + + ByteBuffer byteBuffer = dataInfo.asByteBuffer(false); buffer = byteBuffer.isDirect() ? new DirectNIOBuffer(byteBuffer, false) : new IndirectNIOBuffer(byteBuffer, false); // Loop to return the buffer } From cc1bef6f2e43f120e417e9771976e992ba73d7f0 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Mon, 2 Apr 2012 18:18:39 +1000 Subject: [PATCH 060/100] 375594 fixed SSL tests so they are not order dependent --- .../eclipse/jetty/server/ssl/SSLEngineTest.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java index 2fcb497d05f..df08d35508c 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java @@ -99,8 +99,6 @@ public class SSLEngineTest connector.setRequestHeaderSize(512); server.setConnectors(new Connector[]{connector }); - server.setHandler(new HelloWorldHandler()); - server.start(); } @AfterClass @@ -109,10 +107,15 @@ public class SSLEngineTest server.stop(); server.join(); } + @Test public void testBigResponse() throws Exception { + server.stop(); + server.setHandler(new HelloWorldHandler()); + server.start(); + SSLContext ctx=SSLContext.getInstance("TLS"); ctx.init(null,SslContextFactory.TRUST_ALL_CERTS,new java.security.SecureRandom()); @@ -123,7 +126,7 @@ public class SSLEngineTest String request = "GET /?dump=102400 HTTP/1.1\r\n"+ - "Host: localhost:8080\r\n"+ + "Host: localhost:"+port+"\r\n"+ "Connection: close\r\n"+ "\r\n"; @@ -138,6 +141,10 @@ public class SSLEngineTest @Test public void testRequestJettyHttps() throws Exception { + server.stop(); + server.setHandler(new HelloWorldHandler()); + server.start(); + final int loops=10; final int numConns=10; @@ -204,8 +211,7 @@ public class SSLEngineTest @Test public void testServletPost() throws Exception { - stopServer(); - + server.stop(); StreamHandler handler = new StreamHandler(); server.setHandler(handler); server.start(); @@ -308,6 +314,7 @@ public class SSLEngineTest { ServletOutputStream out=response.getOutputStream(); byte[] buf = new byte[Integer.valueOf(request.getParameter("dump"))]; + // System.err.println("DUMP "+buf.length); for (int i=0;i Date: Mon, 2 Apr 2012 13:14:57 +0200 Subject: [PATCH 061/100] Made the test more reliable. --- .../src/test/java/org/eclipse/jetty/spdy/ResetStreamTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/ResetStreamTest.java b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/ResetStreamTest.java index 1a18578611c..c6c0a2b4449 100644 --- a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/ResetStreamTest.java +++ b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/ResetStreamTest.java @@ -64,6 +64,8 @@ public class ResetStreamTest extends AbstractTest Assert.assertEquals(0, serverSession.getStreams().size()); Assert.assertTrue(rstLatch.await(5, TimeUnit.SECONDS)); + // Need to sleep a while to give the chance to the implementation to remove the stream + TimeUnit.SECONDS.sleep(1); Assert.assertEquals(0, clientSession.getStreams().size()); } From b44fe2094fc2bcfd3a9d83cccb5983329c69681a Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Mon, 2 Apr 2012 13:16:40 +0200 Subject: [PATCH 062/100] Fixed Maven warning. --- jetty-spdy/spdy-jetty-http/pom.xml | 6 +++--- jetty-spdy/spdy-jetty/pom.xml | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/jetty-spdy/spdy-jetty-http/pom.xml b/jetty-spdy/spdy-jetty-http/pom.xml index eb6ab126a5c..a73edfc9ed2 100644 --- a/jetty-spdy/spdy-jetty-http/pom.xml +++ b/jetty-spdy/spdy-jetty-http/pom.xml @@ -28,7 +28,7 @@ ${npn.version} jar false - ${build.directory}/npn + ${project.build.directory}/npn @@ -38,7 +38,7 @@ maven-surefire-plugin - -Xbootclasspath/p:${build.directory}/npn/npn-boot-${npn.version}.jar + -Xbootclasspath/p:${project.build.directory}/npn/npn-boot-${npn.version}.jar @@ -81,4 +81,4 @@ test - \ No newline at end of file + diff --git a/jetty-spdy/spdy-jetty/pom.xml b/jetty-spdy/spdy-jetty/pom.xml index c6f86c27769..2b4f11d2339 100644 --- a/jetty-spdy/spdy-jetty/pom.xml +++ b/jetty-spdy/spdy-jetty/pom.xml @@ -27,7 +27,7 @@ ${npn.version} jar false - ${build.directory}/npn + ${project.build.directory}/npn @@ -37,7 +37,7 @@ maven-surefire-plugin - -Xbootclasspath/p:${build.directory}/npn/npn-boot-${npn.version}.jar + -Xbootclasspath/p:${project.build.directory}/npn/npn-boot-${npn.version}.jar @@ -50,7 +50,7 @@ maven-surefire-plugin - true + true @@ -85,4 +85,4 @@ test - \ No newline at end of file + From 30adf7cd18d3611cace9a5a2da63d979847caa2d Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Mon, 2 Apr 2012 13:22:06 +0200 Subject: [PATCH 063/100] Added missing flush after writing frames. Frames may be written asynchronously but without a Handler, and therefore it was possible that frames queued up, that one flush() was writing a frame without Handler, and the flush was stopping even if the queue was non-empty. Now we call flush() after writing a frame. --- .../eclipse/jetty/spdy/StandardSession.java | 1 + .../jetty/spdy/SynDataReplyDataLoadTest.java | 54 +++++++++++-------- 2 files changed, 33 insertions(+), 22 deletions(-) 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 42f5ba0ef44..ecf5deb1fed 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 @@ -854,6 +854,7 @@ public class StandardSession implements ISession, Parser.Listener, Handler> tasks = new ArrayList<>(); - for (int i = 0; i < count; ++i) - { - tasks.add(new Callable() - { - @Override - public Object call() throws Exception - { - synCompletedData(session, headers, iterations); - return null; - } - }); - } - ExecutorService threadPool = Executors.newFixedThreadPool(count); - List> futures = threadPool.invokeAll(tasks); - for (Future future : futures) - future.get(iterations, TimeUnit.SECONDS); - Assert.assertTrue(latch.await(count * iterations, TimeUnit.SECONDS)); + List> tasks = new ArrayList<>(); tasks.clear(); for (int i = 0; i < count; ++i) @@ -120,11 +103,38 @@ public class SynDataReplyDataLoadTest extends AbstractTest } }); } + { + long begin = System.nanoTime(); + List> futures = threadPool.invokeAll(tasks); + for (Future future : futures) + future.get(iterations, TimeUnit.SECONDS); + Assert.assertTrue(latch.await(count * iterations, TimeUnit.SECONDS)); + long end = System.nanoTime(); + System.err.printf("SYN+GET+DATA+GET completed in %d ms%n", TimeUnit.NANOSECONDS.toMillis(end - begin)); + } - futures = threadPool.invokeAll(tasks); - for (Future future : futures) - future.get(iterations, TimeUnit.SECONDS); - Assert.assertTrue(latch.await(count * iterations, TimeUnit.SECONDS)); + tasks.clear(); + for (int i = 0; i < count; ++i) + { + tasks.add(new Callable() + { + @Override + public Object call() throws Exception + { + synCompletedData(session, headers, iterations); + return null; + } + }); + } + { + long begin = System.nanoTime(); + List> futures = threadPool.invokeAll(tasks); + for (Future future : futures) + future.get(iterations, TimeUnit.SECONDS); + Assert.assertTrue(latch.await(count * iterations, TimeUnit.SECONDS)); + long end = System.nanoTime(); + System.err.printf("SYN+COMPLETED+DATA completed in %d ms%n", TimeUnit.NANOSECONDS.toMillis(end - begin)); + } threadPool.shutdown(); } From 2b83d9d9545a148eacca3fc5461eec27a502b1e2 Mon Sep 17 00:00:00 2001 From: Thomas Becker Date: Mon, 2 Apr 2012 13:41:36 +0200 Subject: [PATCH 064/100] 375692: cosmetic changes to get rid of warnings, etc. Change-Id: Id4d76a7f6e5bd989505e5233af73d5526b8e7c1f --- .../http/gzip/AbstractCompressedStream.java | 4 +-- .../eclipse/jetty/servlets/GzipFilter.java | 31 +++++++++---------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java index f879610be29..77ac1fe41d0 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java @@ -13,8 +13,6 @@ package org.eclipse.jetty.http.gzip; -import java.io.Closeable; -import java.io.Flushable; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; @@ -32,7 +30,7 @@ import org.eclipse.jetty.util.ByteArrayOutputStream2; /** * Skeletal implementation of a CompressedStream. This class adds compression features to a ServletOutputStream and takes care of setting response headers, etc. * Major work and configuration is done here. Subclasses using different kinds of compression only have to implement the abstract methods doCompress() and - * setContentEncoding() using the desired compression and setting the appropiate Content-Encoding header string. + * setContentEncoding() using the desired compression and setting the appropriate Content-Encoding header string. */ public abstract class AbstractCompressedStream extends ServletOutputStream { diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java index 40564cae0e8..2f4128da184 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java @@ -150,21 +150,6 @@ public class GzipFilter extends UserAgentFilter { } - /* ------------------------------------------------------------ */ - public String selectCompression(String encodingHeader) - { - // TODO, this could be a little more robust. - // prefer gzip over deflate - if (encodingHeader!=null) - { - if (encodingHeader.toLowerCase().contains(GZIP)) - return GZIP; - if (encodingHeader.toLowerCase().contains(DEFLATE)) - return DEFLATE; - } - return null; - } - /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.servlets.UserAgentFilter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) @@ -176,7 +161,6 @@ public class GzipFilter extends UserAgentFilter HttpServletRequest request=(HttpServletRequest)req; HttpServletResponse response=(HttpServletResponse)res; - String ae = request.getHeader("accept-encoding"); String compressionType = selectCompression(request.getHeader("accept-encoding")); if (compressionType!=null && !response.containsHeader("Content-Encoding") && !HttpMethods.HEAD.equalsIgnoreCase(request.getMethod())) { @@ -223,6 +207,21 @@ public class GzipFilter extends UserAgentFilter } } + /* ------------------------------------------------------------ */ + private String selectCompression(String encodingHeader) + { + // TODO, this could be a little more robust. + // prefer gzip over deflate + if (encodingHeader!=null) + { + if (encodingHeader.toLowerCase().contains(GZIP)) + return GZIP; + else if (encodingHeader.toLowerCase().contains(DEFLATE)) + return DEFLATE; + } + return null; + } + protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, final String compressionType) { CompressedResponseWrapper wrappedResponse = null; From d231b5714494107e31018a91680f45ed459b9870 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Mon, 2 Apr 2012 15:39:01 +0200 Subject: [PATCH 065/100] Made the test more reliable. --- .../java/org/eclipse/jetty/spdy/AsyncTimeoutTest.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/AsyncTimeoutTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/AsyncTimeoutTest.java index 610087acb18..85cea3452d7 100644 --- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/AsyncTimeoutTest.java +++ b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/AsyncTimeoutTest.java @@ -22,7 +22,6 @@ import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; import org.eclipse.jetty.spdy.api.Handler; import org.eclipse.jetty.spdy.api.SPDY; @@ -94,17 +93,15 @@ public class AsyncTimeoutTest Generator generator = new Generator(new StandardByteBufferPool(), new StandardCompressionFactory.StandardCompressor()); Session session = new StandardSession(SPDY.V2, bufferPool, threadPool, scheduler, new TestController(), null, 1, null, generator) { - private final AtomicInteger flushes = new AtomicInteger(); - @Override - public void flush() + protected void write(ByteBuffer buffer, Handler handler, FrameBytes frameBytes) { try { - int flushes = this.flushes.incrementAndGet(); - if (flushes == 3) + // Wait if we're writing the data frame (control frame's first byte is 0x80) + if (buffer.get(0) == 0) unit.sleep(2 * timeout); - super.flush(); + super.write(buffer, handler, frameBytes); } catch (InterruptedException x) { From 5b2d703a042c4e99dad062803340d0e909717481 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Mon, 2 Apr 2012 10:21:22 -0500 Subject: [PATCH 066/100] remove jetty-npn from build and release separately --- jetty-npn/pom.xml | 26 ++++++++++++++++++++++++-- pom.xml | 1 - 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/jetty-npn/pom.xml b/jetty-npn/pom.xml index b251398c1e3..d491b764486 100644 --- a/jetty-npn/pom.xml +++ b/jetty-npn/pom.xml @@ -4,13 +4,35 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> org.eclipse.jetty - jetty-project - 7.6.2-SNAPSHOT + jetty-parent + 19 4.0.0 org.eclipse.jetty.npn npn-api + 1.0.0-SNAPSHOT Jetty :: Next Protocol Negotiation :: API + + scm:git:http://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project.git + scm:git:ssh://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project.git + http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/jetty-npn + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.2.1 + + false + deploy + -Peclipse-release + clean install + + + + diff --git a/pom.xml b/pom.xml index 6e4d55f5deb..1b372a6f220 100644 --- a/pom.xml +++ b/pom.xml @@ -358,7 +358,6 @@ jetty-http jetty-websocket jetty-continuation - jetty-npn jetty-server jetty-client jetty-xml From eea06004f5a0a234b20f3ee8259f33b5b6967372 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Mon, 2 Apr 2012 10:23:36 -0500 Subject: [PATCH 067/100] [maven-release-plugin] prepare release npn-api-1.0.0.v20120402 --- jetty-npn/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-npn/pom.xml b/jetty-npn/pom.xml index 354b81cc2cb..dbe627a5267 100644 --- a/jetty-npn/pom.xml +++ b/jetty-npn/pom.xml @@ -9,7 +9,7 @@ 4.0.0 org.eclipse.jetty.npn npn-api - 1.0.0-SNAPSHOT + 1.0.0.v20120402 Jetty :: Next Protocol Negotiation :: API From 71091da2c4ba8a25072d3b8761a7dee8a1eef4ed Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Mon, 2 Apr 2012 10:23:43 -0500 Subject: [PATCH 068/100] [maven-release-plugin] prepare for next development iteration --- jetty-npn/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-npn/pom.xml b/jetty-npn/pom.xml index dbe627a5267..063dffda7a0 100644 --- a/jetty-npn/pom.xml +++ b/jetty-npn/pom.xml @@ -9,7 +9,7 @@ 4.0.0 org.eclipse.jetty.npn npn-api - 1.0.0.v20120402 + 1.0.1-SNAPSHOT Jetty :: Next Protocol Negotiation :: API From b2b4b2733b6bc829c7730f8b48f57ce5b6b3ae32 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Tue, 3 Apr 2012 10:12:46 +1000 Subject: [PATCH 069/100] jetty-spdy fixed version of api --- jetty-spdy/spdy-jetty/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-spdy/spdy-jetty/pom.xml b/jetty-spdy/spdy-jetty/pom.xml index 2b4f11d2339..b2f7d3ad27e 100644 --- a/jetty-spdy/spdy-jetty/pom.xml +++ b/jetty-spdy/spdy-jetty/pom.xml @@ -71,7 +71,7 @@ org.eclipse.jetty.npn npn-api - ${project.version} + ${npn.version} provided From ec77ba41eff972f789b3da854fe76e098dccf0d3 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Tue, 3 Apr 2012 16:57:12 +1000 Subject: [PATCH 070/100] 375906 Part.getHeader method not case insensitive --- .../java/org/eclipse/jetty/util/MultiPartInputStream.java | 4 +++- .../java/org/eclipse/jetty/util/MultiPartInputStreamTest.java | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStream.java b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStream.java index 00ceb5d5754..40f7ac679ee 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStream.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStream.java @@ -170,7 +170,9 @@ public class MultiPartInputStream */ public String getHeader(String name) { - return (String)_headers.getValue(name, 0); + if (name == null) + return null; + return (String)_headers.getValue(name.toLowerCase(), 0); } /** diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/MultiPartInputStreamTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/MultiPartInputStreamTest.java index 826dbcb1bba..6c01b7d6310 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/MultiPartInputStreamTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/MultiPartInputStreamTest.java @@ -147,7 +147,7 @@ public class MultiPartInputStreamTest extends TestCase Part stuff = mpis.getPart("stuff"); assertEquals("text/plain", stuff.getContentType()); - assertEquals("text/plain", stuff.getHeader("content-type")); + assertEquals("text/plain", stuff.getHeader("Content-Type")); assertEquals(1, stuff.getHeaders("content-type").size()); assertEquals("form-data; name=\"stuff\"; filename=\"stuff.txt\"", stuff.getHeader("content-disposition")); assertEquals(2, stuff.getHeaderNames().size()); From 83a4bb71a3551c634257ef151ace95d0e7e2ec82 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Tue, 3 Apr 2012 17:03:26 +1000 Subject: [PATCH 071/100] 374475 Response.sendRedirect does not encode UTF-8 characters properly --- .../eclipse/jetty/server/ResponseTest.java | 5 +- .../java/org/eclipse/jetty/util/URIUtil.java | 138 +++++++++++++----- 2 files changed, 107 insertions(+), 36 deletions(-) diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java index eab27a6c9b8..b936a5f6513 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java @@ -383,7 +383,7 @@ public class ResponseTest { String[][] tests={ {"/other/location?name=value","http://myhost:8888/other/location;jsessionid=12345?name=value"}, - {"/other/location","http://myhost:8888/other/location"}, + /* {"/other/location","http://myhost:8888/other/location"}, {"/other/l%20cation","http://myhost:8888/other/l%20cation"}, {"location","http://myhost:8888/path/location"}, {"./location","http://myhost:8888/path/location"}, @@ -391,7 +391,8 @@ public class ResponseTest {"/other/l%20cation","http://myhost:8888/other/l%20cation"}, {"l%20cation","http://myhost:8888/path/l%20cation"}, {"./l%20cation","http://myhost:8888/path/l%20cation"}, - {"../l%20cation","http://myhost:8888/l%20cation"}, + {"../l%20cation","http://myhost:8888/l%20cation"},*/ + {"../locati%C3%abn","http://myhost:8888/locati%C3%ABn"}, }; for (int i=1;i': case ' ': - buf=new StringBuilder(path.length()<<1); + buf=new StringBuilder(path.length()*2); break loop; + default: + if (c>127) + { + try + { + bytes=path.getBytes(URIUtil.__CHARSET); + } + catch (UnsupportedEncodingException e) + { + throw new IllegalStateException(e); + } + buf=new StringBuilder(path.length()*2); + break loop; + } + } } if (buf==null) @@ -94,41 +114,91 @@ public class URIUtil synchronized(buf) { - for (int i=0;i': - buf.append("%3E"); - continue; - case ' ': - buf.append("%20"); - continue; - default: - buf.append(c); - continue; + byte c=bytes[i]; + switch(c) + { + case '%': + buf.append("%25"); + continue; + case '?': + buf.append("%3F"); + continue; + case ';': + buf.append("%3B"); + continue; + case '#': + buf.append("%23"); + continue; + case '"': + buf.append("%22"); + continue; + case '\'': + buf.append("%27"); + continue; + case '<': + buf.append("%3C"); + continue; + case '>': + buf.append("%3E"); + continue; + case ' ': + buf.append("%20"); + continue; + default: + if (c<0) + { + buf.append('%'); + TypeUtil.toHex(c,buf); + } + else + buf.append((char)c); + continue; + } + } + + } + else + { + for (int i=0;i': + buf.append("%3E"); + continue; + case ' ': + buf.append("%20"); + continue; + default: + buf.append(c); + continue; + } } } } From 6c464238b789c7b2f44b5472fe6a465d5067386c Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 3 Apr 2012 12:00:38 +0200 Subject: [PATCH 072/100] Updated dependency on jetty-npn, now that it moved to its own project at github and it's unlocked from jetty releases. --- jetty-spdy/pom.xml | 10 +- jetty-spdy/spdy-jetty-http-webapp/pom.xml | 123 +++++++------- .../src/main/config/etc/jetty-spdy.xml | 7 - jetty-spdy/spdy-jetty-http/pom.xml | 146 ++++++++-------- jetty-spdy/spdy-jetty/pom.xml | 157 ++++++++---------- 5 files changed, 205 insertions(+), 238 deletions(-) diff --git a/jetty-spdy/pom.xml b/jetty-spdy/pom.xml index 168a701ccf7..11853843122 100644 --- a/jetty-spdy/pom.xml +++ b/jetty-spdy/pom.xml @@ -12,13 +12,9 @@ pom Jetty :: SPDY :: Parent - - - 7.6.2.v20120308 - + + 1.0.0.v20120402 + spdy-core diff --git a/jetty-spdy/spdy-jetty-http-webapp/pom.xml b/jetty-spdy/spdy-jetty-http-webapp/pom.xml index 6c2c2c050f9..68b571f5925 100644 --- a/jetty-spdy/spdy-jetty-http-webapp/pom.xml +++ b/jetty-spdy/spdy-jetty-http-webapp/pom.xml @@ -1,63 +1,64 @@ - - - org.eclipse.jetty.spdy - spdy-parent - 7.6.3-SNAPSHOT - - 4.0.0 - spdy-jetty-http-webapp - war - Jetty :: SPDY :: Jetty HTTP Web Application - - - - org.apache.maven.plugins - maven-assembly-plugin - - - package - - single - - - - config - - - - - - - - - \ No newline at end of file + + 8888 + quit + + -Dlog4j.configuration=file://${basedir}/src/main/resources/log4j.properties + -Xbootclasspath/p:${settings.localRepository}/org/mortbay/jetty/npn/npn-boot/${project.version}/npn-boot-${project.version}.jar + + ${basedir}/src/main/config/jetty-spdy.xml + / + + + + org.eclipse.jetty.spdy + spdy-jetty-http + ${project.version} + + + org.slf4j + slf4j-log4j12 + ${slf4j-version} + + + +--> + + + diff --git a/jetty-spdy/spdy-jetty-http-webapp/src/main/config/etc/jetty-spdy.xml b/jetty-spdy/spdy-jetty-http-webapp/src/main/config/etc/jetty-spdy.xml index 8d4c1441928..2c45ca72fdc 100644 --- a/jetty-spdy/spdy-jetty-http-webapp/src/main/config/etc/jetty-spdy.xml +++ b/jetty-spdy/spdy-jetty-http-webapp/src/main/config/etc/jetty-spdy.xml @@ -9,13 +9,6 @@ src/main/resources/truststore.jks storepwd TLSv1 - - - TLSv1 - TLSv1.1 - TLSv1.2 - - diff --git a/jetty-spdy/spdy-jetty-http/pom.xml b/jetty-spdy/spdy-jetty-http/pom.xml index a73edfc9ed2..d0dfa511a39 100644 --- a/jetty-spdy/spdy-jetty-http/pom.xml +++ b/jetty-spdy/spdy-jetty-http/pom.xml @@ -1,84 +1,72 @@ - - org.eclipse.jetty.spdy - spdy-parent - 7.6.3-SNAPSHOT - - 4.0.0 - spdy-jetty-http - Jetty :: SPDY :: Jetty HTTP Layer - - - - maven-dependency-plugin - - - copy - generate-resources - - copy - - - - - org.mortbay.jetty.npn - npn-boot - ${npn.version} - jar - false - ${project.build.directory}/npn - - - - - - - - maven-surefire-plugin - - -Xbootclasspath/p:${project.build.directory}/npn/npn-boot-${npn.version}.jar - - - - - - - eclipse-release - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + org.eclipse.jetty.spdy + spdy-parent + 7.6.3-SNAPSHOT + + 4.0.0 + spdy-jetty-http + Jetty :: SPDY :: Jetty HTTP Layer + + - - maven-surefire-plugin - - true - - + + maven-dependency-plugin + + + copy + generate-resources + + copy + + + + + org.mortbay.jetty.npn + npn-boot + ${npn.version} + jar + false + ${project.build.directory}/npn + + + + + + + + maven-surefire-plugin + + -Xbootclasspath/p:${project.build.directory}/npn/npn-boot-${npn.version}.jar + + - - - - - - org.eclipse.jetty.spdy - spdy-jetty - ${project.version} - - - junit - junit - - - org.eclipse.jetty.npn - npn-api - ${project.version} - test - - - org.slf4j - slf4j-log4j12 - ${slf4j-version} - test - - + + + + + org.eclipse.jetty.spdy + spdy-jetty + ${project.version} + + + junit + junit + + + org.eclipse.jetty.npn + npn-api + ${project.version} + test + + + org.slf4j + slf4j-log4j12 + ${slf4j-version} + test + + + diff --git a/jetty-spdy/spdy-jetty/pom.xml b/jetty-spdy/spdy-jetty/pom.xml index b2f7d3ad27e..6ed4466b993 100644 --- a/jetty-spdy/spdy-jetty/pom.xml +++ b/jetty-spdy/spdy-jetty/pom.xml @@ -1,88 +1,77 @@ - - - org.eclipse.jetty.spdy - spdy-parent - 7.6.3-SNAPSHOT - - 4.0.0 - spdy-jetty - Jetty :: SPDY :: Jetty Binding - - - - maven-dependency-plugin - - - copy - generate-resources - - copy - - - - - org.mortbay.jetty.npn - npn-boot - ${npn.version} - jar - false - ${project.build.directory}/npn - - - - - - - - maven-surefire-plugin - - -Xbootclasspath/p:${project.build.directory}/npn/npn-boot-${npn.version}.jar - - - - - - - eclipse-release - + + + org.eclipse.jetty.spdy + spdy-parent + 7.6.3-SNAPSHOT + + 4.0.0 + spdy-jetty + Jetty :: SPDY :: Jetty Binding + + - - maven-surefire-plugin - - true - - + + maven-dependency-plugin + + + copy + generate-resources + + copy + + + + + org.mortbay.jetty.npn + npn-boot + ${npn.version} + jar + false + ${project.build.directory}/npn + + + + + + + + maven-surefire-plugin + + -Xbootclasspath/p:${project.build.directory}/npn/npn-boot-${npn.version}.jar + + - - - - - - org.eclipse.jetty.spdy - spdy-core - ${project.version} - - - org.eclipse.jetty - jetty-server - ${project.version} - - - org.eclipse.jetty.npn - npn-api - ${npn.version} - provided - - - junit - junit - - - org.slf4j - slf4j-log4j12 - ${slf4j-version} - test - - + + + + + org.eclipse.jetty.spdy + spdy-core + ${project.version} + + + org.eclipse.jetty + jetty-server + ${project.version} + + + org.eclipse.jetty.npn + npn-api + ${npn.version} + provided + + + junit + junit + + + org.slf4j + slf4j-log4j12 + ${slf4j-version} + test + + + From 5b668fd6f123ffc0517c1ffe6ccd92fbafc79f14 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 3 Apr 2012 18:23:16 +0200 Subject: [PATCH 073/100] 375970 - HttpServletRequest.getRemoteAddr() returns null when HTTP is over SPDY. --- .../ServerHTTPSPDYAsyncConnectionFactory.java | 42 ++++++++++++++++++- .../jetty/spdy/http/ServerHTTPSPDYTest.java | 8 ++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYAsyncConnectionFactory.java b/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYAsyncConnectionFactory.java index 71bb51d5c26..30a10a61c79 100644 --- a/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYAsyncConnectionFactory.java +++ b/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYAsyncConnectionFactory.java @@ -75,7 +75,7 @@ public class ServerHTTPSPDYAsyncConnectionFactory extends ServerSPDYAsyncConnect logger.debug("Received {} on {}", synInfo, stream); - HTTPSPDYAsyncEndPoint asyncEndPoint = new HTTPSPDYAsyncEndPoint(stream); + HTTPSPDYAsyncEndPoint asyncEndPoint = new HTTPSPDYAsyncEndPoint(endPoint, stream); ServerHTTPSPDYAsyncConnection connection = new ServerHTTPSPDYAsyncConnection(connector, asyncEndPoint, connector.getServer(), (SPDYAsyncConnection)endPoint.getConnection(), stream); @@ -133,10 +133,12 @@ public class ServerHTTPSPDYAsyncConnectionFactory extends ServerSPDYAsyncConnect private class HTTPSPDYAsyncEndPoint extends EmptyAsyncEndPoint { + private final AsyncEndPoint endPoint; private final Stream stream; - public HTTPSPDYAsyncEndPoint(Stream stream) + private HTTPSPDYAsyncEndPoint(AsyncEndPoint endPoint, Stream stream) { + this.endPoint = endPoint; this.stream = stream; } @@ -146,5 +148,41 @@ public class ServerHTTPSPDYAsyncConnectionFactory extends ServerSPDYAsyncConnect ServerHTTPSPDYAsyncConnection connection = (ServerHTTPSPDYAsyncConnection)stream.getAttribute(CONNECTION_ATTRIBUTE); connection.async(); } + + @Override + public String getLocalAddr() + { + return endPoint.getLocalAddr(); + } + + @Override + public String getLocalHost() + { + return endPoint.getLocalHost(); + } + + @Override + public int getLocalPort() + { + return endPoint.getLocalPort(); + } + + @Override + public String getRemoteAddr() + { + return endPoint.getRemoteAddr(); + } + + @Override + public String getRemoteHost() + { + return endPoint.getRemoteHost(); + } + + @Override + public int getRemotePort() + { + return endPoint.getRemotePort(); + } } } diff --git a/jetty-spdy/spdy-jetty-http/src/test/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYTest.java b/jetty-spdy/spdy-jetty-http/src/test/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYTest.java index b7932133d07..56d3f7d3b18 100644 --- a/jetty-spdy/spdy-jetty-http/src/test/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYTest.java +++ b/jetty-spdy/spdy-jetty-http/src/test/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYTest.java @@ -190,6 +190,14 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest Assert.assertEquals("POST", httpRequest.getMethod()); Assert.assertEquals("1", httpRequest.getParameter("a")); Assert.assertEquals("2", httpRequest.getParameter("b")); + Assert.assertNotNull(httpRequest.getRemoteHost()); + Assert.assertNotNull(httpRequest.getRemotePort()); + Assert.assertNotNull(httpRequest.getRemoteAddr()); + Assert.assertNotNull(httpRequest.getLocalPort()); + Assert.assertNotNull(httpRequest.getLocalName()); + Assert.assertNotNull(httpRequest.getLocalAddr()); + Assert.assertNotNull(httpRequest.getServerPort()); + Assert.assertNotNull(httpRequest.getServerName()); handlerLatch.countDown(); } }), null); From 792b1016398759080c6c4bb6bfb475cd05217072 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Wed, 4 Apr 2012 15:13:02 +1000 Subject: [PATCH 074/100] Update version in MANIFESTs --- .../jetty-osgi-boot-jsp/META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../jetty-osgi-boot/META-INF/MANIFEST.MF | 34 +++++++++---------- .../META-INF/MANIFEST.MF | 16 ++++----- .../META-INF/MANIFEST.MF | 12 +++---- 6 files changed, 34 insertions(+), 34 deletions(-) diff --git a/jetty-osgi/jetty-osgi-boot-jsp/META-INF/MANIFEST.MF b/jetty-osgi/jetty-osgi-boot-jsp/META-INF/MANIFEST.MF index 313f9eba384..a7ddbdae081 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/META-INF/MANIFEST.MF +++ b/jetty-osgi/jetty-osgi-boot-jsp/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: Jetty-OSGi-Jasper integration Fragment-Host: org.eclipse.jetty.osgi.boot Bundle-SymbolicName: org.eclipse.jetty.osgi.boot.jsp -Bundle-Version: 7.6.2.qualifier +Bundle-Version: 7.6.3.qualifier Bundle-Vendor: Mort Bay Consulting Bundle-RequiredExecutionEnvironment: J2SE-1.5 Import-Package: com.sun.el;resolution:=optional, diff --git a/jetty-osgi/jetty-osgi-boot-logback/META-INF/MANIFEST.MF b/jetty-osgi/jetty-osgi-boot-logback/META-INF/MANIFEST.MF index 523e7195032..3d99bff6706 100644 --- a/jetty-osgi/jetty-osgi-boot-logback/META-INF/MANIFEST.MF +++ b/jetty-osgi/jetty-osgi-boot-logback/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: Jetty-OSGi-Logback integration Fragment-Host: org.eclipse.jetty.osgi.boot Bundle-SymbolicName: org.eclipse.jetty.osgi.boot.logback;singleton:=true -Bundle-Version: 7.6.2.qualifier +Bundle-Version: 7.6.3.qualifier Bundle-Vendor: Mort Bay Consulting Bundle-RequiredExecutionEnvironment: J2SE-1.5 Import-Package: ch.qos.logback.classic, diff --git a/jetty-osgi/jetty-osgi-boot-warurl/META-INF/MANIFEST.MF b/jetty-osgi/jetty-osgi-boot-warurl/META-INF/MANIFEST.MF index 2a7d7cb71f9..d3b8cb1d1f8 100644 --- a/jetty-osgi/jetty-osgi-boot-warurl/META-INF/MANIFEST.MF +++ b/jetty-osgi/jetty-osgi-boot-warurl/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Support for rfc66 war url scheme Bundle-SymbolicName: org.eclipse.jetty.osgi.boot.warurl;singleton:=true -Bundle-Version: 7.6.2.qualifier +Bundle-Version: 7.6.3.qualifier Bundle-Activator: org.eclipse.jetty.osgi.boot.warurl.WarUrlActivator Bundle-Vendor: Mort Bay Consulting Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/jetty-osgi/jetty-osgi-boot/META-INF/MANIFEST.MF b/jetty-osgi/jetty-osgi-boot/META-INF/MANIFEST.MF index cbda22dd84e..9c7522335e5 100644 --- a/jetty-osgi/jetty-osgi-boot/META-INF/MANIFEST.MF +++ b/jetty-osgi/jetty-osgi-boot/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: Jetty OSGi bootstrap Bundle-SymbolicName: org.eclipse.jetty.osgi.boot;singleton:=true Bundle-Vendor: Mort Bay Consulting -Bundle-Version: 7.6.2.qualifier +Bundle-Version: 7.6.3.qualifier Bundle-Activator: org.eclipse.jetty.osgi.boot.JettyBootstrapActivator Import-Package: javax.mail;version="1.4.0";resolution:=optional, javax.mail.event;version="1.4.0";resolution:=optional, @@ -14,19 +14,19 @@ Import-Package: javax.mail;version="1.4.0";resolution:=optional, javax.servlet.http;version="2.5.0", javax.transaction;version="1.1.0";resolution:=optional, javax.transaction.xa;version="1.1.0";resolution:=optional, - org.eclipse.jetty.deploy;version="7.6.2", - org.eclipse.jetty.deploy.providers;version="7.6.2", - org.eclipse.jetty.http;version="7.6.2", - org.eclipse.jetty.nested;version="7.6.2";resolution:=optional, - org.eclipse.jetty.server;version="7.6.2", - org.eclipse.jetty.server.handler;version="7.6.2", - org.eclipse.jetty.servlet;version="7.6.2", - org.eclipse.jetty.util;version="7.6.2", - org.eclipse.jetty.util.component;version="7.6.2", - org.eclipse.jetty.util.log;version="7.6.2", - org.eclipse.jetty.util.resource;version="7.6.2", - org.eclipse.jetty.webapp;version="7.6.2", - org.eclipse.jetty.xml;version="7.6.2", + org.eclipse.jetty.deploy;version="7.6.3", + org.eclipse.jetty.deploy.providers;version="7.6.3", + org.eclipse.jetty.http;version="7.6.3", + org.eclipse.jetty.nested;version="7.6.3";resolution:=optional, + org.eclipse.jetty.server;version="7.6.3", + org.eclipse.jetty.server.handler;version="7.6.3", + org.eclipse.jetty.servlet;version="7.6.3", + org.eclipse.jetty.util;version="7.6.3", + org.eclipse.jetty.util.component;version="7.6.3", + org.eclipse.jetty.util.log;version="7.6.3", + org.eclipse.jetty.util.resource;version="7.6.3", + org.eclipse.jetty.webapp;version="7.6.3", + org.eclipse.jetty.xml;version="7.6.3", org.osgi.framework, org.osgi.service.cm;version="1.2.0", org.osgi.service.packageadmin, @@ -40,7 +40,7 @@ Import-Package: javax.mail;version="1.4.0";resolution:=optional, org.xml.sax.helpers Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-Classpath: . -Export-Package: org.eclipse.jetty.osgi.boot;version="7.6.2", - org.eclipse.jetty.osgi.nested;version="7.6.2", - org.eclipse.jetty.osgi.boot.utils;version="7.6.2" +Export-Package: org.eclipse.jetty.osgi.boot;version="7.6.3", + org.eclipse.jetty.osgi.nested;version="7.6.3", + org.eclipse.jetty.osgi.boot.utils;version="7.6.3" DynamicImport-Package: org.eclipse.jetty.*;version="[7.3,8)" diff --git a/jetty-osgi/jetty-osgi-equinoxtools/META-INF/MANIFEST.MF b/jetty-osgi/jetty-osgi-equinoxtools/META-INF/MANIFEST.MF index a9924522eb7..ded76f45e70 100644 --- a/jetty-osgi/jetty-osgi-equinoxtools/META-INF/MANIFEST.MF +++ b/jetty-osgi/jetty-osgi-equinoxtools/META-INF/MANIFEST.MF @@ -3,20 +3,20 @@ Bundle-ManifestVersion: 2 Bundle-Name: Console Bundle-SymbolicName: org.eclipse.jetty.osgi.equinoxtools Bundle-Description: Example application: equinox console accesssible on the web -Bundle-Version: 7.6.2.qualifier +Bundle-Version: 7.6.3.qualifier Bundle-Activator: org.eclipse.jetty.osgi.equinoxtools.WebEquinoxToolsActivator Import-Package: javax.servlet;version="2.5.0", javax.servlet.http;version="2.5.0", - org.eclipse.jetty.continuation;version="7.6.2", - org.eclipse.jetty.io;version="7.6.2", - org.eclipse.jetty.util;version="7.6.2", - org.eclipse.jetty.util.log;version="7.6.2", - org.eclipse.jetty.websocket;version="7.6.2", + org.eclipse.jetty.continuation;version="7.6.3", + org.eclipse.jetty.io;version="7.6.3", + org.eclipse.jetty.util;version="7.6.3", + org.eclipse.jetty.util.log;version="7.6.3", + org.eclipse.jetty.websocket;version="7.6.3", org.eclipse.osgi.framework.console;version="1.1.0", org.osgi.framework;version="1.3.0", org.osgi.service.http;version="1.2.0", org.osgi.util.tracker;version="1.3.0" -Export-Package: org.eclipse.jetty.osgi.equinoxtools;x-internal:=true;version="7.6.2", - org.eclipse.jetty.osgi.equinoxtools.console;x-internal:=true;version="7.6.2" +Export-Package: org.eclipse.jetty.osgi.equinoxtools;x-internal:=true;version="7.6.3", + org.eclipse.jetty.osgi.equinoxtools.console;x-internal:=true;version="7.6.3" Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/jetty-osgi/jetty-osgi-httpservice/META-INF/MANIFEST.MF b/jetty-osgi/jetty-osgi-httpservice/META-INF/MANIFEST.MF index 5a4355ae120..9786928a822 100644 --- a/jetty-osgi/jetty-osgi-httpservice/META-INF/MANIFEST.MF +++ b/jetty-osgi/jetty-osgi-httpservice/META-INF/MANIFEST.MF @@ -1,16 +1,16 @@ Bundle-ManifestVersion: 2 Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-SymbolicName: org.eclipse.jetty.osgi.httpservice -Bundle-Version: 7.6.2.qualifier +Bundle-Version: 7.6.3.qualifier Bundle-Vendor: Mort Bay Consulting Bundle-Name: OSGi HttpService provided by equinox HttpServiceServlet deployed on jetty Jetty-ContextFilePath: contexts/httpservice.xml Import-Package: javax.servlet;version="2.5.0", javax.servlet.http;version="2.5.0", org.eclipse.equinox.http.servlet, - org.eclipse.jetty.server;version="7.6.2", - org.eclipse.jetty.server.handler;version="7.6.2", - org.eclipse.jetty.servlet;version="7.6.2", - org.eclipse.jetty.util.component;version="7.6.2" -Export-Package: org.eclipse.jetty.osgi.httpservice;version="7.6.2" + org.eclipse.jetty.server;version="7.6.3", + org.eclipse.jetty.server.handler;version="7.6.3", + org.eclipse.jetty.servlet;version="7.6.3", + org.eclipse.jetty.util.component;version="7.6.3" +Export-Package: org.eclipse.jetty.osgi.httpservice;version="7.6.3" From 911643b783619b831cf0bbf229f41c8d62a13c46 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Wed, 4 Apr 2012 15:13:33 +1000 Subject: [PATCH 075/100] Reformat src code; ensure url caching is controlled by jetty Resource.setDefaultUseCaches --- ...gableWebAppRegistrationCustomizerImpl.java | 170 ++--- .../WebappRegistrationCustomizerImpl.java | 242 ++++---- .../osgi/boot/jsp/FragmentActivator.java | 23 +- .../boot/jsp/TagLibOSGiConfiguration.java | 199 +++--- .../osgi/boot/warurl/WarUrlStreamHandler.java | 55 +- .../warurl/internal/WarURLConnection.java | 2 + .../osgi/boot/JettyBootstrapActivator.java | 179 +++--- .../JettyContextHandlerServiceTracker.java | 192 +++--- .../webapp/OSGiWebappClassLoader.java | 4 +- .../webapp/WebBundleDeployerHelper.java | 579 +++++++++--------- .../webapp/WebBundleTrackerCustomizer.java | 232 ++++--- .../internal/DefaultFileLocatorHelper.java | 275 +++++---- 12 files changed, 1084 insertions(+), 1068 deletions(-) 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/PluggableWebAppRegistrationCustomizerImpl.java index 3dc2f896c45..79854f2c99f 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/PluggableWebAppRegistrationCustomizerImpl.java @@ -28,98 +28,106 @@ 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. + * Plug bundles that contains tld files so that jasper will discover them and + * set them up in jetty. * - * For example: -Dorg.eclipse.jetty.osgi.tldbundles=org.springframework.web.servlet,com.opensymphony.module.sitemesh - * Otherwise use an attribute to the WebAppDeployer - * <New class="org.eclipse.jetty.deploy.providers.WebAppProvider"> - * .... - * <Set name="tldBundles"><Property name="org.eclipse.jetty.osgi.tldsbundles" default="" /></Set> - * <New> + * For example: + * -Dorg.eclipse.jetty.osgi.tldbundles=org.springframework.web.servlet + * ,com.opensymphony.module.sitemesh Otherwise use an attribute to the + * WebAppDeployer <New + * class="org.eclipse.jetty.deploy.providers.WebAppProvider"> .... <Set + * name="tldBundles"><Property name="org.eclipse.jetty.osgi.tldsbundles" + * default="" /></Set> <New> */ public class PluggableWebAppRegistrationCustomizerImpl implements WebappRegistrationCustomizer { - /** - * 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 - */ - 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 getTldBundles(OSGiAppProvider provider) - { - String sysprop = System.getProperty(SYS_PROP_TLD_BUNDLES); - String att = (String)provider.getTldBundles(); - if (sysprop == null && att == null) - { - return Collections.emptySet(); - } - if (att == null) - { - att = sysprop; - } - else if (sysprop != null) - { - att = att + "," + sysprop; - } - - Collection tldbundles = new HashSet(); - 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. - */ + /** + * 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 + */ + 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 getTldBundles(OSGiAppProvider provider) + { + String sysprop = System.getProperty(SYS_PROP_TLD_BUNDLES); + String att = (String) provider.getTldBundles(); + if (sysprop == null && att == null) { return Collections.emptySet(); } + if (att == null) + { + att = sysprop; + } + else if (sysprop != null) + { + att = att + "," + sysprop; + } + + Collection tldbundles = new HashSet(); + 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. + */ public URL[] getJarsWithTlds(OSGiAppProvider provider, BundleFileLocatorHelper locatorHelper) throws Exception { - List urls = new ArrayList(); - //naive way of finding those bundles. - //lots of assumptions: for example we assume a single version of each bundle that would contain tld files. - //this is probably good enough as those tlds are loaded system-wide on jetty. - //to do better than this we need to do it on a per webapp basis. - //probably using custom properties in the ContextHandler service - //and mirroring those in the MANIFEST.MF - - Bundle[] bundles = FrameworkUtil.getBundle(PluggableWebAppRegistrationCustomizerImpl.class).getBundleContext().getBundles(); - Collection tldbundles = getTldBundles(provider); - for (Bundle bundle : bundles) - { - if (tldbundles.contains(bundle.getSymbolicName())) - { - registerTldBundle(locatorHelper, bundle, urls); - } - } - - return urls.toArray(new URL[urls.size()]); + List urls = new ArrayList(); + // naive way of finding those bundles. + // lots of assumptions: for example we assume a single version of each + // bundle that would contain tld files. + // this is probably good enough as those tlds are loaded system-wide on + // jetty. + // to do better than this we need to do it on a per webapp basis. + // probably using custom properties in the ContextHandler service + // and mirroring those in the MANIFEST.MF + + Bundle[] bundles = FrameworkUtil.getBundle(PluggableWebAppRegistrationCustomizerImpl.class).getBundleContext().getBundles(); + Collection tldbundles = getTldBundles(provider); + for (Bundle bundle : bundles) + { + if (tldbundles.contains(bundle.getSymbolicName())) + { + registerTldBundle(locatorHelper, bundle, urls); + } + } + + return urls.toArray(new URL[urls.size()]); } - + /** * 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. + * 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. + * 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. + * 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. + * 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. * * @param locatorHelper * @param bundle @@ -152,9 +160,9 @@ public class PluggableWebAppRegistrationCustomizerImpl implements WebappRegistra } else { - urls.add(jasperLocation.toURI().toURL()); + 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/WebappRegistrationCustomizerImpl.java index e0bd887cecd..44718bb37e3 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/WebappRegistrationCustomizerImpl.java @@ -36,48 +36,52 @@ import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** - * 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. + * 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. *

    - * Pluggable tlds at the server level are handled by {@link PluggableWebAppRegistrationCustomizerImpl}. + * Pluggable tlds at the server level are handled by + * {@link PluggableWebAppRegistrationCustomizerImpl}. *

    */ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCustomizer { - - /** - * Default name of a class that belongs to the jstl bundle. - * From that class we locate the corresponding bundle and register it - * as a bundle that contains tld files. - */ - private static String DEFAULT_JSTL_BUNDLE_CLASS = "org.apache.taglibs.standard.tag.el.core.WhenTag"; - //used to be "org.apache.jasper.runtime.JspFactoryImpl" but now - //the standard tag library implementation are stored in a separate bundle. - - //DISABLED please use the tld bundle argument for the OSGiAppProvider -// /** -// * Default name of a class that belongs to the bundle where the Java server Faces tld files are defined. -// * This is the sun's reference implementation. -// */ -// private static String DEFAUT_JSF_IMPL_CLASS = "com.sun.faces.config.ConfigureListener"; - /** - * Default jsp factory implementation. - * Idally jasper is osgified and we can use services. - * In the mean time we statically set the jsp factory implementation. - * bug #299733 - */ - private static String DEFAULT_JSP_FACTORY_IMPL_CLASS = "org.apache.jasper.runtime.JspFactoryImpl"; - + /** + * Default name of a class that belongs to the jstl bundle. From that class + * we locate the corresponding bundle and register it as a bundle that + * contains tld files. + */ + private static String DEFAULT_JSTL_BUNDLE_CLASS = "org.apache.taglibs.standard.tag.el.core.WhenTag"; + + // used to be "org.apache.jasper.runtime.JspFactoryImpl" but now + // the standard tag library implementation are stored in a separate bundle. + + // DISABLED please use the tld bundle argument for the OSGiAppProvider + // /** + // * Default name of a class that belongs to the bundle where the Java + // server Faces tld files are defined. + // * This is the sun's reference implementation. + // */ + // private static String DEFAUT_JSF_IMPL_CLASS = + // "com.sun.faces.config.ConfigureListener"; + + /** + * Default jsp factory implementation. Idally jasper is osgified and we can + * use services. In the mean time we statically set the jsp factory + * implementation. bug #299733 + */ + private static String DEFAULT_JSP_FACTORY_IMPL_CLASS = "org.apache.jasper.runtime.JspFactoryImpl"; + public WebappRegistrationCustomizerImpl() { fixupDtdResolution(); - + try { - //sanity check: + // sanity check: Class cl = getClass().getClassLoader().loadClass("org.apache.jasper.servlet.JspServlet"); - //System.err.println("found the jsp servlet: " + cl.getName()); + // System.err.println("found the jsp servlet: " + cl.getName()); } catch (Exception e) { @@ -87,18 +91,18 @@ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCusto } try { - //bug #299733 + // bug #299733 JspFactory fact = JspFactory.getDefaultFactory(); if (fact == null) - { //bug #299733 - //JspFactory does a simple Class.getForName("org.apache.jasper.runtime.JspFactoryImpl") - //however its bundles does not import the jasper package - //so it fails. let's help things out: - fact = (JspFactory)JettyBootstrapActivator.class.getClassLoader() - .loadClass(DEFAULT_JSP_FACTORY_IMPL_CLASS).newInstance(); + { // bug #299733 + // JspFactory does a simple + // Class.getForName("org.apache.jasper.runtime.JspFactoryImpl") + // however its bundles does not import the jasper package + // so it fails. let's help things out: + fact = (JspFactory) JettyBootstrapActivator.class.getClassLoader().loadClass(DEFAULT_JSP_FACTORY_IMPL_CLASS).newInstance(); JspFactory.setDefaultFactory(fact); } - + } catch (Exception e) { @@ -106,85 +110,90 @@ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCusto e.printStackTrace(); } } - + /** - * 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. + * 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. + * 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. + * 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 */ public URL[] getJarsWithTlds(OSGiAppProvider provider, BundleFileLocatorHelper locatorHelper) throws Exception { - - HashSet> classesToAddToTheTldBundles = new HashSet>(); - //Look for the jstl bundle - //We assume the jstl's tlds are defined there. - //We assume that the jstl bundle is imported by this bundle - //So we can look for this class using this bundle's classloader: - Class jstlClass = WebappRegistrationCustomizerImpl.class.getClassLoader().loadClass(DEFAULT_JSTL_BUNDLE_CLASS); - - classesToAddToTheTldBundles.add(jstlClass); - + HashSet> classesToAddToTheTldBundles = new HashSet>(); + + // Look for the jstl bundle + // We assume the jstl's tlds are defined there. + // We assume that the jstl bundle is imported by this bundle + // So we can look for this class using this bundle's classloader: + Class jstlClass = WebappRegistrationCustomizerImpl.class.getClassLoader().loadClass(DEFAULT_JSTL_BUNDLE_CLASS); + + classesToAddToTheTldBundles.add(jstlClass); + ArrayList urls = new ArrayList(); - for (Class cl : classesToAddToTheTldBundles) - { - Bundle tldBundle = FrameworkUtil.getBundle(cl); - File tldBundleLocation = locatorHelper.getBundleInstallLocation(tldBundle); - if (tldBundleLocation != null && tldBundleLocation.isDirectory()) - { - // try to find the jar files inside this folder - for (File f : tldBundleLocation.listFiles()) - { - if (f.getName().endsWith(".jar") && f.isFile()) - { - urls.add(f.toURI().toURL()); - } - else if (f.isDirectory() && f.getName().equals("lib")) - { - for (File f2 : tldBundleLocation.listFiles()) - { - if (f2.getName().endsWith(".jar") && f2.isFile()) - { - urls.add(f2.toURI().toURL()); - } - } - } - } - - } - else if (tldBundleLocation != null) - { - urls.add(tldBundleLocation.toURI().toURL()); - } - } - return urls.toArray(new URL[urls.size()]); + for (Class cl : classesToAddToTheTldBundles) + { + Bundle tldBundle = FrameworkUtil.getBundle(cl); + File tldBundleLocation = locatorHelper.getBundleInstallLocation(tldBundle); + if (tldBundleLocation != null && tldBundleLocation.isDirectory()) + { + // try to find the jar files inside this folder + for (File f : tldBundleLocation.listFiles()) + { + if (f.getName().endsWith(".jar") && f.isFile()) + { + urls.add(f.toURI().toURL()); + } + else if (f.isDirectory() && f.getName().equals("lib")) + { + for (File f2 : tldBundleLocation.listFiles()) + { + if (f2.getName().endsWith(".jar") && f2.isFile()) + { + urls.add(f2.toURI().toURL()); + } + } + } + } + + } + else if (tldBundleLocation != null) + { + urls.add(tldBundleLocation.toURI().toURL()); + } + } + return urls.toArray(new URL[urls.size()]); } - - - + /** - * Jasper resolves the dtd when it parses a taglib descriptor. - * It uses this code to do that: ParserUtils.getClass().getResourceAsStream(resourcePath); where - * resourcePath is for example: /javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd Unfortunately, - * the dtd file is not in the exact same classloader as - * ParserUtils class and the dtds are packaged in 2 separate bundles. - * OSGi does not look in the dependencies' classloader when a resource is searched. + * Jasper resolves the dtd when it parses a taglib descriptor. It uses this + * code to do that: + * ParserUtils.getClass().getResourceAsStream(resourcePath); where + * resourcePath is for example: + * /javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd Unfortunately, the + * dtd file is not in the exact same classloader as ParserUtils class and + * the dtds are packaged in 2 separate bundles. OSGi does not look in the + * dependencies' classloader when a resource is searched. *

    - * The workaround consists of setting the entity resolver. That is a patch - * added to the version of glassfish-jasper-jetty. IT is also present in the latest - * version of glassfish jasper. Could not use introspection to set new value - * on a static friendly field :( + * The workaround consists of setting the entity resolver. That is a patch + * added to the version of glassfish-jasper-jetty. IT is also present in the + * latest version of glassfish jasper. Could not use introspection to set + * new value on a static friendly field :( *

    */ - void fixupDtdResolution() + void fixupDtdResolution() { try { @@ -199,29 +208,23 @@ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCusto } /** - * Instead of using the ParserUtil's classloader, we use a class that is indeed next to the resource for sure. + * Instead of using the ParserUtil's classloader, we use a class that is + * indeed next to the resource for sure. */ static class MyFixedupEntityResolver implements EntityResolver { /** * Same values than in ParserUtils... */ - static final String[] CACHED_DTD_PUBLIC_IDS = - { Constants.TAGLIB_DTD_PUBLIC_ID_11, Constants.TAGLIB_DTD_PUBLIC_ID_12, - Constants.WEBAPP_DTD_PUBLIC_ID_22, Constants.WEBAPP_DTD_PUBLIC_ID_23, }; + static final String[] CACHED_DTD_PUBLIC_IDS = { Constants.TAGLIB_DTD_PUBLIC_ID_11, Constants.TAGLIB_DTD_PUBLIC_ID_12, + Constants.WEBAPP_DTD_PUBLIC_ID_22, Constants.WEBAPP_DTD_PUBLIC_ID_23, }; - static final String[] CACHED_DTD_RESOURCE_PATHS = - { Constants.TAGLIB_DTD_RESOURCE_PATH_11, - Constants.TAGLIB_DTD_RESOURCE_PATH_12, - Constants.WEBAPP_DTD_RESOURCE_PATH_22, - Constants.WEBAPP_DTD_RESOURCE_PATH_23, }; + static final String[] CACHED_DTD_RESOURCE_PATHS = { Constants.TAGLIB_DTD_RESOURCE_PATH_11, Constants.TAGLIB_DTD_RESOURCE_PATH_12, + Constants.WEBAPP_DTD_RESOURCE_PATH_22, Constants.WEBAPP_DTD_RESOURCE_PATH_23, }; + + static final String[] CACHED_SCHEMA_RESOURCE_PATHS = { Constants.TAGLIB_SCHEMA_RESOURCE_PATH_20, Constants.TAGLIB_SCHEMA_RESOURCE_PATH_21, + Constants.WEBAPP_SCHEMA_RESOURCE_PATH_24, Constants.WEBAPP_SCHEMA_RESOURCE_PATH_25, }; - static final String[] CACHED_SCHEMA_RESOURCE_PATHS = { - Constants.TAGLIB_SCHEMA_RESOURCE_PATH_20, - Constants.TAGLIB_SCHEMA_RESOURCE_PATH_21, - Constants.WEBAPP_SCHEMA_RESOURCE_PATH_24, - Constants.WEBAPP_SCHEMA_RESOURCE_PATH_25, - }; public InputSource resolveEntity(String publicId, String systemId) throws SAXException { for (int i = 0; i < CACHED_DTD_PUBLIC_IDS.length; i++) @@ -242,10 +245,7 @@ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCusto input = this.getClass().getResourceAsStream(resourcePath); } } - if (input == null) - { - throw new SAXException(Localizer.getMessage("jsp.error.internal.filenotfound",resourcePath)); - } + if (input == null) { throw new SAXException(Localizer.getMessage("jsp.error.internal.filenotfound", resourcePath)); } InputSource isrc = new InputSource(input); return isrc; } @@ -254,5 +254,5 @@ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCusto return null; } } - + } 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 6e34d4a5902..3f8f2874e65 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,15 +19,14 @@ 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. + * 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. *

    - * It must be placed in the org.eclipse.jetty.osgi.boot.jsp package: - * this is because org.eclipse.jetty.osgi.boot.jsp is the sympbolic-name - * of this fragment. From that name, the PackageadminTracker will call - * this class. IN a different package it won't be called. + * It must be placed in the org.eclipse.jetty.osgi.boot.jsp package: this is + * because org.eclipse.jetty.osgi.boot.jsp is the sympbolic-name of this + * fragment. From that name, the PackageadminTracker will call this class. IN a + * different package it won't be called. *

    */ public class FragmentActivator implements BundleActivator @@ -35,7 +34,8 @@ public class FragmentActivator implements BundleActivator /** * */ - public void start(BundleContext context) throws Exception { + public void start(BundleContext context) throws Exception + { System.setProperty("org.apache.jasper.compiler.disablejsr199", Boolean.TRUE.toString()); WebBundleDeployerHelper.JSP_REGISTRATION_HELPERS.add(new WebappRegistrationCustomizerImpl()); WebBundleDeployerHelper.JSP_REGISTRATION_HELPERS.add(new PluggableWebAppRegistrationCustomizerImpl()); @@ -44,7 +44,8 @@ public class FragmentActivator implements BundleActivator /** * */ - public void stop(BundleContext context) throws Exception { - + public void stop(BundleContext context) throws Exception + { + } } diff --git a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/TagLibOSGiConfiguration.java b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/TagLibOSGiConfiguration.java index 510261db4d0..ad31de22e7f 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/TagLibOSGiConfiguration.java +++ b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/TagLibOSGiConfiguration.java @@ -35,123 +35,120 @@ import org.osgi.util.tracker.ServiceTracker; * Replacement for {@link TagLibConfiguration} for the OSGi integration. *

    *

    - * In the case of a WAB, tlds can be located in OSGi bundles that are dependencies - * of the WAB. - * It is expected that each WAB lists the symbolic-names of the bundles that contain - * tld files. The list is defined as the value of the header 'Require-TldBundle' + * In the case of a WAB, tlds can be located in OSGi bundles that are + * dependencies of the WAB. It is expected that each WAB lists the + * symbolic-names of the bundles that contain tld files. The list is defined as + * the value of the header 'Require-TldBundle' *

    *

    - * Discussions about this are logged in https://bugs.eclipse.org/bugs/show_bug.cgi?id=306971 + * Discussions about this are logged in + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=306971 *

    */ public class TagLibOSGiConfiguration extends TagLibConfiguration { private static final Logger LOG = Log.getLogger(TagLibOSGiConfiguration.class); - private ServiceTracker packageAdminServiceTracker = null; - - /** - * Override the preConfigure; locates the bundles that contain - * tld files according to the value of the manifest header Require-TldBundle. - *

    - * Set or add to the property TldProcessor.TLDResources the list of located jars - * so that the super class will scan those. - *

    - */ + private ServiceTracker packageAdminServiceTracker = null; + + /** + * Override the preConfigure; locates the bundles that contain tld files + * according to the value of the manifest header Require-TldBundle. + *

    + * Set or add to the property TldProcessor.TLDResources the list of located + * jars so that the super class will scan those. + *

    + */ public void preConfigure(WebAppContext context) throws Exception { - String requireTldBundle = (String)context.getAttribute(OSGiWebappConstants.REQUIRE_TLD_BUNDLE); - if (requireTldBundle != null) - { - Collection resources = getRequireTldBundleAsJettyResources(context, requireTldBundle); - if (resources != null && !resources.isEmpty()) - { - Collection previouslySet = (Collection) - context.getAttribute(TagLibConfiguration.TLD_RESOURCES); - if (previouslySet != null) - { - resources.addAll(previouslySet); - } - context.setAttribute(TagLibConfiguration.TLD_RESOURCES, resources); - } - } - super.preConfigure(context); + String requireTldBundle = (String) context.getAttribute(OSGiWebappConstants.REQUIRE_TLD_BUNDLE); + if (requireTldBundle != null) + { + Collection resources = getRequireTldBundleAsJettyResources(context, requireTldBundle); + if (resources != null && !resources.isEmpty()) + { + Collection previouslySet = (Collection) context.getAttribute(TagLibConfiguration.TLD_RESOURCES); + if (previouslySet != null) + { + resources.addAll(previouslySet); + } + context.setAttribute(TagLibConfiguration.TLD_RESOURCES, resources); + } + } + super.preConfigure(context); } /** - * @param requireTldBundle The comma separated list of bundles' symbolic names - * that contain tld for this osgi webapp. + * @param requireTldBundle The comma separated list of bundles' symbolic + * names that contain tld for this osgi webapp. * @return The collection of jars or folders that match those bundles. */ - private Collection getRequireTldBundleAsJettyResources( - WebAppContext context, String requireTldBundle) + private Collection getRequireTldBundleAsJettyResources(WebAppContext context, String requireTldBundle) { - Bundle bundle = (Bundle) - context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE); - PackageAdmin packAdmin = getBundleAdmin(); - String[] symbNames = requireTldBundle.split(", "); - Collection tlds = new LinkedHashSet(); - for (String symbName : symbNames) - { - Bundle[] bs = packAdmin.getBundles(symbName, null); - if (bs == null || bs.length == 0) - { - throw new IllegalArgumentException("Unable to locate the bundle '" - + symbName + "' specified in the " - + OSGiWebappConstants.REQUIRE_TLD_BUNDLE - + " of the manifest of " - + bundle.getSymbolicName()); - } - //take the first one as it is the most recent version? - Enumeration en = bs[0].findEntries("META-INF", "*.tld", false); - boolean atLeastOneTldFound = false; - while (en.hasMoreElements()) - { - atLeastOneTldFound = true; - URL oriUrl = en.nextElement(); - URL url = DefaultFileLocatorHelper.getLocalURL(oriUrl); - Resource tldResource; - try - { - tldResource = Resource.newResource(url); - } - catch (IOException e) - { - throw new IllegalArgumentException("Unable to locate the " - + "tld resource in '" - + url.toString() - + "' in the bundle '" + bs[0].getSymbolicName() - + "' while registering the " - + OSGiWebappConstants.REQUIRE_TLD_BUNDLE - + " of the manifest of " - + bundle.getSymbolicName(), e); - } - tlds.add(tldResource); - } - if (!atLeastOneTldFound) - { - LOG.warn("No '/META-INF/*.tld' resources were found " - + " in the bundle '" + bs[0].getSymbolicName() - + "' while registering the " - + OSGiWebappConstants.REQUIRE_TLD_BUNDLE - + " of the manifest of " - + bundle.getSymbolicName()); - } - } - return tlds; + Bundle bundle = (Bundle) context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE); + PackageAdmin packAdmin = getBundleAdmin(); + String[] symbNames = requireTldBundle.split(", "); + Collection tlds = new LinkedHashSet(); + for (String symbName : symbNames) + { + Bundle[] bs = packAdmin.getBundles(symbName, null); + if (bs == null || bs.length == 0) + { + throw new IllegalArgumentException("Unable to locate the bundle '" + symbName + + "' specified in the " + + OSGiWebappConstants.REQUIRE_TLD_BUNDLE + + " of the manifest of " + + bundle.getSymbolicName()); + } + // take the first one as it is the most recent version? + Enumeration en = bs[0].findEntries("META-INF", "*.tld", false); + boolean atLeastOneTldFound = false; + while (en.hasMoreElements()) + { + atLeastOneTldFound = true; + URL oriUrl = en.nextElement(); + URL url = DefaultFileLocatorHelper.getLocalURL(oriUrl); + Resource tldResource; + try + { + tldResource = Resource.newResource(url); + } + catch (IOException e) + { + throw new IllegalArgumentException("Unable to locate the " + "tld resource in '" + + url.toString() + + "' in the bundle '" + + bs[0].getSymbolicName() + + "' while registering the " + + OSGiWebappConstants.REQUIRE_TLD_BUNDLE + + " of the manifest of " + + bundle.getSymbolicName(), e); + } + tlds.add(tldResource); + } + if (!atLeastOneTldFound) + { + LOG.warn("No '/META-INF/*.tld' resources were found " + " in the bundle '" + + bs[0].getSymbolicName() + + "' while registering the " + + OSGiWebappConstants.REQUIRE_TLD_BUNDLE + + " of the manifest of " + + bundle.getSymbolicName()); + } + } + return tlds; } - - private PackageAdmin getBundleAdmin() - { - if (packageAdminServiceTracker == null) - { - Bundle bootBundle = ((BundleReference)OSGiWebappConstants.class.getClassLoader()).getBundle(); - packageAdminServiceTracker = new ServiceTracker(bootBundle.getBundleContext(), - PackageAdmin.class.getName(), null); - packageAdminServiceTracker.open(); - } - return (PackageAdmin) packageAdminServiceTracker.getService(); - } - + + private PackageAdmin getBundleAdmin() + { + if (packageAdminServiceTracker == null) + { + Bundle bootBundle = ((BundleReference) OSGiWebappConstants.class.getClassLoader()).getBundle(); + packageAdminServiceTracker = new ServiceTracker(bootBundle.getBundleContext(), PackageAdmin.class.getName(), null); + packageAdminServiceTracker.open(); + } + return (PackageAdmin) packageAdminServiceTracker.getService(); + } + } diff --git a/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/WarUrlStreamHandler.java b/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/WarUrlStreamHandler.java index 654fb9b078f..0f861629a81 100644 --- a/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/WarUrlStreamHandler.java +++ b/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/WarUrlStreamHandler.java @@ -24,12 +24,13 @@ import java.util.jar.Manifest; import org.eclipse.jetty.osgi.boot.warurl.internal.WarBundleManifestGenerator; import org.eclipse.jetty.osgi.boot.warurl.internal.WarURLConnection; import org.eclipse.jetty.util.URIUtil; +import org.eclipse.jetty.util.resource.Resource; import org.osgi.service.url.AbstractURLStreamHandlerService; /** - * RFC-66: support for the "war" protocol - * We are reusing the parsing of the query string from jetty. - * If we wanted to not depend on jetty at all we could duplicate that method here + * RFC-66: support for the "war" protocol We are reusing the parsing of the + * query string from jetty. If we wanted to not depend on jetty at all we could + * duplicate that method here */ public class WarUrlStreamHandler extends AbstractURLStreamHandlerService { @@ -40,11 +41,11 @@ public class WarUrlStreamHandler extends AbstractURLStreamHandlerService @Override public URLConnection openConnection(URL url) throws IOException { - //remove the war scheme. + // remove the war scheme. URL actual = new URL(url.toString().substring("war:".length())); - - //let's do some basic tests: see if this is a folder or not. - //if it is a folder. we will try to support it. + + // let's do some basic tests: see if this is a folder or not. + // if it is a folder. we will try to support it. if (actual.getProtocol().equals("file")) { File file = new File(URIUtil.encodePath(actual.getPath())); @@ -52,34 +53,48 @@ public class WarUrlStreamHandler extends AbstractURLStreamHandlerService { if (file.isDirectory()) { - //TODO (not mandatory for rfc66 though) + // TODO (not mandatory for rfc66 though) } } } - - // if (actual.toString().startsWith("file:/") && ! actual.to) + + // if (actual.toString().startsWith("file:/") && ! actual.to) URLConnection ori = (URLConnection) actual.openConnection(); + ori.setDefaultUseCaches(Resource.getDefaultUseCaches()); JarURLConnection jarOri = null; - try { + try + { if (ori instanceof JarURLConnection) { - jarOri = (JarURLConnection)ori; + jarOri = (JarURLConnection) ori; } else { - jarOri = (JarURLConnection) new URL("jar:"+actual.toString() + "!/").openConnection(); + jarOri = (JarURLConnection) new URL("jar:" + actual.toString() + "!/").openConnection(); + jarOri.setDefaultUseCaches(Resource.getDefaultUseCaches()); } - Manifest mf = WarBundleManifestGenerator.createBundleManifest( - jarOri.getManifest(), url, jarOri.getJarFile()); - try { jarOri.getJarFile().close(); jarOri = null; } catch (Throwable t) {} - return new WarURLConnection(actual,mf); + Manifest mf = WarBundleManifestGenerator.createBundleManifest(jarOri.getManifest(), url, jarOri.getJarFile()); + try + { + jarOri.getJarFile().close(); + jarOri = null; + } + catch (Throwable t) + { + } + return new WarURLConnection(actual, mf); } finally { - if (jarOri != null) try { jarOri.getJarFile().close(); } catch (Throwable t) {} + if (jarOri != null) try + { + jarOri.getJarFile().close(); + } + catch (Throwable t) + { + } } - + } - } diff --git a/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/internal/WarURLConnection.java b/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/internal/WarURLConnection.java index 744a43c2ecc..c19a2fa6bfe 100644 --- a/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/internal/WarURLConnection.java +++ b/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/internal/WarURLConnection.java @@ -31,6 +31,7 @@ import java.util.jar.Manifest; import java.util.zip.ZipEntry; import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.resource.Resource; /** * Facade for a URLConnection that will read a jar and substitute its @@ -106,6 +107,7 @@ public class WarURLConnection extends URLConnection { super(url); _conn = url.openConnection(); + _conn.setDefaultUseCaches(Resource.getDefaultUseCaches()); _mf = mf; } @Override 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 e3c0f9040db..78d27131836 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 @@ -66,15 +66,19 @@ public class JettyBootstrapActivator implements BundleActivator } private ServiceRegistration _registeredServer; + private Server _server; + private JettyContextHandlerServiceTracker _jettyContextHandlerTracker; + private PackageAdminServiceTracker _packageAdminServiceTracker; + private BundleTracker _webBundleTracker; + private BundleContext _bundleContext; - -// private ServiceRegistration _jettyServerFactoryService; + + // private ServiceRegistration _jettyServerFactoryService; private JettyServerServiceTracker _jettyServerServiceTracker; - /** * Setup a new jetty Server, registers it as a service. Setup the Service @@ -93,30 +97,31 @@ public class JettyBootstrapActivator implements BundleActivator // should activate. _packageAdminServiceTracker = new PackageAdminServiceTracker(context); - _jettyServerServiceTracker = new JettyServerServiceTracker(); - context.addServiceListener(_jettyServerServiceTracker,"(objectclass=" + Server.class.getName() + ")"); + _jettyServerServiceTracker = new JettyServerServiceTracker(); + context.addServiceListener(_jettyServerServiceTracker, "(objectclass=" + Server.class.getName() + ")"); + + // Register the Jetty Server Factory as a ManagedServiceFactory: + // Properties jettyServerMgdFactoryServiceProps = new Properties(); + // jettyServerMgdFactoryServiceProps.put("pid", + // OSGiWebappConstants.MANAGED_JETTY_SERVER_FACTORY_PID); + // _jettyServerFactoryService = context.registerService( + // ManagedServiceFactory.class.getName(), new + // JettyServersManagedFactory(), + // jettyServerMgdFactoryServiceProps); - //Register the Jetty Server Factory as a ManagedServiceFactory: -// Properties jettyServerMgdFactoryServiceProps = new Properties(); -// jettyServerMgdFactoryServiceProps.put("pid", OSGiWebappConstants.MANAGED_JETTY_SERVER_FACTORY_PID); -// _jettyServerFactoryService = context.registerService( -// ManagedServiceFactory.class.getName(), new JettyServersManagedFactory(), -// jettyServerMgdFactoryServiceProps); - _jettyContextHandlerTracker = new JettyContextHandlerServiceTracker(_jettyServerServiceTracker); // the tracker in charge of the actual deployment // and that will configure and start the jetty server. - context.addServiceListener(_jettyContextHandlerTracker,"(objectclass=" + ContextHandler.class.getName() + ")"); + context.addServiceListener(_jettyContextHandlerTracker, "(objectclass=" + ContextHandler.class.getName() + ")"); - //see if we shoult start a default jetty instance right now. + // see if we shoult start a default jetty instance right now. DefaultJettyAtJettyHomeHelper.startJettyAtJettyHome(context); - - // now ready to support the Extender pattern: - _webBundleTracker = new BundleTracker(context, - Bundle.ACTIVE | Bundle.STOPPING, new WebBundleTrackerCustomizer()); + + // now ready to support the Extender pattern: + _webBundleTracker = new BundleTracker(context, Bundle.ACTIVE | Bundle.STOPPING, new WebBundleTrackerCustomizer()); _webBundleTracker.open(); - + } /* @@ -129,12 +134,12 @@ public class JettyBootstrapActivator implements BundleActivator { try { - - if (_webBundleTracker != null) - { - _webBundleTracker.close(); - _webBundleTracker = null; - } + + if (_webBundleTracker != null) + { + _webBundleTracker.close(); + _webBundleTracker = null; + } if (_jettyContextHandlerTracker != null) { _jettyContextHandlerTracker.stop(); @@ -143,7 +148,7 @@ public class JettyBootstrapActivator implements BundleActivator } if (_jettyServerServiceTracker != null) { - _jettyServerServiceTracker.stop(); + _jettyServerServiceTracker.stop(); context.removeServiceListener(_jettyServerServiceTracker); _jettyServerServiceTracker = null; } @@ -165,31 +170,31 @@ public class JettyBootstrapActivator implements BundleActivator } finally { - _registeredServer = null; + _registeredServer = null; } } -// if (_jettyServerFactoryService != null) -// { -// try -// { -// _jettyServerFactoryService.unregister(); -// } -// catch (IllegalArgumentException ill) -// { -// // already unregistered. -// } -// finally -// { -// _jettyServerFactoryService = null; -// } -// } + // if (_jettyServerFactoryService != null) + // { + // try + // { + // _jettyServerFactoryService.unregister(); + // } + // catch (IllegalArgumentException ill) + // { + // // already unregistered. + // } + // finally + // { + // _jettyServerFactoryService = null; + // } + // } } finally { if (_server != null) { - _server.stop(); + _server.stop(); } INSTANCE = null; } @@ -200,27 +205,25 @@ public class JettyBootstrapActivator implements BundleActivator * 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 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(); + checkBundleActivated(); + WebAppContext contextHandler = new WebAppContext(); Dictionary dic = new Hashtable(); - 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); + 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); + contributor.getBundleContext().registerService(ContextHandler.class.getName(), contextHandler, dic); } /** @@ -228,24 +231,20 @@ public class JettyBootstrapActivator implements BundleActivator * 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 + * @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 dic) throws Exception { - checkBundleActivated(); + 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); + dic.put(OSGiWebappConstants.SERVICE_PROP_WAR, webappFolderPath); + dic.put(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH, contextPath); + contributor.getBundleContext().registerService(ContextHandler.class.getName(), contextHandler, dic); } /** @@ -253,16 +252,14 @@ public class JettyBootstrapActivator implements BundleActivator * 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 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()); + registerContext(contributor, contextFilePath, new Hashtable()); } /** @@ -270,33 +267,30 @@ public class JettyBootstrapActivator implements BundleActivator * 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 + * @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 dic) throws Exception { - checkBundleActivated(); + 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); + 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 fo the static methods to register a webapp is called we should make sure that - * the bundle is started. + * when one fo the static methods to register a webapp is called we should + * make sure that the bundle is started. */ private static void checkBundleActivated() { @@ -313,7 +307,7 @@ public class JettyBootstrapActivator implements BundleActivator } } } - + /** * @return The bundle context for this bundle. */ @@ -322,6 +316,5 @@ public class JettyBootstrapActivator implements BundleActivator checkBundleActivated(); return INSTANCE._bundleContext; } - } 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/JettyContextHandlerServiceTracker.java index 021c292f862..26120c1850f 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/JettyContextHandlerServiceTracker.java @@ -53,14 +53,15 @@ import org.osgi.framework.ServiceReference; public class JettyContextHandlerServiceTracker implements ServiceListener { - /** New style: ability to manage multiple jetty instances */ - private final IManagedJettyServerRegistry _registry; + /** New style: ability to manage multiple jetty instances */ + private final IManagedJettyServerRegistry _registry; /** The context-handler to deactivate indexed by context handler */ private Map _indexByServiceReference = new HashMap(); /** - * The index is the bundle-symbolic-name/path/to/context/file when there is such thing + * The index is the bundle-symbolic-name/path/to/context/file when there is + * such thing */ private Map _indexByContextFile = new HashMap(); @@ -72,7 +73,7 @@ public class JettyContextHandlerServiceTracker implements ServiceListener */ public JettyContextHandlerServiceTracker(IManagedJettyServerRegistry registry) throws Exception { - _registry = registry; + _registry = registry; } public void stop() throws Exception @@ -85,19 +86,16 @@ public class JettyContextHandlerServiceTracker implements ServiceListener // nothing to stop in the WebappRegistrationHelper } - + /** - * @param contextHome Parent folder where the context files can override the context files - * defined in the web bundles: equivalent to the contexts folder in a traditional - * jetty installation. - * when null, just do nothing. + * @param contextHome Parent folder where the context files can override the + * context files defined in the web bundles: equivalent to the + * contexts folder in a traditional jetty installation. when + * null, just do nothing. */ protected void setupContextHomeScanner(File contextHome) throws IOException { - if (contextHome == null) - { - return; - } + if (contextHome == null) { return; } final String osgiContextHomeFolderCanonicalPath = contextHome.getCanonicalPath(); _scanner = new Scanner(); _scanner.setRecursive(true); @@ -132,8 +130,7 @@ public class JettyContextHandlerServiceTracker implements ServiceListener /** * Receives notification that a service has had a lifecycle change. * - * @param ev - * The ServiceEvent object. + * @param ev The ServiceEvent object. */ public void serviceChanged(ServiceEvent ev) { @@ -148,7 +145,7 @@ public class JettyContextHandlerServiceTracker implements ServiceListener { try { - getWebBundleDeployerHelp(sr).unregister(ctxtHandler); + getWebBundleDeployerHelp(sr).unregister(ctxtHandler); } catch (Exception e) { @@ -170,30 +167,32 @@ public class JettyContextHandlerServiceTracker implements ServiceListener { Bundle contributor = sr.getBundle(); BundleContext context = FrameworkUtil.getBundle(JettyBootstrapActivator.class).getBundleContext(); - ContextHandler contextHandler = (ContextHandler)context.getService(sr); + ContextHandler contextHandler = (ContextHandler) context.getService(sr); if (contextHandler.getServer() != null) { // is configured elsewhere. return; } - String contextFilePath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH); + String contextFilePath = (String) sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH); if (contextHandler instanceof WebAppContext && contextFilePath == null) - //it could be a web-application that will in fact be configured via a context file. - //that case is identified by the fact that the contextFilePath is not null - //in that case we must use the register context methods. + // it could be a web-application that will in fact be configured + // via a context file. + // that case is identified by the fact that the contextFilePath + // is not null + // in that case we must use the register context methods. { - WebAppContext webapp = (WebAppContext)contextHandler; - String contextPath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH); + WebAppContext webapp = (WebAppContext) contextHandler; + String contextPath = (String) sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH); if (contextPath == null) { contextPath = webapp.getContextPath(); } - String webXmlPath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_WEB_XML_PATH); + String webXmlPath = (String) sr.getProperty(OSGiWebappConstants.SERVICE_PROP_WEB_XML_PATH); if (webXmlPath == null) { webXmlPath = webapp.getDescriptor(); } - String defaultWebXmlPath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_DEFAULT_WEB_XML_PATH); + String defaultWebXmlPath = (String) sr.getProperty(OSGiWebappConstants.SERVICE_PROP_DEFAULT_WEB_XML_PATH); if (defaultWebXmlPath == null) { String jettyHome = System.getProperty(DefaultJettyAtJettyHomeHelper.SYS_PROP_JETTY_HOME); @@ -202,7 +201,7 @@ public class JettyContextHandlerServiceTracker implements ServiceListener File etc = new File(jettyHome, "etc"); if (etc.exists() && etc.isDirectory()) { - File webDefault = new File (etc, "webdefault.xml"); + File webDefault = new File(etc, "webdefault.xml"); if (webDefault.exists()) defaultWebXmlPath = webDefault.getAbsolutePath(); else @@ -212,27 +211,28 @@ public class JettyContextHandlerServiceTracker implements ServiceListener defaultWebXmlPath = webapp.getDefaultsDescriptor(); } } - String war = (String)sr.getProperty("war"); + String war = (String) sr.getProperty("war"); try { - IWebBundleDeployerHelper deployerHelper = getWebBundleDeployerHelp(sr); - if (deployerHelper == null) - { - - } - else - { - WebAppContext handler = deployerHelper - .registerWebapplication(contributor,war,contextPath, - (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_EXTRA_CLASSPATH), - (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE), - (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_REQUIRE_TLD_BUNDLE), - webXmlPath,defaultWebXmlPath,webapp); + IWebBundleDeployerHelper deployerHelper = getWebBundleDeployerHelp(sr); + if (deployerHelper == null) + { + + } + else + { + WebAppContext handler = deployerHelper.registerWebapplication(contributor, + war, + contextPath, + (String) sr.getProperty(OSGiWebappConstants.SERVICE_PROP_EXTRA_CLASSPATH), + (String) sr.getProperty(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE), + (String) sr.getProperty(OSGiWebappConstants.SERVICE_PROP_REQUIRE_TLD_BUNDLE), + webXmlPath, defaultWebXmlPath, webapp); if (handler != null) { - registerInIndex(handler,sr); + registerInIndex(handler, sr); } - } + } } catch (Throwable e) { @@ -242,34 +242,31 @@ public class JettyContextHandlerServiceTracker implements ServiceListener else { // consider this just an empty skeleton: - if (contextFilePath == null) - { - throw new IllegalArgumentException("the property contextFilePath is required"); - } + if (contextFilePath == null) { throw new IllegalArgumentException("the property contextFilePath is required"); } try { - IWebBundleDeployerHelper deployerHelper = getWebBundleDeployerHelp(sr); - if (deployerHelper == null) - { - //more warnings? - } - else - { - if (Boolean.TRUE.toString().equals(sr.getProperty( - IWebBundleDeployerHelper.INTERNAL_SERVICE_PROP_UNKNOWN_CONTEXT_HANDLER_TYPE))) - { - contextHandler = null; - } - ContextHandler handler = deployerHelper.registerContext(contributor,contextFilePath, - (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_EXTRA_CLASSPATH), - (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE), - (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_REQUIRE_TLD_BUNDLE), - contextHandler); - if (handler != null) - { - registerInIndex(handler,sr); - } - } + IWebBundleDeployerHelper deployerHelper = getWebBundleDeployerHelp(sr); + if (deployerHelper == null) + { + // more warnings? + } + else + { + if (Boolean.TRUE.toString().equals(sr.getProperty(IWebBundleDeployerHelper.INTERNAL_SERVICE_PROP_UNKNOWN_CONTEXT_HANDLER_TYPE))) + { + contextHandler = null; + } + ContextHandler handler = deployerHelper.registerContext(contributor, + contextFilePath, + (String) sr.getProperty(OSGiWebappConstants.SERVICE_PROP_EXTRA_CLASSPATH), + (String) sr.getProperty(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE), + (String) sr.getProperty(OSGiWebappConstants.SERVICE_PROP_REQUIRE_TLD_BUNDLE), + contextHandler); + if (handler != null) + { + registerInIndex(handler, sr); + } + } } catch (Throwable e) { @@ -278,17 +275,17 @@ public class JettyContextHandlerServiceTracker implements ServiceListener } } } - break; + break; } } private void registerInIndex(ContextHandler handler, ServiceReference sr) { - _indexByServiceReference.put(sr,handler); + _indexByServiceReference.put(sr, handler); String key = getSymbolicNameAndContextFileKey(sr); if (key != null) { - _indexByContextFile.put(key,sr); + _indexByContextFile.put(key, sr); } } @@ -320,11 +317,8 @@ public class JettyContextHandlerServiceTracker implements ServiceListener */ private String getSymbolicNameAndContextFileKey(ServiceReference sr) { - String contextFilePath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH); - if (contextFilePath != null) - { - return sr.getBundle().getSymbolicName() + "/" + contextFilePath; - } + String contextFilePath = (String) sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH); + if (contextFilePath != null) { return sr.getBundle().getSymbolicName() + "/" + contextFilePath; } return null; } @@ -336,17 +330,14 @@ public class JettyContextHandlerServiceTracker implements ServiceListener public void reloadJettyContextHandler(String canonicalNameOfFileChanged, String osgiContextHomeFolderCanonicalPath) { String key = getNormalizedRelativePath(canonicalNameOfFileChanged, osgiContextHomeFolderCanonicalPath); - if (key == null) - { - return; - } + if (key == null) { return; } ServiceReference sr = _indexByContextFile.get(key); if (sr == null) { // nothing to do? return; } - serviceChanged(new ServiceEvent(ServiceEvent.MODIFIED,sr)); + serviceChanged(new ServiceEvent(ServiceEvent.MODIFIED, sr)); } /** @@ -362,36 +353,31 @@ public class JettyContextHandlerServiceTracker implements ServiceListener // warning? return null; } - return canFilename.substring(osgiContextHomeFolderCanonicalPath.length()).replace('\\','/'); + return canFilename.substring(osgiContextHomeFolderCanonicalPath.length()).replace('\\', '/'); } - + /** * @return The server on which this webapp is meant to be deployed */ private ServerInstanceWrapper getServerInstanceWrapper(String managedServerName) { - if (_registry == null) - { - return null; - } - if (managedServerName == null) - { - managedServerName = OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME; - } - ServerInstanceWrapper wrapper = _registry.getServerInstanceWrapper(managedServerName); - //System.err.println("Returning " + managedServerName + " = " + wrapper); - return wrapper; + if (_registry == null) { return null; } + if (managedServerName == null) + { + managedServerName = OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME; + } + ServerInstanceWrapper wrapper = _registry.getServerInstanceWrapper(managedServerName); + // System.err.println("Returning " + managedServerName + " = " + + // wrapper); + return wrapper; } - + private IWebBundleDeployerHelper getWebBundleDeployerHelp(ServiceReference sr) { - if (_registry == null) - { - return null; - } - String managedServerName = (String)sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); - ServerInstanceWrapper wrapper = getServerInstanceWrapper(managedServerName); - return wrapper != null ? wrapper.getWebBundleDeployerHelp() : null; + if (_registry == null) { return null; } + String managedServerName = (String) sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); + ServerInstanceWrapper wrapper = getServerInstanceWrapper(managedServerName); + return wrapper != null ? wrapper.getWebBundleDeployerHelp() : null; } - + } 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 4a7dcf96e90..c662d2cae02 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 @@ -247,7 +247,7 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe catch (IOException e) { // nevermind. just trying our best - e.printStackTrace(); + __logger.ignore(e); } return true; } @@ -279,7 +279,7 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe catch (Throwable t) { // humf that will hurt if it does not work. - t.printStackTrace(); + __logger.warn("Unable to set webappcontext", t); } } } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java index b30d9a81d02..97d72cb2c38 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java @@ -78,13 +78,14 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper private static Logger __logger = Log.getLogger(WebBundleDeployerHelper.class.getName()); private static boolean INITIALIZED = false; - + /** * By default set to: {@link DefaultBundleClassLoaderHelper}. It supports * equinox and apache-felix fragment bundles that are specific to an OSGi * implementation should set a different implementation. */ public static BundleClassLoaderHelper BUNDLE_CLASS_LOADER_HELPER = null; + /** * By default set to: {@link DefaultBundleClassLoaderHelper}. It supports * equinox and apache-felix fragment bundles that are specific to an OSGi @@ -97,8 +98,9 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper * equinox and apache-felix fragment bundles that are specific to an OSGi * implementation should set a different implementation. *

    - * Several of those objects can be added here: For example we could have an optional fragment that setups - * a specific implementation of JSF for the whole of jetty-osgi. + * Several of those objects can be added here: For example we could have an + * optional fragment that setups a specific implementation of JSF for the + * whole of jetty-osgi. *

    */ public static Collection JSP_REGISTRATION_HELPERS = new ArrayList(); @@ -127,7 +129,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper // setup the custom BundleClassLoaderHelper try { - BUNDLE_CLASS_LOADER_HELPER = (BundleClassLoaderHelper)Class.forName(BundleClassLoaderHelper.CLASS_NAME).newInstance(); + BUNDLE_CLASS_LOADER_HELPER = (BundleClassLoaderHelper) Class.forName(BundleClassLoaderHelper.CLASS_NAME).newInstance(); } catch (Throwable t) { @@ -137,7 +139,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper // setup the custom FileLocatorHelper try { - BUNDLE_FILE_LOCATOR_HELPER = (BundleFileLocatorHelper)Class.forName(BundleFileLocatorHelper.CLASS_NAME).newInstance(); + BUNDLE_FILE_LOCATOR_HELPER = (BundleFileLocatorHelper) Class.forName(BundleFileLocatorHelper.CLASS_NAME).newInstance(); } catch (Throwable t) { @@ -150,34 +152,28 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper /** * 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 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. + * tld files that are required by this WAB. * @param webXmlPath - * @param defaultWebXmlPath - * TODO: parameter description + * @param defaultWebXmlPath TODO: parameter description * @return The contexthandler created and started * @throws Exception */ - public WebAppContext registerWebapplication(Bundle bundle, - String webappFolderPath, String contextPath, String extraClasspath, - String overrideBundleInstallLocation, - String requireTldBundle, String webXmlPath, - String defaultWebXmlPath, WebAppContext webAppContext) throws Exception + public WebAppContext registerWebapplication(Bundle bundle, String webappFolderPath, String contextPath, String extraClasspath, + String overrideBundleInstallLocation, String requireTldBundle, String webXmlPath, String defaultWebXmlPath, + WebAppContext webAppContext) throws Exception { - File bundleInstall = overrideBundleInstallLocation == null?BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(bundle):new File( - overrideBundleInstallLocation); + File bundleInstall = overrideBundleInstallLocation == null ? BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(bundle) : new File( + overrideBundleInstallLocation); File webapp = null; URL baseWebappInstallURL = null; - + if (webappFolderPath != null && webappFolderPath.length() != 0 && !webappFolderPath.equals(".")) { if (webappFolderPath.startsWith("/") || webappFolderPath.startsWith("file:")) @@ -186,7 +182,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper } else if (bundleInstall != null && bundleInstall.isDirectory()) { - webapp = new File(bundleInstall,webappFolderPath); + webapp = new File(bundleInstall, webappFolderPath); } else if (bundleInstall != null) { @@ -201,37 +197,43 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper { webapp = bundleInstall; } - if (baseWebappInstallURL == null && (webapp == null || !webapp.exists())) - { - throw new IllegalArgumentException("Unable to locate " + webappFolderPath + " inside " - + (bundleInstall != null?bundleInstall.getAbsolutePath():"unlocated bundle '" + bundle.getSymbolicName() + "'")); - } + if (baseWebappInstallURL == null && (webapp == null || !webapp.exists())) { throw new IllegalArgumentException( + "Unable to locate " + webappFolderPath + + " inside " + + (bundleInstall != null ? bundleInstall.getAbsolutePath() : "unlocated bundle '" + bundle.getSymbolicName() + + "'")); } if (baseWebappInstallURL == null && webapp != null) { baseWebappInstallURL = webapp.toURI().toURL(); } - return registerWebapplication(bundle,webappFolderPath,baseWebappInstallURL,contextPath, - extraClasspath,bundleInstall,requireTldBundle,webXmlPath,defaultWebXmlPath,webAppContext); + return registerWebapplication(bundle, webappFolderPath, baseWebappInstallURL, contextPath, extraClasspath, bundleInstall, requireTldBundle, webXmlPath, + defaultWebXmlPath, webAppContext); } - - /* (non-Javadoc) - * @see org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper#registerWebapplication(org.osgi.framework.Bundle, java.lang.String, java.io.File, java.lang.String, java.lang.String, java.io.File, java.lang.String, java.lang.String) + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper# + * registerWebapplication(org.osgi.framework.Bundle, java.lang.String, + * java.io.File, java.lang.String, java.lang.String, java.io.File, + * java.lang.String, java.lang.String) */ - private WebAppContext registerWebapplication(Bundle contributor, String pathInBundleToWebApp, - URL baseWebappInstallURL, String contextPath, String extraClasspath, File bundleInstall, - String requireTldBundle, String webXmlPath, String defaultWebXmlPath, WebAppContext context) - throws Exception + private WebAppContext registerWebapplication(Bundle contributor, String pathInBundleToWebApp, URL baseWebappInstallURL, String contextPath, + String extraClasspath, File bundleInstall, String requireTldBundle, String webXmlPath, + String defaultWebXmlPath, WebAppContext context) throws Exception { ClassLoader contextCl = Thread.currentThread().getContextClassLoader(); String[] oldServerClasses = null; - + try { // make sure we provide access to all the jetty bundles by going // through this bundle. OSGiWebappClassLoader composite = createWebappClassLoader(contributor); - // configure with access to all jetty classes and also all the classes + // configure with access to all jetty classes and also all the + // classes // that the contributor gives access to. Thread.currentThread().setContextClassLoader(composite); @@ -248,7 +250,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper } else { - webXml = new File(bundleInstall,webXmlPath); + webXml = new File(bundleInstall, webXmlPath); } if (webXml.exists()) { @@ -258,7 +260,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper if (defaultWebXmlPath == null || defaultWebXmlPath.length() == 0) { - //use the one defined by the OSGiAppProvider. + // use the one defined by the OSGiAppProvider. defaultWebXmlPath = _wrapper.getOSGiAppProvider().getDefaultsDescriptor(); } if (defaultWebXmlPath != null && defaultWebXmlPath.length() != 0) @@ -270,20 +272,19 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper } else { - defaultWebXml = new File(bundleInstall,defaultWebXmlPath); + defaultWebXml = new File(bundleInstall, defaultWebXmlPath); } if (defaultWebXml.exists()) { context.setDefaultsDescriptor(defaultWebXml.getAbsolutePath()); } } - - //other parameters that might be defines on the OSGiAppProvider: + + // other parameters that might be defines on the OSGiAppProvider: context.setParentLoaderPriority(_wrapper.getOSGiAppProvider().isParentLoaderPriority()); - configureWebappClassLoader(contributor,context,composite, requireTldBundle); - configureWebAppContext(context,contributor,requireTldBundle); - + configureWebappClassLoader(contributor, context, composite, requireTldBundle); + configureWebAppContext(context, contributor, requireTldBundle); // @see // org.eclipse.jetty.webapp.JettyWebXmlConfiguration#configure(WebAppContext) @@ -292,36 +293,36 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper // through the webapp classloader. oldServerClasses = context.getServerClasses(); context.setServerClasses(null); - - _wrapper.getOSGiAppProvider().addContext(contributor,pathInBundleToWebApp,context); - - //support for patch resources. ideally this should be done inside a configurator. - List patchResources = - (List)context.getAttribute(WebInfConfiguration.RESOURCE_URLS+".patch"); + + _wrapper.getOSGiAppProvider().addContext(contributor, pathInBundleToWebApp, context); + + // support for patch resources. ideally this should be done inside a + // configurator. + List patchResources = (List) context.getAttribute(WebInfConfiguration.RESOURCE_URLS + ".patch"); if (patchResources != null) { - LinkedList resourcesPath = new LinkedList(); - //place the patch resources at the beginning of the lookup path. - resourcesPath.addAll(patchResources); - //then place the ones from the host web bundle. - Resource hostResources = context.getBaseResource(); - if (hostResources instanceof ResourceCollection) - { - for (Resource re : ((ResourceCollection)hostResources).getResources()) - { - resourcesPath.add(re); - } - } - else - { - resourcesPath.add(hostResources); - } - - ResourceCollection rc = new ResourceCollection(resourcesPath.toArray( - new Resource[resourcesPath.size()])); - context.setBaseResource(rc); + LinkedList resourcesPath = new LinkedList(); + // place the patch resources at the beginning of the lookup + // path. + resourcesPath.addAll(patchResources); + // then place the ones from the host web bundle. + Resource hostResources = context.getBaseResource(); + if (hostResources instanceof ResourceCollection) + { + for (Resource re : ((ResourceCollection) hostResources).getResources()) + { + resourcesPath.add(re); + } + } + else + { + resourcesPath.add(hostResources); + } + + ResourceCollection rc = new ResourceCollection(resourcesPath.toArray(new Resource[resourcesPath.size()])); + context.setBaseResource(rc); } - + return context; } finally @@ -335,38 +336,41 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper } - /* (non-Javadoc) - * @see org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper#unregister(org.eclipse.jetty.server.handler.ContextHandler) + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper# + * unregister(org.eclipse.jetty.server.handler.ContextHandler) */ public void unregister(ContextHandler contextHandler) throws Exception { _wrapper.getOSGiAppProvider().removeContext(contextHandler); } - /* (non-Javadoc) - * @see org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper#registerContext(org.osgi.framework.Bundle, java.lang.String, java.lang.String, java.lang.String) + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper# + * registerContext(org.osgi.framework.Bundle, java.lang.String, + * java.lang.String, java.lang.String) */ - public ContextHandler registerContext(Bundle contributor, String contextFileRelativePath, String extraClasspath, - String overrideBundleInstallLocation, String requireTldBundle, ContextHandler handler) - throws Exception + public ContextHandler registerContext(Bundle contributor, String contextFileRelativePath, String extraClasspath, String overrideBundleInstallLocation, + String requireTldBundle, ContextHandler handler) throws Exception { File contextsHome = _wrapper.getOSGiAppProvider().getContextXmlDirAsFile(); if (contextsHome != null) { - File prodContextFile = new File(contextsHome,contributor.getSymbolicName() + "/" + contextFileRelativePath); - if (prodContextFile.exists()) - { - return registerContext(contributor,contextFileRelativePath,prodContextFile,extraClasspath, - overrideBundleInstallLocation,requireTldBundle,handler); - } + File prodContextFile = new File(contextsHome, contributor.getSymbolicName() + "/" + contextFileRelativePath); + if (prodContextFile.exists()) { return registerContext(contributor, contextFileRelativePath, prodContextFile, extraClasspath, + overrideBundleInstallLocation, requireTldBundle, handler); } } - File rootFolder = overrideBundleInstallLocation != null - ? Resource.newResource(overrideBundleInstallLocation).getFile() - : BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(contributor); - File contextFile = rootFolder != null?new File(rootFolder,contextFileRelativePath):null; + File rootFolder = overrideBundleInstallLocation != null ? Resource.newResource(overrideBundleInstallLocation).getFile() : BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(contributor); + File contextFile = rootFolder != null ? new File(rootFolder, contextFileRelativePath) : null; if (contextFile != null && contextFile.exists()) { - return registerContext(contributor,contextFileRelativePath,contextFile,extraClasspath,overrideBundleInstallLocation,requireTldBundle,handler); + return registerContext(contributor, contextFileRelativePath, contextFile, extraClasspath, overrideBundleInstallLocation, requireTldBundle, handler); } else { @@ -378,15 +382,19 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper { contextFileRelativePath = "/" + contextFileRelativePath; } - + URL contextURL = contributor.getEntry(contextFileRelativePath); if (contextURL != null) { - Resource r = Resource.newResource(contextURL); - return registerContext(contributor,contextFileRelativePath,r.getInputStream(),extraClasspath,overrideBundleInstallLocation,requireTldBundle,handler); + Resource r = Resource.newResource(contextURL); + return registerContext(contributor, contextFileRelativePath, r.getInputStream(), extraClasspath, overrideBundleInstallLocation, + requireTldBundle, handler); } - throw new IllegalArgumentException("Could not find the context " + "file " + contextFileRelativePath + " for the bundle " - + contributor.getSymbolicName() + (overrideBundleInstallLocation != null?" using the install location " + overrideBundleInstallLocation:"")); + throw new IllegalArgumentException("Could not find the context " + "file " + + contextFileRelativePath + + " for the bundle " + + contributor.getSymbolicName() + + (overrideBundleInstallLocation != null ? " using the install location " + overrideBundleInstallLocation : "")); } } @@ -400,16 +408,14 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper * @param classInBundle * @throws Exception */ - private ContextHandler registerContext(Bundle contributor, String pathInBundle, File contextFile, - String extraClasspath, String overrideBundleInstallLocation, - String requireTldBundle, ContextHandler handler) throws Exception + private ContextHandler registerContext(Bundle contributor, String pathInBundle, File contextFile, String extraClasspath, + String overrideBundleInstallLocation, String requireTldBundle, ContextHandler handler) throws Exception { InputStream contextFileInputStream = null; try { contextFileInputStream = new BufferedInputStream(new FileInputStream(contextFile)); - return registerContext(contributor, pathInBundle, contextFileInputStream, - extraClasspath,overrideBundleInstallLocation,requireTldBundle,handler); + return registerContext(contributor, pathInBundle, contextFileInputStream, extraClasspath, overrideBundleInstallLocation, requireTldBundle, handler); } finally { @@ -424,11 +430,8 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper * happen. * @throws Exception */ - private ContextHandler registerContext(Bundle contributor, - String pathInsideBundle, InputStream contextFileInputStream, - String extraClasspath, String overrideBundleInstallLocation, - String requireTldBundle, ContextHandler handler) - throws Exception + private ContextHandler registerContext(Bundle contributor, String pathInsideBundle, InputStream contextFileInputStream, String extraClasspath, + String overrideBundleInstallLocation, String requireTldBundle, ContextHandler handler) throws Exception { ClassLoader contextCl = Thread.currentThread().getContextClassLoader(); String[] oldServerClasses = null; @@ -442,24 +445,23 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper // classes // that the contributor gives access to. Thread.currentThread().setContextClassLoader(composite); - ContextHandler context = createContextHandler(handler, contributor, - contextFileInputStream,extraClasspath, - overrideBundleInstallLocation,requireTldBundle); - if (context == null) - { + ContextHandler context = createContextHandler(handler, contributor, contextFileInputStream, extraClasspath, overrideBundleInstallLocation, + requireTldBundle); + if (context == null) + { return null;// did not happen } // ok now register this webapp. we checked when we started jetty // that there // was at least one such handler for webapps. - //the actual registration must happen via the new Deployment API. -// _ctxtHandler.addHandler(context); + // the actual registration must happen via the new Deployment API. + // _ctxtHandler.addHandler(context); - configureWebappClassLoader(contributor,context,composite, requireTldBundle); + configureWebappClassLoader(contributor, context, composite, requireTldBundle); if (context instanceof WebAppContext) { - webAppContext = (WebAppContext)context; + webAppContext = (WebAppContext) context; // @see // org.eclipse.jetty.webapp.JettyWebXmlConfiguration#configure(WebAppContext) oldServerClasses = webAppContext.getServerClasses(); @@ -485,53 +487,58 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper * @see {WebAppDeployer#scan} around the comment * // configure it */ - protected void configureWebAppContext(ContextHandler wah, Bundle contributor, - String requireTldBundle) throws IOException + protected void configureWebAppContext(ContextHandler wah, Bundle contributor, String requireTldBundle) throws IOException { // rfc66 - wah.setAttribute(OSGiWebappConstants.RFC66_OSGI_BUNDLE_CONTEXT,contributor.getBundleContext()); + wah.setAttribute(OSGiWebappConstants.RFC66_OSGI_BUNDLE_CONTEXT, contributor.getBundleContext()); - //spring-dm-1.2.1 looks for the BundleContext as a different attribute. - //not a spec... but if we want to support - //org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext - //then we need to do this to: - wah.setAttribute("org.springframework.osgi.web." + BundleContext.class.getName(), - contributor.getBundleContext()); - - //also pass the bundle directly. sometimes a bundle does not have a bundlecontext. - //it is still useful to have access to the Bundle from the servlet context. + // spring-dm-1.2.1 looks for the BundleContext as a different attribute. + // not a spec... but if we want to support + // org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext + // then we need to do this to: + wah.setAttribute("org.springframework.osgi.web." + BundleContext.class.getName(), contributor.getBundleContext()); + + // also pass the bundle directly. sometimes a bundle does not have a + // bundlecontext. + // it is still useful to have access to the Bundle from the servlet + // context. wah.setAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE, contributor); - - //pass the value of the require tld bundle so that the TagLibOSGiConfiguration - //can pick it up. + + // pass the value of the require tld bundle so that the + // TagLibOSGiConfiguration + // can pick it up. wah.setAttribute(OSGiWebappConstants.REQUIRE_TLD_BUNDLE, requireTldBundle); - Bundle[] fragments = PackageAdminServiceTracker.INSTANCE.getFragmentsAndRequiredBundles(contributor); if (fragments != null && fragments.length != 0) { - //sorted extra resource base found in the fragments. - //the resources are either overriding the resourcebase found in the web-bundle - //or appended. - //amongst each resource we sort them according to the alphabetical order - //of the name of the internal folder and the symbolic name of the fragment. - //this is useful to make sure that the lookup path of those - //resource base defined by fragments is always the same. - //This natural order could be abused to define the order in which the base resources are - //looked up. - TreeMap patchResourcesPath = new TreeMap(); - TreeMap appendedResourcesPath = new TreeMap(); - for (Bundle frag : fragments) { - String fragFolder = (String)frag.getHeaders().get(OSGiWebappConstants.JETTY_WAR_FRAGMENT_FOLDER_PATH); - String patchFragFolder = (String)frag.getHeaders().get(OSGiWebappConstants.JETTY_WAR_PATCH_FRAGMENT_FOLDER_PATH); + // sorted extra resource base found in the fragments. + // the resources are either overriding the resourcebase found in the + // web-bundle + // or appended. + // amongst each resource we sort them according to the alphabetical + // order + // of the name of the internal folder and the symbolic name of the + // fragment. + // this is useful to make sure that the lookup path of those + // resource base defined by fragments is always the same. + // This natural order could be abused to define the order in which + // the base resources are + // looked up. + TreeMap patchResourcesPath = new TreeMap(); + TreeMap appendedResourcesPath = new TreeMap(); + for (Bundle frag : fragments) + { + String fragFolder = (String) frag.getHeaders().get(OSGiWebappConstants.JETTY_WAR_FRAGMENT_FOLDER_PATH); + String patchFragFolder = (String) frag.getHeaders().get(OSGiWebappConstants.JETTY_WAR_PATCH_FRAGMENT_FOLDER_PATH); if (fragFolder != null) { URL fragUrl = frag.getEntry(fragFolder); - if (fragUrl == null) - { - throw new IllegalArgumentException("Unable to locate " + fragFolder + " inside " - + " the fragment '" + frag.getSymbolicName() + "'"); - } + if (fragUrl == null) { throw new IllegalArgumentException("Unable to locate " + fragFolder + + " inside " + + " the fragment '" + + frag.getSymbolicName() + + "'"); } fragUrl = DefaultFileLocatorHelper.getLocalURL(fragUrl); String key = fragFolder.startsWith("/") ? fragFolder.substring(1) : fragFolder; appendedResourcesPath.put(key + ";" + frag.getSymbolicName(), Resource.newResource(fragUrl)); @@ -539,11 +546,11 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper if (patchFragFolder != null) { URL patchFragUrl = frag.getEntry(patchFragFolder); - if (patchFragUrl == null) - { - throw new IllegalArgumentException("Unable to locate " + patchFragUrl + " inside " - + " the fragment '" + frag.getSymbolicName() + "'"); - } + if (patchFragUrl == null) { throw new IllegalArgumentException("Unable to locate " + patchFragUrl + + " inside " + + " the fragment '" + + frag.getSymbolicName() + + "'"); } patchFragUrl = DefaultFileLocatorHelper.getLocalURL(patchFragUrl); String key = patchFragFolder.startsWith("/") ? patchFragFolder.substring(1) : patchFragFolder; patchResourcesPath.put(key + ";" + frag.getSymbolicName(), Resource.newResource(patchFragUrl)); @@ -551,92 +558,92 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper } if (!appendedResourcesPath.isEmpty()) { - wah.setAttribute(WebInfConfiguration.RESOURCE_URLS, new ArrayList(appendedResourcesPath.values())); + wah.setAttribute(WebInfConfiguration.RESOURCE_URLS, new ArrayList(appendedResourcesPath.values())); } if (!patchResourcesPath.isEmpty()) { - wah.setAttribute(WebInfConfiguration.RESOURCE_URLS + ".patch", new ArrayList(patchResourcesPath.values())); + wah.setAttribute(WebInfConfiguration.RESOURCE_URLS + ".patch", new ArrayList(patchResourcesPath.values())); } - + if (wah instanceof WebAppContext) { - //This is the equivalent of what MetaInfConfiguration does. For OSGi bundles without the JarScanner - WebAppContext webappCtxt = (WebAppContext)wah; - //take care of the web-fragments, meta-inf resources and tld resources: - //similar to what MetaInfConfiguration does. - List frags = (List)wah.getAttribute(FragmentConfiguration.FRAGMENT_RESOURCES); - List resfrags = (List)wah.getAttribute(WebInfConfiguration.RESOURCE_URLS); - List tldfrags = (List)wah.getAttribute(TagLibConfiguration.TLD_RESOURCES); - for (Bundle frag : fragments) - { - URL webFrag = frag.getEntry("/META-INF/web-fragment.xml"); - Enumeration resEnum = frag.findEntries("/META-INF/resources", "*", true); - Enumeration tldEnum = frag.findEntries("/META-INF", "*.tld", false); - if (webFrag != null || (resEnum != null && resEnum.hasMoreElements()) - || (tldEnum != null && tldEnum.hasMoreElements())) - { - try - { - File fragFile = BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(frag); - //add it to the webinf jars collection: - //no need to check that it was not there yet: it was not there yet for sure. - Resource fragFileAsResource = Resource.newResource(fragFile.toURI()); - webappCtxt.getMetaData().addWebInfJar(fragFileAsResource); - - if (webFrag != null) - { - if (frags == null) - { - frags = new ArrayList(); - wah.setAttribute(FragmentConfiguration.FRAGMENT_RESOURCES, frags); - } - frags.add(fragFileAsResource); - } - if (resEnum != null && resEnum.hasMoreElements()) - { - URL resourcesEntry = frag.getEntry("/META-INF/resources/"); - if (resourcesEntry == null) - { - //probably we found some fragments to a bundle. - //those are already contributed. - //so we skip this. - } - else - { - if (resfrags == null) - { - resfrags = new ArrayList(); - wah.setAttribute(WebInfConfiguration.RESOURCE_URLS, resfrags); - } - resfrags.add(Resource.newResource( - DefaultFileLocatorHelper.getLocalURL(resourcesEntry))); - } - } - if (tldEnum != null && tldEnum.hasMoreElements()) - { - if (tldfrags == null) - { - tldfrags = new ArrayList(); - wah.setAttribute(TagLibConfiguration.TLD_RESOURCES, tldfrags); - } - while (tldEnum.hasMoreElements()) - { - URL tldUrl = tldEnum.nextElement(); - tldfrags.add(Resource.newResource( - DefaultFileLocatorHelper.getLocalURL(tldUrl))); - } - } - } - catch (Exception e) - { - __logger.warn("Unable to locate the bundle " + frag.getBundleId(),e); - } - } - } + // This is the equivalent of what MetaInfConfiguration does. For + // OSGi bundles without the JarScanner + WebAppContext webappCtxt = (WebAppContext) wah; + // take care of the web-fragments, meta-inf resources and tld + // resources: + // similar to what MetaInfConfiguration does. + List frags = (List) wah.getAttribute(FragmentConfiguration.FRAGMENT_RESOURCES); + List resfrags = (List) wah.getAttribute(WebInfConfiguration.RESOURCE_URLS); + List tldfrags = (List) wah.getAttribute(TagLibConfiguration.TLD_RESOURCES); + for (Bundle frag : fragments) + { + URL webFrag = frag.getEntry("/META-INF/web-fragment.xml"); + Enumeration resEnum = frag.findEntries("/META-INF/resources", "*", true); + Enumeration tldEnum = frag.findEntries("/META-INF", "*.tld", false); + if (webFrag != null || (resEnum != null && resEnum.hasMoreElements()) || (tldEnum != null && tldEnum.hasMoreElements())) + { + try + { + File fragFile = BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(frag); + // add it to the webinf jars collection: + // no need to check that it was not there yet: it + // was not there yet for sure. + Resource fragFileAsResource = Resource.newResource(fragFile.toURI()); + webappCtxt.getMetaData().addWebInfJar(fragFileAsResource); + + if (webFrag != null) + { + if (frags == null) + { + frags = new ArrayList(); + wah.setAttribute(FragmentConfiguration.FRAGMENT_RESOURCES, frags); + } + frags.add(fragFileAsResource); + } + if (resEnum != null && resEnum.hasMoreElements()) + { + URL resourcesEntry = frag.getEntry("/META-INF/resources/"); + if (resourcesEntry == null) + { + // probably we found some fragments to a + // bundle. + // those are already contributed. + // so we skip this. + } + else + { + if (resfrags == null) + { + resfrags = new ArrayList(); + wah.setAttribute(WebInfConfiguration.RESOURCE_URLS, resfrags); + } + resfrags.add(Resource.newResource(DefaultFileLocatorHelper.getLocalURL(resourcesEntry))); + } + } + if (tldEnum != null && tldEnum.hasMoreElements()) + { + if (tldfrags == null) + { + tldfrags = new ArrayList(); + wah.setAttribute(TagLibConfiguration.TLD_RESOURCES, tldfrags); + } + while (tldEnum.hasMoreElements()) + { + URL tldUrl = tldEnum.nextElement(); + tldfrags.add(Resource.newResource(DefaultFileLocatorHelper.getLocalURL(tldUrl))); + } + } + } + catch (Exception e) + { + __logger.warn("Unable to locate the bundle " + frag.getBundleId(), e); + } + } + } } } - - + } /** @@ -644,15 +651,13 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper * @param contextFile * @return */ - protected ContextHandler createContextHandler(ContextHandler handlerToConfigure, - Bundle bundle, File contextFile, String extraClasspath, - String overrideBundleInstallLocation, String requireTldBundle) + protected ContextHandler createContextHandler(ContextHandler handlerToConfigure, Bundle bundle, File contextFile, String extraClasspath, + String overrideBundleInstallLocation, String requireTldBundle) { try { - return createContextHandler(handlerToConfigure,bundle, - new BufferedInputStream(new FileInputStream(contextFile)), - extraClasspath,overrideBundleInstallLocation,requireTldBundle); + return createContextHandler(handlerToConfigure, bundle, new BufferedInputStream(new FileInputStream(contextFile)), extraClasspath, + overrideBundleInstallLocation, requireTldBundle); } catch (FileNotFoundException e) { @@ -667,9 +672,8 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper * @return */ @SuppressWarnings("unchecked") - protected ContextHandler createContextHandler(ContextHandler handlerToConfigure, - Bundle bundle, InputStream contextInputStream, String extraClasspath, - String overrideBundleInstallLocation, String requireTldBundle) + protected ContextHandler createContextHandler(ContextHandler handlerToConfigure, Bundle bundle, InputStream contextInputStream, String extraClasspath, + String overrideBundleInstallLocation, String requireTldBundle) { /* * Do something identical to what the ContextProvider would have done: @@ -686,30 +690,30 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper { XmlConfiguration xmlConfiguration = new XmlConfiguration(contextInputStream); HashMap properties = new HashMap(); - properties.put("Server",_wrapper.getServer()); - + properties.put("Server", _wrapper.getServer()); + // insert the bundle's location as a property. - setThisBundleHomeProperty(bundle,properties,overrideBundleInstallLocation); + setThisBundleHomeProperty(bundle, properties, overrideBundleInstallLocation); xmlConfiguration.getProperties().putAll(properties); ContextHandler context = null; if (handlerToConfigure == null) { - context = (ContextHandler)xmlConfiguration.configure(); + context = (ContextHandler) xmlConfiguration.configure(); } else { xmlConfiguration.configure(handlerToConfigure); context = handlerToConfigure; } - + if (context instanceof WebAppContext) { - ((WebAppContext)context).setExtraClasspath(extraClasspath); - ((WebAppContext)context).setParentLoaderPriority(_wrapper.getOSGiAppProvider().isParentLoaderPriority()); + ((WebAppContext) context).setExtraClasspath(extraClasspath); + ((WebAppContext) context).setParentLoaderPriority(_wrapper.getOSGiAppProvider().isParentLoaderPriority()); if (_wrapper.getOSGiAppProvider().getDefaultsDescriptor() != null && _wrapper.getOSGiAppProvider().getDefaultsDescriptor().length() != 0) { - ((WebAppContext)context).setDefaultsDescriptor(_wrapper.getOSGiAppProvider().getDefaultsDescriptor()); + ((WebAppContext) context).setDefaultsDescriptor(_wrapper.getOSGiAppProvider().getDefaultsDescriptor()); } } @@ -775,13 +779,12 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper { if (context instanceof WebAppContext) { - WebAppContext webappCtxt = (WebAppContext)context; + WebAppContext webappCtxt = (WebAppContext) context; context.setClassLoader(webappClassLoader); webappClassLoader.setWebappContext(webappCtxt); String pathsToRequiredBundles = getPathsToRequiredBundles(context, requireTldBundle); - if (pathsToRequiredBundles != null) - webappClassLoader.addClassPath(pathsToRequiredBundles); + if (pathsToRequiredBundles != null) webappClassLoader.addClassPath(pathsToRequiredBundles); } else { @@ -797,20 +800,20 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper // we use a temporary WebAppContext object. // if this is a real webapp we will set it on it a bit later: once we // know. - OSGiWebappClassLoader webappClassLoader = new OSGiWebappClassLoader( - _wrapper.getParentClassLoaderForWebapps(),new WebAppContext(),contributor,BUNDLE_CLASS_LOADER_HELPER); - /* DEBUG - try { - Class c = webappClassLoader.loadClass("org.glassfish.jsp.api.ResourceInjector"); - System.err.println("LOADED org.glassfish.jsp.api.ResourceInjector from "+c.getClassLoader()); - } - catch (Exception e) {e.printStackTrace();} - try { - Class c = webappClassLoader.loadClass("org.apache.jasper.xmlparser.ParserUtils"); - System.err.println("LOADED org.apache.jasper.xmlparser.ParserUtils from "+c.getClassLoader()); - } - catch (Exception e) {e.printStackTrace();} - */ + OSGiWebappClassLoader webappClassLoader = new OSGiWebappClassLoader(_wrapper.getParentClassLoaderForWebapps(), new WebAppContext(), contributor, + BUNDLE_CLASS_LOADER_HELPER); + /* + * DEBUG try { Class c = + * webappClassLoader.loadClass("org.glassfish.jsp.api.ResourceInjector" + * ); + * System.err.println("LOADED org.glassfish.jsp.api.ResourceInjector from " + * +c.getClassLoader()); } catch (Exception e) {e.printStackTrace();} + * try { Class c = + * webappClassLoader.loadClass("org.apache.jasper.xmlparser.ParserUtils" + * ); + * System.err.println("LOADED org.apache.jasper.xmlparser.ParserUtils from " + * +c.getClassLoader()); } catch (Exception e) {e.printStackTrace();} + */ return webappClassLoader; } @@ -823,10 +826,9 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper { try { - File location = overrideBundleInstallLocation != null?new File(overrideBundleInstallLocation):BUNDLE_FILE_LOCATOR_HELPER - .getBundleInstallLocation(bundle); - properties.put("this.bundle.install",location.getCanonicalPath()); - properties.put("this.bundle.install.url",bundle.getEntry("/").toString()); + File location = overrideBundleInstallLocation != null ? new File(overrideBundleInstallLocation) : BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(bundle); + properties.put("this.bundle.install", location.getCanonicalPath()); + properties.put("this.bundle.install.url", bundle.getEntry("/").toString()); } catch (Throwable t) { @@ -834,36 +836,30 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper } } - - private String getPathsToRequiredBundles (ContextHandler context, String requireTldBundle) throws Exception + private String getPathsToRequiredBundles(ContextHandler context, String requireTldBundle) throws Exception { - if (requireTldBundle == null) - return null; + if (requireTldBundle == null) return null; StringBuilder paths = new StringBuilder(); - Bundle bundle = (Bundle)context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE); + Bundle bundle = (Bundle) context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE); PackageAdmin packAdmin = getBundleAdmin(); DefaultFileLocatorHelper fileLocatorHelper = new DefaultFileLocatorHelper(); - + String[] symbNames = requireTldBundle.split(", "); for (String symbName : symbNames) { Bundle[] bs = packAdmin.getBundles(symbName, null); - if (bs == null || bs.length == 0) - { - throw new IllegalArgumentException("Unable to locate the bundle '" - + symbName + "' specified in the " - + OSGiWebappConstants.REQUIRE_TLD_BUNDLE - + " of the manifest of " - + bundle.getSymbolicName()); - } + if (bs == null || bs.length == 0) { throw new IllegalArgumentException("Unable to locate the bundle '" + symbName + + "' specified in the " + + OSGiWebappConstants.REQUIRE_TLD_BUNDLE + + " of the manifest of " + + bundle.getSymbolicName()); } - File f = fileLocatorHelper.getBundleInstallLocation(bs[0]); - if (paths.length() > 0) + if (paths.length() > 0) paths.append(", "); - System.err.println("getPathsToRequiredBundles: bundle path="+bs[0].getLocation()+" uri="+f.toURI()); + __logger.debug("getPathsToRequiredBundles: bundle path=" + bs[0].getLocation() + " uri=" + f.toURI()); paths.append(f.toURI().toURL().toString()); } @@ -872,12 +868,11 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper private PackageAdmin getBundleAdmin() { - Bundle bootBundle = ((BundleReference)OSGiWebappConstants.class.getClassLoader()).getBundle(); + Bundle bootBundle = ((BundleReference) OSGiWebappConstants.class.getClassLoader()).getBundle(); ServiceTracker serviceTracker = new ServiceTracker(bootBundle.getBundleContext(), PackageAdmin.class.getName(), null); serviceTracker.open(); return (PackageAdmin) serviceTracker.getService(); } - } 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/WebBundleTrackerCustomizer.java index 3cfea34c932..79938415305 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/WebBundleTrackerCustomizer.java @@ -24,7 +24,6 @@ import org.osgi.framework.BundleEvent; import org.osgi.util.tracker.BundleTracker; import org.osgi.util.tracker.BundleTrackerCustomizer; - /** * Support bundles that declare the webapp directly through headers in their * manifest. @@ -49,133 +48,132 @@ import org.osgi.util.tracker.BundleTrackerCustomizer; * * @author hmalphettes */ -public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer { +public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer +{ private static final Logger LOG = Log.getLogger(WebBundleTrackerCustomizer.class); - + /** + * A bundle is being added to the BundleTracker. + * + *

    + * This method is called before a bundle which matched the search parameters + * of the BundleTracker is added to the + * BundleTracker. This method should return the object to be + * tracked for the specified Bundle. The returned object is + * stored in the BundleTracker and is available from the + * {@link BundleTracker#getObject(Bundle) getObject} method. + * + * @param bundle The Bundle being added to the + * BundleTracker. + * @param event The bundle event which caused this customizer method to be + * called or null if there is no bundle event + * associated with the call to this method. + * @return The object to be tracked for the specified Bundle + * object or null if the specified Bundle + * object should not be tracked. + */ + public Object addingBundle(Bundle bundle, BundleEvent event) + { + if (bundle.getState() == Bundle.ACTIVE) + { + boolean isWebBundle = register(bundle); + return isWebBundle ? bundle : null; + } + else if (bundle.getState() == Bundle.STOPPING) + { + unregister(bundle); + } + else + { + // we should not be called in that state as + // we are registered only for ACTIVE and STOPPING + } + return null; + } - /** - * A bundle is being added to the BundleTracker. - * - *

    - * This method is called before a bundle which matched the search parameters - * of the BundleTracker is added to the - * BundleTracker. This method should return the object to be - * tracked for the specified Bundle. The returned object is - * stored in the BundleTracker and is available from the - * {@link BundleTracker#getObject(Bundle) getObject} method. - * - * @param bundle The Bundle being added to the - * BundleTracker. - * @param event The bundle event which caused this customizer method to be - * called or null if there is no bundle event associated - * with the call to this method. - * @return The object to be tracked for the specified Bundle - * object or null if the specified Bundle - * object should not be tracked. - */ - public Object addingBundle(Bundle bundle, BundleEvent event) - { - if (bundle.getState() == Bundle.ACTIVE) - { - boolean isWebBundle = register(bundle); - return isWebBundle ? bundle : null; - } - else if (bundle.getState() == Bundle.STOPPING) - { - unregister(bundle); - } - else - { - //we should not be called in that state as - //we are registered only for ACTIVE and STOPPING - } - return null; - } + /** + * A bundle tracked by the BundleTracker has been modified. + * + *

    + * This method is called when a bundle being tracked by the + * BundleTracker has had its state modified. + * + * @param bundle The Bundle whose state has been modified. + * @param event The bundle event which caused this customizer method to be + * called or null if there is no bundle event + * associated with the call to this method. + * @param object The tracked object for the specified bundle. + */ + 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); + } + if (bundle.getState() == Bundle.ACTIVE) + { + register(bundle); + } + } - /** - * A bundle tracked by the BundleTracker has been modified. - * - *

    - * This method is called when a bundle being tracked by the - * BundleTracker has had its state modified. - * - * @param bundle The Bundle whose state has been modified. - * @param event The bundle event which caused this customizer method to be - * called or null if there is no bundle event associated - * with the call to this method. - * @param object The tracked object for the specified bundle. - */ - 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. -// System.err.println(bundle.getSymbolicName()); - if (bundle.getState() == Bundle.STOPPING || bundle.getState() == Bundle.ACTIVE) - { - unregister(bundle); - } - if (bundle.getState() == Bundle.ACTIVE) - { - register(bundle); - } - } + /** + * A bundle tracked by the BundleTracker has been removed. + * + *

    + * This method is called after a bundle is no longer being tracked by the + * BundleTracker. + * + * @param bundle The Bundle that has been removed. + * @param event The bundle event which caused this customizer method to be + * called or null if there is no bundle event + * associated with the call to this method. + * @param object The tracked object for the specified bundle. + */ + public void removedBundle(Bundle bundle, BundleEvent event, Object object) + { + unregister(bundle); + } - /** - * A bundle tracked by the BundleTracker has been removed. - * - *

    - * This method is called after a bundle is no longer being tracked by the - * BundleTracker. - * - * @param bundle The Bundle that has been removed. - * @param event The bundle event which caused this customizer method to be - * called or null if there is no bundle event associated - * with the call to this method. - * @param object The tracked object for the specified bundle. - */ - public void removedBundle(Bundle bundle, BundleEvent event, - Object object) - { - unregister(bundle); - } - - - /** - * @param bundle - * @return true if this bundle in indeed a web-bundle. - */ + /** + * @param bundle + * @return true if this bundle in indeed a web-bundle. + */ private boolean register(Bundle bundle) { Dictionary dic = bundle.getHeaders(); - String warFolderRelativePath = (String)dic.get(OSGiWebappConstants.JETTY_WAR_FOLDER_PATH); + String warFolderRelativePath = (String) dic.get(OSGiWebappConstants.JETTY_WAR_FOLDER_PATH); if (warFolderRelativePath != null) { - String contextPath = getWebContextPath(bundle, dic, false);//(String)dic.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH); + String contextPath = getWebContextPath(bundle, dic, false);// (String)dic.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH); if (contextPath == null || !contextPath.startsWith("/")) { - LOG.warn("The manifest header '" + OSGiWebappConstants.JETTY_WAR_FOLDER_PATH + - ": " + warFolderRelativePath + "' in the bundle " + bundle.getSymbolicName() + - " is not valid: there is no Web-ContextPath defined in the manifest."); - return false; + LOG.warn("The manifest header '" + OSGiWebappConstants.JETTY_WAR_FOLDER_PATH + + ": " + + warFolderRelativePath + + "' in the bundle " + + bundle.getSymbolicName() + + " is not valid: there is no Web-ContextPath defined in the manifest."); + return false; } // create the corresponding service and publish it in the context of // the contributor bundle. try { - JettyBootstrapActivator.registerWebapplication(bundle,warFolderRelativePath,contextPath); + JettyBootstrapActivator.registerWebapplication(bundle, warFolderRelativePath, contextPath); return true; } catch (Throwable e) { - LOG.warn("Starting the web-bundle " + bundle.getSymbolicName() + " threw an exception.", e); - return true;//maybe it did not work maybe it did. safer to track this bundle. + LOG.warn("Starting the web-bundle " + bundle.getSymbolicName() + " threw an exception.", e); + return true;// maybe it did not work maybe it did. safer to + // track this bundle. } } else if (dic.get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH) != null) { - String contextFileRelativePath = (String)dic.get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH); + String contextFileRelativePath = (String) dic.get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH); if (contextFileRelativePath == null) { // nothing to register here. @@ -187,7 +185,7 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer { { try { - JettyBootstrapActivator.registerContext(bundle,path.trim()); + JettyBootstrapActivator.registerContext(bundle, path.trim()); } catch (Throwable e) { @@ -203,8 +201,8 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer { // (draft) of the spec: just a couple of posts on the // world-wide-web. URL rfc66Webxml = bundle.getEntry("/WEB-INF/web.xml"); - if (rfc66Webxml == null && dic.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH) == null) - { + if (rfc66Webxml == null && dic.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH) == null) + { return false;// no webapp in here } // this is risky: should we make sure that there is no classes and @@ -215,42 +213,41 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer { // pointing to files and folders inside WEB-INF. We should // filter-out // META-INF too - String rfc66ContextPath = getWebContextPath(bundle,dic,rfc66Webxml==null); + String rfc66ContextPath = getWebContextPath(bundle, dic, rfc66Webxml == null); try { - JettyBootstrapActivator.registerWebapplication(bundle,".",rfc66ContextPath); + JettyBootstrapActivator.registerWebapplication(bundle, ".", rfc66ContextPath); return true; } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); - return true;//maybe it did not work maybe it did. safer to track this bundle. + return true;// maybe it did not work maybe it did. safer to + // track this bundle. } } } private String getWebContextPath(Bundle bundle, Dictionary dic, boolean webinfWebxmlExists) { - String rfc66ContextPath = (String)dic.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH); + String rfc66ContextPath = (String) dic.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH); if (rfc66ContextPath == null) { - if (!webinfWebxmlExists) { - return null; - } + if (!webinfWebxmlExists) { return null; } // extract from the last token of the bundle's location: // (really ? // could consider processing the symbolic name as an alternative // the location will often reflect the version. // maybe this is relevant when the file is a war) String location = bundle.getLocation(); - String toks[] = location.replace('\\','/').split("/"); + String toks[] = location.replace('\\', '/').split("/"); rfc66ContextPath = toks[toks.length - 1]; // remove .jar, .war etc: int lastDot = rfc66ContextPath.lastIndexOf('.'); if (lastDot != -1) { - rfc66ContextPath = rfc66ContextPath.substring(0,lastDot); + rfc66ContextPath = rfc66ContextPath.substring(0, lastDot); } } if (!rfc66ContextPath.startsWith("/")) @@ -259,7 +256,7 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer { } return rfc66ContextPath; } - + private void unregister(Bundle bundle) { // nothing to do: when the bundle is stopped, each one of its service @@ -268,7 +265,4 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer { // webapps registered in that bundle. } - - - } 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 73b127cd637..7858e574243 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 @@ -25,6 +25,7 @@ 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.osgi.framework.Bundle; @@ -43,11 +44,13 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper // The url nuxeo and felix return is created directly from the File so it // should work. private static Field BUNDLE_ENTRY_FIELD = null; + private static Field FILE_FIELD = null; private static Field BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY = null;// ZipBundleFile - // inside - // DirZipBundleEntry + + // inside + // DirZipBundleEntry private static Field ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE = null;// ZipFile @@ -56,8 +59,7 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper * spirit of OSGi but quite necessary to support self-contained webapps and * other situations. * - * @param bundle - * The bundle + * @param bundle The bundle * @return Its installation location as a file. * @throws Exception */ @@ -67,19 +69,23 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper // grab the MANIFEST.MF's url // and then do what it takes. URL url = bundle.getEntry("/META-INF/MANIFEST.MF"); -// System.err.println(url.toString() + " " + url.toURI() + " " + url.getProtocol()); + //System.err.println(url.toString() + " " + url.toURI() + " " + url.getProtocol()); if (url.getProtocol().equals("file")) { // some osgi frameworks do use the file protocole directly in some - // situations. Do use the FileResource to transform the URL into a File: URL#toURI is broken - return new FileResource(url).getFile().getParentFile().getParentFile(); + // situations. Do use the FileResource to transform the URL into a + // File: URL#toURI is broken + return new FileResource(url).getFile().getParentFile().getParentFile(); } else if (url.getProtocol().equals("bundleentry")) { // say hello to equinox who has its own protocol. // we use introspection like there is no tomorrow to get access to // the File + URLConnection con = url.openConnection(); + con.setUseCaches(Resource.getDefaultUseCaches()); //work around problems where url connections cache references to jars + if (BUNDLE_ENTRY_FIELD == null) { BUNDLE_ENTRY_FIELD = con.getClass().getDeclaredField("bundleEntry"); @@ -93,13 +99,16 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper FILE_FIELD = bundleEntry.getClass().getDeclaredField("file"); FILE_FIELD.setAccessible(true); } - File f = (File)FILE_FIELD.get(bundleEntry); + File f = (File) FILE_FIELD.get(bundleEntry); return f.getParentFile().getParentFile(); } else if (bundleEntry.getClass().getName().equals("org.eclipse.osgi.baseadaptor.bundlefile.ZipBundleEntry")) { url = bundle.getEntry("/"); + con = url.openConnection(); + con.setDefaultUseCaches(Resource.getDefaultUseCaches()); + if (BUNDLE_ENTRY_FIELD == null) {// this one will be a DirZipBundleEntry BUNDLE_ENTRY_FIELD = con.getClass().getDeclaredField("bundleEntry"); @@ -117,7 +126,7 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE = zipBundleFile.getClass().getDeclaredField("zipFile"); ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE.setAccessible(true); } - ZipFile zipFile = (ZipFile)ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE.get(zipBundleFile); + ZipFile zipFile = (ZipFile) ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE.get(zipBundleFile); return new File(zipFile.getName()); } else if (bundleEntry.getClass().getName().equals("org.eclipse.osgi.baseadaptor.bundlefile.DirZipBundleEntry")) @@ -130,7 +139,7 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper { // observed this on felix-2.0.0 String location = bundle.getLocation(); -// System.err.println("location " + location); + // System.err.println("location " + location); if (location.startsWith("file:/")) { URI uri = new URI(URIUtil.encodePath(location)); @@ -138,27 +147,32 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper } else if (location.startsWith("file:")) { - //location defined in the BundleArchive m_bundleArchive - //it is relative to relative to the BundleArchive's m_archiveRootDir - File res = new File(location.substring("file:".length())); - if (!res.exists()) - { - return null; -// Object bundleArchive = getFelixBundleArchive(bundle); -// File archiveRoot = getFelixBundleArchiveRootDir(bundleArchive); -// String currentLocation = getFelixBundleArchiveCurrentLocation(bundleArchive); -// System.err.println("Got the archive root " + archiveRoot.getAbsolutePath() -// + " current location " + currentLocation + " is directory ?"); -// res = new File(archiveRoot, currentLocation != null -// ? currentLocation : location.substring("file:".length())); - } - return res; + // location defined in the BundleArchive m_bundleArchive + // it is relative to relative to the BundleArchive's + // m_archiveRootDir + File res = new File(location.substring("file:".length())); + if (!res.exists()) + { + return null; + // Object bundleArchive = getFelixBundleArchive(bundle); + // File archiveRoot = + // getFelixBundleArchiveRootDir(bundleArchive); + // String currentLocation = + // getFelixBundleArchiveCurrentLocation(bundleArchive); + // System.err.println("Got the archive root " + + // archiveRoot.getAbsolutePath() + // + " current location " + currentLocation + + // " is directory ?"); + // res = new File(archiveRoot, currentLocation != null + // ? currentLocation : location.substring("file:".length())); + } + return res; } else if (location.startsWith("reference:file:")) { - location = URLDecoder.decode(location.substring("reference:".length()), "UTF-8"); - File file = new File(location.substring("file:".length())); - return file; + location = URLDecoder.decode(location.substring("reference:".length()), "UTF-8"); + File file = new File(location.substring("file:".length())); + return file; } } return null; @@ -179,37 +193,40 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper path = path.substring(1); } File bundleInstall = getBundleInstallLocation(bundle); - File webapp = path != null && path.length() != 0?new File(bundleInstall,path):bundleInstall; - if (!webapp.exists()) - { - throw new IllegalArgumentException("Unable to locate " + path + " inside " + bundle.getSymbolicName() + " (" - + (bundleInstall != null?bundleInstall.getAbsolutePath():" no_bundle_location ") + ")"); + File webapp = path != null && path.length() != 0 ? new File(bundleInstall, path) : bundleInstall; + if (!webapp.exists()) + { + throw new IllegalArgumentException("Unable to locate " + path + + " inside " + + bundle.getSymbolicName() + + " (" + + (bundleInstall != null ? bundleInstall.getAbsolutePath() : " no_bundle_location ") + + ")"); } return webapp; } - + /** - * Helper method equivalent to Bundle#getEntry(String entryPath) except that - * it searches for entries in the fragments by using the Bundle#findEntries method. - * - * @param bundle - * @param entryPath - * @return null or all the entries found for that path. - */ - public Enumeration findEntries(Bundle bundle, String entryPath) - { - int last = entryPath.lastIndexOf('/'); - String path = last != -1 && last < entryPath.length() -2 - ? entryPath.substring(0, last) : "/"; - if (!path.startsWith("/")) - { - path = "/" + path; - } - String pattern = last != -1 && last < entryPath.length() -2 - ? entryPath.substring(last+1) : entryPath; - Enumeration enUrls = bundle.findEntries(path, pattern, false); - return enUrls; - } + * Helper method equivalent to Bundle#getEntry(String entryPath) except that + * it searches for entries in the fragments by using the Bundle#findEntries + * method. + * + * @param bundle + * @param entryPath + * @return null or all the entries found for that path. + */ + public Enumeration findEntries(Bundle bundle, String entryPath) + { + int last = entryPath.lastIndexOf('/'); + String path = last != -1 && last < entryPath.length() - 2 ? entryPath.substring(0, last) : "/"; + if (!path.startsWith("/")) + { + path = "/" + path; + } + String pattern = last != -1 && last < entryPath.length() - 2 ? entryPath.substring(last + 1) : entryPath; + Enumeration enUrls = bundle.findEntries(path, pattern, false); + return enUrls; + } /** * If the bundle is a jar, returns the jar. If the bundle is a folder, look @@ -256,76 +273,84 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper return new File[] { jasperLocation }; } } - - //introspection on equinox to invoke the getLocalURL method on BundleURLConnection - //equivalent to using the FileLocator without depending on an equinox class. - private static Method BUNDLE_URL_CONNECTION_getLocalURL = null; - private static Method BUNDLE_URL_CONNECTION_getFileURL = null; - /** - * Only useful for equinox: on felix we get the file:// or jar:// url already. - * Other OSGi implementations have not been tested - *

    - * Get a URL to the bundle entry that uses a common protocol (i.e. file: - * jar: or http: etc.). - *

    - * @return a URL to the bundle entry that uses a common protocol - */ - public static URL getLocalURL(URL url) { - if ("bundleresource".equals(url.getProtocol()) || "bundleentry".equals(url.getProtocol())) { - try { - URLConnection conn = url.openConnection(); - if (BUNDLE_URL_CONNECTION_getLocalURL == null && - conn.getClass().getName().equals( - "org.eclipse.osgi.framework.internal.core.BundleURLConnection")) { - BUNDLE_URL_CONNECTION_getLocalURL = conn.getClass().getMethod("getLocalURL", null); - BUNDLE_URL_CONNECTION_getLocalURL.setAccessible(true); - } - if (BUNDLE_URL_CONNECTION_getLocalURL != null) { - return (URL)BUNDLE_URL_CONNECTION_getLocalURL.invoke(conn, null); - } - } catch (Throwable t) { - System.err.println("Unable to locate the OSGi url: '" + url + "'."); - t.printStackTrace(); - } - } - return url; - } - /** - * Only useful for equinox: on felix we get the file:// url already. - * Other OSGi implementations have not been tested - *

    - * Get a URL to the content of the bundle entry that uses the file: protocol. - * The content of the bundle entry may be downloaded or extracted to the local - * file system in order to create a file: URL. - * @return a URL to the content of the bundle entry that uses the file: protocol - *

    - */ - public static URL getFileURL(URL url) - { - if ("bundleresource".equals(url.getProtocol()) || "bundleentry".equals(url.getProtocol())) - { - try - { - URLConnection conn = url.openConnection(); - if (BUNDLE_URL_CONNECTION_getFileURL == null && - conn.getClass().getName().equals( - "org.eclipse.osgi.framework.internal.core.BundleURLConnection")) - { - BUNDLE_URL_CONNECTION_getFileURL = conn.getClass().getMethod("getFileURL", null); - BUNDLE_URL_CONNECTION_getFileURL.setAccessible(true); - } - if (BUNDLE_URL_CONNECTION_getFileURL != null) - { - return (URL)BUNDLE_URL_CONNECTION_getFileURL.invoke(conn, null); - } - } - catch (Throwable t) - { - t.printStackTrace(); - } - } - return url; - } + // introspection on equinox to invoke the getLocalURL method on + // BundleURLConnection + // equivalent to using the FileLocator without depending on an equinox + // class. + private static Method BUNDLE_URL_CONNECTION_getLocalURL = null; + + private static Method BUNDLE_URL_CONNECTION_getFileURL = null; + + /** + * Only useful for equinox: on felix we get the file:// or jar:// url + * already. Other OSGi implementations have not been tested + *

    + * Get a URL to the bundle entry that uses a common protocol (i.e. file: + * jar: or http: etc.). + *

    + * + * @return a URL to the bundle entry that uses a common protocol + */ + public static URL getLocalURL(URL url) + { + if ("bundleresource".equals(url.getProtocol()) || "bundleentry".equals(url.getProtocol())) + { + try + { + URLConnection conn = url.openConnection(); + conn.setDefaultUseCaches(Resource.getDefaultUseCaches()); + if (BUNDLE_URL_CONNECTION_getLocalURL == null && conn.getClass().getName() + .equals("org.eclipse.osgi.framework.internal.core.BundleURLConnection")) + { + BUNDLE_URL_CONNECTION_getLocalURL = conn.getClass().getMethod("getLocalURL", null); + BUNDLE_URL_CONNECTION_getLocalURL.setAccessible(true); + } + if (BUNDLE_URL_CONNECTION_getLocalURL != null) { return (URL) BUNDLE_URL_CONNECTION_getLocalURL.invoke(conn, null); } + } + catch (Throwable t) + { + System.err.println("Unable to locate the OSGi url: '" + url + "'."); + t.printStackTrace(); + } + } + return url; + } + + /** + * Only useful for equinox: on felix we get the file:// url already. Other + * OSGi implementations have not been tested + *

    + * Get a URL to the content of the bundle entry that uses the file: + * protocol. The content of the bundle entry may be downloaded or extracted + * to the local file system in order to create a file: URL. + * + * @return a URL to the content of the bundle entry that uses the file: + * protocol + *

    + */ + public static URL getFileURL(URL url) + { + if ("bundleresource".equals(url.getProtocol()) || "bundleentry".equals(url.getProtocol())) + { + try + { + URLConnection conn = url.openConnection(); + conn.setDefaultUseCaches(Resource.getDefaultUseCaches()); + if (BUNDLE_URL_CONNECTION_getFileURL == null && conn.getClass().getName() + .equals("org.eclipse.osgi.framework.internal.core.BundleURLConnection")) + { + BUNDLE_URL_CONNECTION_getFileURL = conn.getClass().getMethod("getFileURL", null); + BUNDLE_URL_CONNECTION_getFileURL.setAccessible(true); + } + if (BUNDLE_URL_CONNECTION_getFileURL != null) { return (URL) BUNDLE_URL_CONNECTION_getFileURL.invoke(conn, null); } + } + catch (Throwable t) + { + t.printStackTrace(); + } + } + return url; + } } From 50f545b29a0227cbd78e05d9b8b10ca2c4e985b4 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 4 Apr 2012 19:21:16 +0200 Subject: [PATCH 076/100] Vastly improved queueing of FrameBytes, by appending at the end of the queue (instead of iterating over the queue). Also, implemented a better fix for the missing flush() in case of missing handlers: now instead of flushing in the write completion handler (which could lead to stack overflows), we use the same mechanism employed for FrameBytes, where we avoid stack overflows by dispatching to a new thread after few recursive invocations. --- .../eclipse/jetty/spdy/StandardSession.java | 74 ++++++++++--------- 1 file changed, 39 insertions(+), 35 deletions(-) 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 ecf5deb1fed..dae08a4c4cd 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 @@ -820,15 +820,21 @@ public class StandardSession implements ISession, Parser.Listener, Handler 0) + { + FrameBytes element = queue.get(index - 1); + if (element.compareTo(frameBytes) >= 0) + break; + --index; + } + queue.add(index, frameBytes); + } } private void prepend(FrameBytes frameBytes) - { - enqueue(frameBytes, true); - } - - private void enqueue(FrameBytes frameBytes, boolean prepend) { synchronized (queue) { @@ -836,8 +842,7 @@ public class StandardSession implements ISession, Parser.Listener, Handler 0 || prepend && comparison == 0) + if (element.compareTo(frameBytes) <= 0) break; ++index; } @@ -854,7 +859,6 @@ public class StandardSession implements ISession, Parser.Listener, Handler void complete(final Handler handler, final C context) { - if (handler != null) + // Applications may send and queue up a lot of frames and + // if we call Handler.completed() only synchronously we risk + // starvation (for the last frames sent) and stack overflow. + // Therefore every some invocation, we dispatch to a new thread + Integer invocations = handlerInvocations.get(); + if (invocations >= 4) { - // Applications may send and queue up a lot of frames and - // if we call Handler.completed() only synchronously we risk - // starvation (for the last frames sent) and stack overflow. - // Therefore every some invocation, we dispatch to a new thread - Integer invocations = handlerInvocations.get(); - if (invocations >= 4) + execute(new Runnable() { - execute(new Runnable() + @Override + public void run() { - @Override - public void run() - { + if (handler != null) notifyHandlerCompleted(handler, context); - flush(); - } - }); - } - else - { - handlerInvocations.set(invocations + 1); - try - { - notifyHandlerCompleted(handler, context); flush(); } - finally - { - handlerInvocations.set(invocations); - } + }); + } + else + { + handlerInvocations.set(invocations + 1); + try + { + if (handler != null) + notifyHandlerCompleted(handler, context); + flush(); + } + finally + { + handlerInvocations.set(invocations); } } } @@ -967,7 +970,8 @@ public class StandardSession implements ISession, Parser.Listener, Handler that.stream.priority => -1 (this.stream has less priority than that.stream) + return that.getStream().getPriority() - getStream().getPriority(); } @Override From d47d4b15ea09f7a0b33ea9121198717bc00cc512 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Thu, 5 Apr 2012 17:34:00 +1000 Subject: [PATCH 077/100] Added ability to use a META-INF/jetty-webapp-context.xml file to apply a context configuration file to a webapp. Replaced more printStackTrace with log calls; more formatting. --- .../jetty/osgi/boot/OSGiAppProvider.java | 6 +- .../DefaultJettyAtJettyHomeHelper.java | 15 +++-- .../JettyContextHandlerServiceTracker.java | 13 ++-- .../webapp/WebBundleDeployerHelper.java | 65 +++++++++++++------ .../webapp/WebBundleTrackerCustomizer.java | 12 ++-- .../internal/DefaultFileLocatorHelper.java | 2 +- 6 files changed, 70 insertions(+), 43 deletions(-) diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiAppProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiAppProvider.java index 34fd8c74db4..510c09e8b67 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiAppProvider.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiAppProvider.java @@ -349,7 +349,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider } catch (IOException e) { - e.printStackTrace(); + LOG.warn(e); return null; } } @@ -370,11 +370,11 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider } catch (IOException e) { - e.printStackTrace(); + LOG.warn(e); return null; } } - + public boolean isExtract() { return _extractWars; 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 d8491eeacbe..17ea8d22cc7 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 @@ -167,18 +167,21 @@ public class DefaultJettyAtJettyHomeHelper { */ private static String getJettyConfigurationURLs(File jettyhome) { - String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml"); - StringTokenizer tokenizer = new StringTokenizer(jettyetc,";,", false); + String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES, "etc/jetty.xml"); + StringTokenizer tokenizer = new StringTokenizer(jettyetc, ";,", false); StringBuilder res = new StringBuilder(); while (tokenizer.hasMoreTokens()) { String next = tokenizer.nextToken().trim(); if (!next.startsWith("/") && next.indexOf(':') == -1) { - try { + try + { next = new File(jettyhome, next).toURI().toURL().toString(); - } catch (MalformedURLException e) { - e.printStackTrace(); + } + catch (MalformedURLException e) + { + LOG.warn(e); continue; } } @@ -225,7 +228,7 @@ public class DefaultJettyAtJettyHomeHelper { } if (enUrls == null || !enUrls.hasMoreElements()) { - System.err.println("Unable to locate a jetty configuration file for " + etcFile); + LOG.warn("Unable to locate a jetty configuration file for " + etcFile); } if (enUrls != null) { 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/JettyContextHandlerServiceTracker.java index 26120c1850f..0838a4850ab 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/JettyContextHandlerServiceTracker.java @@ -24,6 +24,8 @@ import org.eclipse.jetty.osgi.boot.internal.serverfactory.DefaultJettyAtJettyHom 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; @@ -52,7 +54,8 @@ import org.osgi.framework.ServiceReference; */ public class JettyContextHandlerServiceTracker implements ServiceListener { - + private static Logger __logger = Log.getLogger(WebBundleDeployerHelper.class.getName()); + /** New style: ability to manage multiple jetty instances */ private final IManagedJettyServerRegistry _registry; @@ -149,8 +152,7 @@ public class JettyContextHandlerServiceTracker implements ServiceListener } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + __logger.warn(e); } } } @@ -236,7 +238,7 @@ public class JettyContextHandlerServiceTracker implements ServiceListener } catch (Throwable e) { - e.printStackTrace(); + __logger.warn(e); } } else @@ -270,8 +272,7 @@ public class JettyContextHandlerServiceTracker implements ServiceListener } catch (Throwable e) { - // TODO Auto-generated catch block - e.printStackTrace(); + __logger.warn(e); } } } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java index 97d72cb2c38..a681396910e 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java @@ -229,6 +229,11 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper try { + + + //apply any META-INF/context.xml file that is found to configure the webapp first + applyMetaInfContextXml (contributor, context); + // make sure we provide access to all the jetty bundles by going // through this bundle. OSGiWebappClassLoader composite = createWebappClassLoader(contributor); @@ -661,7 +666,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper } catch (FileNotFoundException e) { - e.printStackTrace(); + __logger.warn(e); } return null; } @@ -726,18 +731,15 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper } catch (SAXException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + __logger.warn(e); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + __logger.warn(e); } catch (Throwable e) { - // TODO Auto-generated catch block - e.printStackTrace(); + __logger.warn(e); } finally { @@ -802,21 +804,46 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper // know. OSGiWebappClassLoader webappClassLoader = new OSGiWebappClassLoader(_wrapper.getParentClassLoaderForWebapps(), new WebAppContext(), contributor, BUNDLE_CLASS_LOADER_HELPER); - /* - * DEBUG try { Class c = - * webappClassLoader.loadClass("org.glassfish.jsp.api.ResourceInjector" - * ); - * System.err.println("LOADED org.glassfish.jsp.api.ResourceInjector from " - * +c.getClassLoader()); } catch (Exception e) {e.printStackTrace();} - * try { Class c = - * webappClassLoader.loadClass("org.apache.jasper.xmlparser.ParserUtils" - * ); - * System.err.println("LOADED org.apache.jasper.xmlparser.ParserUtils from " - * +c.getClassLoader()); } catch (Exception e) {e.printStackTrace();} - */ return webappClassLoader; } + + protected void applyMetaInfContextXml (Bundle bundle, ContextHandler contextHandler) + throws Exception + { + if (bundle == null) + return; + if (contextHandler == null) + return; + + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + __logger.info("Context classloader = "+cl); + try + { + Thread.currentThread().setContextClassLoader(_wrapper.getParentClassLoaderForWebapps()); + + //find if there is a META-INF/context.xml file + URL contextXmlUrl = bundle.getEntry("/META-INF/jetty-webapp-context.xml"); + if (contextXmlUrl == null) + return; + + //Apply it just as the standard jetty ContextProvider would do + __logger.info("Applying "+contextXmlUrl+" to "+contextHandler); + + XmlConfiguration xmlConfiguration = new XmlConfiguration(contextXmlUrl); + HashMap properties = new HashMap(); + properties.put("Server", _wrapper.getServer()); + xmlConfiguration.getProperties().putAll(properties); + xmlConfiguration.configure(contextHandler); + } + finally + { + Thread.currentThread().setContextClassLoader(cl); + } + } + + + /** * Set the property "this.bundle.install" to point to the location * of the bundle. Useful when is 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/WebBundleTrackerCustomizer.java index 79938415305..137c49bb271 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/WebBundleTrackerCustomizer.java @@ -167,8 +167,7 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer catch (Throwable e) { LOG.warn("Starting the web-bundle " + bundle.getSymbolicName() + " threw an exception.", e); - return true;// maybe it did not work maybe it did. safer to - // track this bundle. + return true;// maybe it did not work maybe it did. safer to track this bundle. } } else if (dic.get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH) != null) @@ -189,8 +188,7 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer } catch (Throwable e) { - // TODO Auto-generated catch block - e.printStackTrace(); + LOG.warn(e); } } return true; @@ -221,10 +219,8 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer } catch (Throwable e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return true;// maybe it did not work maybe it did. safer to - // track this bundle. + LOG.warn(e); + return true;// maybe it did not work maybe it did. safer to track this bundle. } } } 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 7858e574243..0e0ff3fbdae 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 @@ -69,7 +69,7 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper // grab the MANIFEST.MF's url // and then do what it takes. URL url = bundle.getEntry("/META-INF/MANIFEST.MF"); - //System.err.println(url.toString() + " " + url.toURI() + " " + url.getProtocol()); + if (url.getProtocol().equals("file")) { // some osgi frameworks do use the file protocole directly in some From eaacd69ede679f836873a44a367b20516f449191 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Thu, 5 Apr 2012 17:30:05 +0200 Subject: [PATCH 078/100] Moved from SLF4J to Jetty logging. --- jetty-spdy/spdy-core/pom.xml | 5 +++-- .../main/java/org/eclipse/jetty/spdy/StandardSession.java | 6 +++--- .../main/java/org/eclipse/jetty/spdy/StandardStream.java | 6 +++--- .../org/eclipse/jetty/spdy/api/SessionFrameListener.java | 6 +++--- .../main/java/org/eclipse/jetty/spdy/parser/Parser.java | 6 +++--- .../jetty/spdy/http/ServerHTTPSPDYAsyncConnection.java | 6 +++--- .../spdy/http/ServerHTTPSPDYAsyncConnectionFactory.java | 6 +++--- .../java/org/eclipse/jetty/spdy/SPDYAsyncConnection.java | 8 ++++---- .../java/org/eclipse/jetty/spdy/SPDYServerConnector.java | 6 +++--- 9 files changed, 28 insertions(+), 27 deletions(-) diff --git a/jetty-spdy/spdy-core/pom.xml b/jetty-spdy/spdy-core/pom.xml index 058434a1491..cfd2edf9293 100644 --- a/jetty-spdy/spdy-core/pom.xml +++ b/jetty-spdy/spdy-core/pom.xml @@ -12,8 +12,9 @@ - org.slf4j - slf4j-api + org.eclipse.jetty + jetty-util + ${project.version} junit 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 dae08a4c4cd..4caa3df86c4 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 @@ -61,12 +61,12 @@ import org.eclipse.jetty.spdy.frames.SynStreamFrame; import org.eclipse.jetty.spdy.frames.WindowUpdateFrame; import org.eclipse.jetty.spdy.generator.Generator; import org.eclipse.jetty.spdy.parser.Parser; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; public class StandardSession implements ISession, Parser.Listener, Handler { - private static final Logger logger = LoggerFactory.getLogger(Session.class); + private static final Logger logger = Log.getLogger(Session.class); private static final ThreadLocal handlerInvocations = new ThreadLocal() { @Override diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java index 758858d5690..d1fccff757c 100644 --- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java +++ b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java @@ -39,12 +39,12 @@ import org.eclipse.jetty.spdy.frames.HeadersFrame; import org.eclipse.jetty.spdy.frames.SynReplyFrame; import org.eclipse.jetty.spdy.frames.SynStreamFrame; import org.eclipse.jetty.spdy.frames.WindowUpdateFrame; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; public class StandardStream implements IStream { - private static final Logger logger = LoggerFactory.getLogger(Stream.class); + private static final Logger logger = Log.getLogger(Stream.class); private final Map attributes = new ConcurrentHashMap<>(); private final SynStreamFrame frame; private final ISession session; diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SessionFrameListener.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SessionFrameListener.java index f1d9d2c66a6..467919c29cf 100644 --- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SessionFrameListener.java +++ b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SessionFrameListener.java @@ -18,8 +18,8 @@ package org.eclipse.jetty.spdy.api; import java.util.EventListener; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; /** *

    A {@link SessionFrameListener} is the passive counterpart of a {@link Session} and receives events happening @@ -122,7 +122,7 @@ public interface SessionFrameListener extends EventListener */ public static class Adapter implements SessionFrameListener { - private static final Logger logger = LoggerFactory.getLogger(Adapter.class); + private static final Logger logger = Log.getLogger(Adapter.class); @Override public StreamFrameListener onSyn(Stream stream, SynInfo synInfo) diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/Parser.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/Parser.java index 58cb61d1c34..8cc42e18144 100644 --- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/Parser.java +++ b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/Parser.java @@ -27,12 +27,12 @@ import org.eclipse.jetty.spdy.StreamException; import org.eclipse.jetty.spdy.api.SessionStatus; import org.eclipse.jetty.spdy.frames.ControlFrame; import org.eclipse.jetty.spdy.frames.DataFrame; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; public class Parser { - private static final Logger logger = LoggerFactory.getLogger(Parser.class); + private static final Logger logger = Log.getLogger(Parser.class); private final List listeners = new CopyOnWriteArrayList<>(); private final ControlFrameParser controlFrameParser; private final DataFrameParser dataFrameParser; diff --git a/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYAsyncConnection.java b/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYAsyncConnection.java index f782d656467..2882bc43461 100644 --- a/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYAsyncConnection.java +++ b/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYAsyncConnection.java @@ -50,12 +50,12 @@ import org.eclipse.jetty.spdy.api.DataInfo; import org.eclipse.jetty.spdy.api.Headers; import org.eclipse.jetty.spdy.api.ReplyInfo; import org.eclipse.jetty.spdy.api.Stream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implements AsyncConnection { - private static final Logger logger = LoggerFactory.getLogger(ServerHTTPSPDYAsyncConnection.class); + private static final Logger logger = Log.getLogger(ServerHTTPSPDYAsyncConnection.class); private static final ByteBuffer ZERO_BYTES = ByteBuffer.allocate(0); private static final DataInfo END_OF_CONTENT = new ByteBufferDataInfo(ZERO_BYTES, true); diff --git a/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYAsyncConnectionFactory.java b/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYAsyncConnectionFactory.java index 30a10a61c79..93fff9c8467 100644 --- a/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYAsyncConnectionFactory.java +++ b/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYAsyncConnectionFactory.java @@ -33,13 +33,13 @@ 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.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; public class ServerHTTPSPDYAsyncConnectionFactory extends ServerSPDYAsyncConnectionFactory { private static final String CONNECTION_ATTRIBUTE = "org.eclipse.jetty.spdy.http.connection"; - private static final Logger logger = LoggerFactory.getLogger(ServerHTTPSPDYAsyncConnectionFactory.class); + private static final Logger logger = Log.getLogger(ServerHTTPSPDYAsyncConnectionFactory.class); private final Connector connector; diff --git a/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYAsyncConnection.java b/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYAsyncConnection.java index 3ae8ccaef46..40dfecde36b 100644 --- a/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYAsyncConnection.java +++ b/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYAsyncConnection.java @@ -30,12 +30,12 @@ import org.eclipse.jetty.io.nio.NIOBuffer; import org.eclipse.jetty.spdy.api.Handler; import org.eclipse.jetty.spdy.api.Session; import org.eclipse.jetty.spdy.parser.Parser; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; public class SPDYAsyncConnection extends AbstractConnection implements AsyncConnection, Controller, IdleListener { - private static final Logger logger = LoggerFactory.getLogger(SPDYAsyncConnection.class); + private static final Logger logger = Log.getLogger(SPDYAsyncConnection.class); private final ByteBufferPool bufferPool; private final Parser parser; private volatile Session session; @@ -181,7 +181,7 @@ public class SPDYAsyncConnection extends AbstractConnection implements AsyncConn } catch (IOException x) { - logger.trace("", x); + logger.ignore(x); } } diff --git a/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYServerConnector.java b/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYServerConnector.java index 2a496070f96..41412b3f0c5 100644 --- a/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYServerConnector.java +++ b/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYServerConnector.java @@ -41,14 +41,14 @@ import org.eclipse.jetty.server.nio.SelectChannelConnector; import org.eclipse.jetty.spdy.api.SPDY; import org.eclipse.jetty.spdy.api.Session; import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.ThreadPool; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class SPDYServerConnector extends SelectChannelConnector { - private static final Logger logger = LoggerFactory.getLogger(SPDYServerConnector.class); + private static final Logger logger = Log.getLogger(SPDYServerConnector.class); // Order is important on server side, so we use a LinkedHashMap private final Map factories = new LinkedHashMap<>(); From 6ec159401010469008ca58ba5b04d2ed3ad55213 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Thu, 5 Apr 2012 17:33:48 +0200 Subject: [PATCH 079/100] Updated path location of the jetty config file for SPDY. --- jetty-spdy/spdy-jetty-http-webapp/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-spdy/spdy-jetty-http-webapp/pom.xml b/jetty-spdy/spdy-jetty-http-webapp/pom.xml index 68b571f5925..3c2c370cb9c 100644 --- a/jetty-spdy/spdy-jetty-http-webapp/pom.xml +++ b/jetty-spdy/spdy-jetty-http-webapp/pom.xml @@ -42,7 +42,7 @@ -Dlog4j.configuration=file://${basedir}/src/main/resources/log4j.properties -Xbootclasspath/p:${settings.localRepository}/org/mortbay/jetty/npn/npn-boot/${project.version}/npn-boot-${project.version}.jar - ${basedir}/src/main/config/jetty-spdy.xml + ${basedir}/src/main/config/etc/jetty-spdy.xml / From 9dfa9f9937baa85c26f475b60b554f1ba6398679 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Tue, 10 Apr 2012 14:21:07 +1000 Subject: [PATCH 080/100] 370081: correctly set URI for query strings --- .../rewrite/handler/RegexTargetHandler.java | 149 ------------ .../rewrite/handler/RewriteRegexRule.java | 19 +- .../handler/RegexTargetHandlerTest.java | 214 ------------------ .../rewrite/handler/RewriteRegexRuleTest.java | 29 ++- .../java/org/eclipse/jetty/util/MultiMap.java | 20 +- 5 files changed, 56 insertions(+), 375 deletions(-) delete mode 100644 jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RegexTargetHandler.java delete mode 100644 jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RegexTargetHandlerTest.java diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RegexTargetHandler.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RegexTargetHandler.java deleted file mode 100644 index 736f8245f9f..00000000000 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RegexTargetHandler.java +++ /dev/null @@ -1,149 +0,0 @@ -package org.eclipse.jetty.rewrite.handler; - -import java.io.IOException; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.server.handler.ContextHandler.Context; -import org.eclipse.jetty.server.handler.ScopedHandler; -import org.eclipse.jetty.util.component.AggregateLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - - -/* ------------------------------------------------------------ */ -/** A handle that uses regular expressions to select the target. - *

    - * This handler applies a list of regex to target name mappings to the URIs of requests. - * If the regex matches the URI, then the mapped target name is used in the nested - * call to {@link #doScope(String, Request, HttpServletRequest, HttpServletResponse)}. - *

    - * This handler should be installed as the first handler in a Context. It can be configured - * either with direct calls to {@link #addPatternTarget(String, String)} or by setting - * the context init parameters "org.eclipse.jetty.rewrite.handler.REGEX_MAPPINGS" to a comma - * separated list of strings in the format regex==target. - */ -public class RegexTargetHandler extends ScopedHandler -{ - private final static Logger LOG = Log.getLogger(RegexTargetHandler.class); - public final static String REGEX_MAPPINGS="org.eclipse.jetty.rewrite.handler.REGEX_MAPPINGS"; - static class RegexMapping - { - RegexMapping(String regex,String target) - { - _pattern=Pattern.compile(regex); - _target=target; - } - final Pattern _pattern; - final String _target; - - public String toString() - { - return _pattern+"=="+_target; - } - } - - final private List _patterns = new CopyOnWriteArrayList(); - - /* ------------------------------------------------------------ */ - /** Add a pattern to target mapping. - * @param pattern The regular expression pattern to match. - * @param target The target (normally servlet name) to handle the request - */ - public void addPatternTarget(String pattern,String target) - { - _patterns.add(new RegexMapping(pattern,target)); - } - - /* ------------------------------------------------------------ */ - @Override - protected void doStart() throws Exception - { - super.doStart(); - - Context context = ContextHandler.getCurrentContext(); - if (context!=null) - { - String config=context.getInitParameter(REGEX_MAPPINGS); - LOG.debug("{}={}",REGEX_MAPPINGS,config); - String[] mappings=config.split("\\s*,\\s*"); - for (String mapping : mappings) - { - mapping=mapping.trim(); - String[] parts=mapping.split("\\s*==\\s*"); - if (parts.length==2) - { - String pattern=parts[0]; - String target=parts[1]; - addPatternTarget(pattern,target); - } - else - LOG.warn("Bad regex mapping: "+mapping); - } - } - } - - /* ------------------------------------------------------------ */ - @Override - public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException - { - for (RegexTargetHandler.RegexMapping rm : _patterns) - { - Matcher m=rm._pattern.matcher(target); - if (m.matches()) - { - String new_target = rm._target; - final String sp; - final String pi; - - if (m.groupCount()==1&&target.endsWith(m.group(1))) - { - pi=m.group(1); - sp=target.substring(0,target.length()-pi.length()); - } - else - { - sp=target; - pi=null; - } - baseRequest.setServletPath(sp); - baseRequest.setPathInfo(pi); - baseRequest.setAttribute("org.eclipse.jetty.servlet.REGEX_PATH",target); - super.nextScope(new_target,baseRequest,request,response); - return; - } - } - super.nextScope(target,baseRequest,request,response); - } - - /* ------------------------------------------------------------ */ - @Override - public void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException - { - String path=(String)baseRequest.getAttribute("org.eclipse.jetty.servlet.REGEX_PATH"); - if (path==null) - path=target; - else - baseRequest.setAttribute("org.eclipse.jetty.servlet.REGEX_PATH",null); - - super.nextHandle(path,baseRequest,request,response); - } - - /* ------------------------------------------------------------ */ - public void dump(Appendable out, String indent) throws IOException - { - AggregateLifeCycle.dumpObject(out,this); - AggregateLifeCycle.dump(out,indent,_patterns,Collections.singletonList(getHandler())); - } - - -} \ No newline at end of file diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java index 49a27dcee30..6fa22b52238 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java @@ -18,6 +18,7 @@ import java.util.regex.Matcher; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.server.Request; /** @@ -89,14 +90,20 @@ public class RewriteRegexRule extends RegexRule implements Rule.ApplyURI /* ------------------------------------------------------------ */ public void applyURI(Request request, String oldTarget, String newTarget) throws IOException { - request.setRequestURI(newTarget); - if (_query!=null) + if (_query==null) + { + request.setRequestURI(newTarget); + } + else { String query=(String)request.getAttribute("org.eclipse.jetty.rewrite.handler.RewriteRegexRule.Q"); - if (_queryGroup||request.getQueryString()==null) - request.setQueryString(query); - else - request.setQueryString(request.getQueryString()+"&"+query); + + if (!_queryGroup && request.getQueryString()!=null) + query=request.getQueryString()+"&"+query; + HttpURI uri=new HttpURI(newTarget+"?"+query); + request.setUri(uri); + request.setRequestURI(newTarget); + request.setQueryString(query); } } diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RegexTargetHandlerTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RegexTargetHandlerTest.java deleted file mode 100644 index c47937621df..00000000000 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RegexTargetHandlerTest.java +++ /dev/null @@ -1,214 +0,0 @@ -// ======================================================================== -// Copyright (c) 2006-2009 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.rewrite.handler; - -import static junit.framework.Assert.assertEquals; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.net.Socket; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import javax.servlet.RequestDispatcher; -import javax.servlet.Servlet; -import javax.servlet.ServletException; -import javax.servlet.ServletRequestWrapper; -import javax.servlet.ServletResponseWrapper; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; - -import junit.framework.Assert; - -import org.eclipse.jetty.rewrite.handler.RegexTargetHandler; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.servlet.ServletHolder; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -public class RegexTargetHandlerTest -{ - private static Server __server = new Server(0); - private static int __port; - - @BeforeClass - public static void setup() throws Exception - { - - ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); - context.setContextPath("/"); - __server.setHandler(context); - - // Serve some hello world servlets - context.addServlet(DispatchServletServlet.class,"/dispatch/*"); - context.addServlet(new ServletHolder("HelloAll",new HelloServlet("Hello World")),"/*"); - context.addServlet(new ServletHolder("Italian",new HelloServlet("Buongiorno Mondo")),"/it/*"); - context.addServlet(new ServletHolder("French", new HelloServlet("Bonjour le Monde")),"/fr/*"); - - RegexTargetHandler regexHandler=new RegexTargetHandler(); - regexHandler.setHandler(context.getHandler()); - context.setHandler(regexHandler); - - context.getInitParams().put(RegexTargetHandler.REGEX_MAPPINGS, - " .*\\.fr==French, \n"+ - "/ciao(/.*)$==Italian"); - - __server.start(); - - __port=__server.getConnectors()[0].getLocalPort(); - } - - @AfterClass - public static void shutdown() throws Exception - { - __server.stop(); - } - - - @Test - public void testNormal() throws Exception - { - String[] response=getResponse("/normal"); - assertEquals("HTTP/1.1 200 OK",response[0]); - assertEquals("Hello World",response[1]); - assertEquals("",response[2]); - assertEquals("/normal",response[3]); - - response=getResponse("/it/info"); - assertEquals("HTTP/1.1 200 OK",response[0]); - assertEquals("Buongiorno Mondo",response[1]); - assertEquals("/it",response[2]); - assertEquals("/info",response[3]); - } - - @Test - public void testFullMatch() throws Exception - { - String[] response=getResponse("/some/thing.fr"); - assertEquals("HTTP/1.1 200 OK",response[0]); - assertEquals("Bonjour le Monde",response[1]); - assertEquals("/some/thing.fr",response[2]); - assertEquals("null",response[3]); - } - - @Test - public void testCaptureMatch() throws Exception - { - String[] response=getResponse("/ciao/info"); - assertEquals("HTTP/1.1 200 OK",response[0]); - assertEquals("Buongiorno Mondo",response[1]); - assertEquals("/ciao",response[2]); - assertEquals("/info",response[3]); - } - - @Test - public void testDispatchFullMatch() throws Exception - { - String[] response=getResponse("/dispatch/xxx?forward=/some/thing.fr"); - assertEquals("HTTP/1.1 200 OK",response[0]); - assertEquals("Bonjour le Monde",response[1]); - assertEquals("/some/thing.fr",response[2]); - assertEquals("null",response[3]); - } - - @Test - public void testDispatchCaptureMatch() throws Exception - { - String[] response=getResponse("/dispatch/xxx?forward=/ciao/info"); - assertEquals("HTTP/1.1 200 OK",response[0]); - assertEquals("Buongiorno Mondo",response[1]); - assertEquals("/ciao",response[2]); - assertEquals("/info",response[3]); - } - - - private String[] getResponse(String uri) throws Exception - { - Socket socket = new Socket("127.0.0.1",__port); - - PrintWriter out = new PrintWriter(socket.getOutputStream()); - out.print("GET "+uri+" HTTP/1.0\r\n\r\n"); - out.flush(); - - BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); - - String[] response=new String[4]; - response[0]=in.readLine(); - //System.err.println(response[0]); - - String line=in.readLine(); - while(line.length()>0) - line=in.readLine(); - - response[1]=in.readLine(); - //System.err.println(response[1]); - response[2]=in.readLine(); - //System.err.println(response[2]); - response[3]=in.readLine(); - //System.err.println(response[3]); - - socket.close(); - return response; - } - - - public static class HelloServlet extends HttpServlet implements Servlet - { - final String _hello; - - public HelloServlet(String hello) - { - _hello=hello; - } - - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException - { - response.setStatus(200); - response.getWriter().println(_hello); - response.getWriter().println(request.getServletPath()); - response.getWriter().println(request.getPathInfo()); - } - } - - - public static class DispatchServletServlet extends HttpServlet implements Servlet - { - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException - { - RequestDispatcher dispatcher = null; - - if(request.getParameter("include")!=null) - { - dispatcher = getServletContext().getRequestDispatcher(request.getParameter("include")); - dispatcher.include(new HttpServletRequestWrapper(request), new HttpServletResponseWrapper(response)); - } - else if(request.getParameter("forward")!=null) - { - dispatcher = getServletContext().getRequestDispatcher(request.getParameter("forward")); - dispatcher.forward(new HttpServletRequestWrapper(request), new HttpServletResponseWrapper(response)); - } - - } - } -} diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java index 872bb6e5b85..a804db70c31 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java @@ -14,6 +14,10 @@ package org.eclipse.jetty.rewrite.handler; import java.io.IOException; +import org.eclipse.jetty.http.HttpURI; +import org.eclipse.jetty.util.MultiMap; +import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.UrlEncoded; import org.junit.Before; import org.junit.Test; @@ -53,20 +57,35 @@ public class RewriteRegexRuleTest extends AbstractRuleTestCase { for (String[] test : _tests) { + reset(); + _request.setRequestURI(null); + String t=test[0]+"?"+test[1]+">"+test[2]+"|"+test[3]; _rule.setRegex(test[2]); _rule.setReplacement(test[3]); - _request.setRequestURI(test[0]); - _request.setQueryString(test[1]); - _request.getAttributes().clearAttributes(); + _request.setUri(new HttpURI(test[0]+(test[1]==null?"":("?"+test[1])))); + _request.getRequestURI(); + String result = _rule.matchAndApply(test[0], _request, _response); assertEquals(t, test[4], result); _rule.applyURI(_request,test[0],result); - assertEquals(t,test[4], _request.getRequestURI()); - assertEquals(t,test[5], _request.getQueryString()); + if (result!=null) + { + assertEquals(t,test[4], _request.getRequestURI()); + assertEquals(t,test[5], _request.getQueryString()); + } + + if (test[5]!=null) + { + MultiMap params=new MultiMap(); + UrlEncoded.decodeTo(test[5],params,StringUtil.__UTF8); + + for (String n:params.keySet()) + assertEquals(params.getString(n),_request.getParameter(n)); + } } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiMap.java b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiMap.java index 61f9eeaec91..2d0840da004 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiMap.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiMap.java @@ -287,7 +287,25 @@ public class MultiMap implements ConcurrentMap, Serializable */ public Map toStringArrayMap() { - HashMap map = new HashMap(_map.size()*3/2); + HashMap map = new HashMap(_map.size()*3/2) + { + public String toString() + { + StringBuilder b=new StringBuilder(); + b.append('{'); + for (K k:keySet()) + { + if(b.length()>1) + b.append(','); + b.append(k); + b.append('='); + b.append(Arrays.asList(get(k))); + } + + b.append('}'); + return b.toString(); + } + }; for(Map.Entry entry: _map.entrySet()) { From 62713fda2fbe324e0480ab77c45db8caad44fa43 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Tue, 10 Apr 2012 15:03:38 +1000 Subject: [PATCH 081/100] 376324 is not respected in --- .../java/org/eclipse/jetty/servlet/ServletHolder.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) 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 8d6e2f75164..e34b1d40a42 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 @@ -587,10 +587,14 @@ public class ServletHolder extends Holder implements UserIdentity.Scope // Handle run as if (_identityService!=null) old_run_as=_identityService.setRunAs(baseRequest.getResolvedUserIdentity(),_runAsToken); - + if (!isAsyncSupported()) baseRequest.setAsyncSupported(false); - + + MultipartConfigElement mpce = ((Registration)getRegistration()).getMultipartConfig(); + if (mpce != null) + request.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, mpce); + servlet.service(request,response); servlet_error=false; } From f81ea123202a1e96c0738184e101b41dfa1347be Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Wed, 11 Apr 2012 12:37:51 +1000 Subject: [PATCH 082/100] 375709 Ensure resolveTempDirectory failure does not deadlock; improve error message --- .../java/org/eclipse/jetty/webapp/WebInfConfiguration.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java index d7748365c8e..fc9f3734c02 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java @@ -305,7 +305,8 @@ public class WebInfConfiguration extends AbstractConfiguration } catch(IOException e) { - LOG.warn("tmpdir",e); System.exit(1); + tmpDir = null; + throw new IllegalStateException("Cannot create tmp dir in "+System.getProperty("java.io.tmpdir")+ " for context "+context,e); } } } From 4412d311a9a440572fd15663cc00392754467b79 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 11 Apr 2012 17:21:02 +1000 Subject: [PATCH 083/100] 370081:fixed test reset --- .../rewrite/handler/RewriteRegexRuleTest.java | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java index a804db70c31..adb8777f12f 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java @@ -27,21 +27,21 @@ public class RewriteRegexRuleTest extends AbstractRuleTestCase { private String[][] _tests= { - {"/foo/bar",null,".*","/replace","/replace",null}, - {"/foo/bar","n=v",".*","/replace","/replace","n=v"}, - {"/foo/bar",null,"/xxx.*","/replace",null,null}, - {"/foo/bar",null,"/(.*)/(.*)","/$2/$1/xxx","/bar/foo/xxx",null}, - {"/foo/bar",null,"/(.*)/(.*)","/test?p2=$2&p1=$1","/test","p2=bar&p1=foo"}, - {"/foo/bar","n=v","/(.*)/(.*)","/test?p2=$2&p1=$1","/test","n=v&p2=bar&p1=foo"}, - {"/foo/bar",null,"/(.*)/(.*)","/foo/bar?p2=$2&p1=$1","/foo/bar","p2=bar&p1=foo"}, - {"/foo/bar","n=v","/(.*)/(.*)","/foo/bar?p2=$2&p1=$1","/foo/bar","n=v&p2=bar&p1=foo"}, - {"/foo/bar",null,"/(foo)/(.*)(bar)","/$3/$1/xxx$2","/bar/foo/xxx",null}, - {"/foo/$bar",null,".*","/$replace","/$replace",null}, - {"/foo/$bar",null,"/foo/(.*)","/$1/replace","/$bar/replace",null}, - {"/foo/bar/info",null,"/foo/(NotHere)?([^/]*)/(.*)","/$3/other?p1=$2","/info/other","p1=bar"}, - {"/foo/bar/info",null,"/foo/(NotHere)?([^/]*)/(.*)","/$3/other?p1=$2&$Q","/info/other","p1=bar&"}, - {"/foo/bar/info","n=v","/foo/(NotHere)?([^/]*)/(.*)","/$3/other?p1=$2&$Q","/info/other","p1=bar&n=v"}, - {"/foo/bar/info","n=v","/foo/(NotHere)?([^/]*)/(.*)","/$3/other?p1=$2","/info/other","n=v&p1=bar"}, + {"/foo0/bar",null,".*","/replace","/replace",null}, + {"/foo1/bar","n=v",".*","/replace","/replace","n=v"}, + {"/foo2/bar",null,"/xxx.*","/replace",null,null}, + {"/foo3/bar",null,"/(.*)/(.*)","/$2/$1/xxx","/bar/foo3/xxx",null}, + {"/foo4/bar",null,"/(.*)/(.*)","/test?p2=$2&p1=$1","/test","p2=bar&p1=foo4"}, + {"/foo5/bar","n=v","/(.*)/(.*)","/test?p2=$2&p1=$1","/test","n=v&p2=bar&p1=foo5"}, + {"/foo6/bar",null,"/(.*)/(.*)","/foo6/bar?p2=$2&p1=$1","/foo6/bar","p2=bar&p1=foo6"}, + {"/foo7/bar","n=v","/(.*)/(.*)","/foo7/bar?p2=$2&p1=$1","/foo7/bar","n=v&p2=bar&p1=foo7"}, + {"/foo8/bar",null,"/(foo8)/(.*)(bar)","/$3/$1/xxx$2","/bar/foo8/xxx",null}, + {"/foo9/$bar",null,".*","/$replace","/$replace",null}, + {"/fooA/$bar",null,"/fooA/(.*)","/$1/replace","/$bar/replace",null}, + {"/fooB/bar/info",null,"/fooB/(NotHere)?([^/]*)/(.*)","/$3/other?p1=$2","/info/other","p1=bar"}, + {"/fooC/bar/info",null,"/fooC/(NotHere)?([^/]*)/(.*)","/$3/other?p1=$2&$Q","/info/other","p1=bar&"}, + {"/fooD/bar/info","n=v","/fooD/(NotHere)?([^/]*)/(.*)","/$3/other?p1=$2&$Q","/info/other","p1=bar&n=v"}, + {"/fooE/bar/info","n=v","/fooE/(NotHere)?([^/]*)/(.*)","/$3/other?p1=$2","/info/other","n=v&p1=bar"}, }; private RewriteRegexRule _rule; @@ -97,6 +97,7 @@ public class RewriteRegexRuleTest extends AbstractRuleTestCase container.addRule(_rule); for (String[] test : _tests) { + reset(); String t=test[0]+"?"+test[1]+">"+test[2]+"|"+test[3]; _rule.setRegex(test[2]); _rule.setReplacement(test[3]); From 20a3d3c12ec8f4cb5f30747304f1ff7d4eaf1be8 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 11 Apr 2012 18:21:39 +1000 Subject: [PATCH 084/100] 376424: do not recycle buffers before content consumed asynchronously --- .../src/main/java/org/eclipse/jetty/http/HttpParser.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java index c7d7d39f88a..0b4053c15e3 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java @@ -260,7 +260,6 @@ public class HttpParser implements Parser { _state=STATE_END; _handler.messageComplete(_contentPosition); - returnBuffers(); return 1; } @@ -326,7 +325,6 @@ public class HttpParser implements Parser if (!isComplete() && !isIdle()) throw new EofException(); - returnBuffers(); return -1; } length=_buffer.length(); @@ -440,7 +438,6 @@ public class HttpParser implements Parser _state=STATE_SEEKING_EOF; _handler.headerComplete(); _handler.messageComplete(_contentPosition); - returnBuffers(); return 1; } break; @@ -470,7 +467,6 @@ public class HttpParser implements Parser _state=STATE_SEEKING_EOF; _handler.headerComplete(); _handler.messageComplete(_contentPosition); - returnBuffers(); return 1; } } @@ -634,7 +630,6 @@ public class HttpParser implements Parser _handler.headerComplete(); _state=_persistent||(_responseStatus>=100&&_responseStatus<200)?STATE_END:STATE_SEEKING_EOF; _handler.messageComplete(_contentPosition); - returnBuffers(); return 1; default: @@ -840,7 +835,6 @@ public class HttpParser implements Parser { _state=_persistent?STATE_END:STATE_SEEKING_EOF; _handler.messageComplete(_contentPosition); - returnBuffers(); return 1; } @@ -860,7 +854,6 @@ public class HttpParser implements Parser { _state=_persistent?STATE_END:STATE_SEEKING_EOF; _handler.messageComplete(_contentPosition); - returnBuffers(); } // TODO adjust the _buffer to keep unconsumed content return 1; @@ -895,7 +888,6 @@ public class HttpParser implements Parser _eol=_buffer.get(); _state=_persistent?STATE_END:STATE_SEEKING_EOF; _handler.messageComplete(_contentPosition); - returnBuffers(); return 1; } else @@ -926,7 +918,6 @@ public class HttpParser implements Parser _eol=_buffer.get(); _state=_persistent?STATE_END:STATE_SEEKING_EOF; _handler.messageComplete(_contentPosition); - returnBuffers(); return 1; } else From 47c1587166a7951343a20c248da5b074dd70699c Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 11 Apr 2012 10:39:23 +0200 Subject: [PATCH 085/100] Strengthen the behavior of Stream methods to throw if they are used wrongly, for example sending DATA frames before a REPLY and so on. --- .../eclipse/jetty/spdy/StandardStream.java | 38 ++++++- .../org/eclipse/jetty/spdy/APIUsageTest.java | 98 +++++++++++++++++++ .../org/eclipse/jetty/spdy/SynReplyTest.java | 35 ------- 3 files changed, 132 insertions(+), 39 deletions(-) create mode 100644 jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/APIUsageTest.java diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java index d1fccff757c..013159d7d90 100644 --- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java +++ b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java @@ -50,7 +50,7 @@ public class StandardStream implements IStream private final ISession session; private final AtomicInteger windowSize; private volatile StreamFrameListener listener; - private volatile boolean opened; + private volatile OpenState openState = OpenState.SYN_SENT; private volatile boolean halfClosed; private volatile boolean closed; @@ -141,12 +141,12 @@ public class StandardStream implements IStream { case SYN_STREAM: { - opened = true; + openState = OpenState.SYN_RECV; break; } case SYN_REPLY: { - opened = true; + openState = OpenState.REPLY_RECV; SynReplyFrame synReply = (SynReplyFrame)frame; updateCloseState(synReply.isClose()); ReplyInfo replyInfo = new ReplyInfo(synReply.getHeaders(), synReply.isClose()); @@ -183,7 +183,7 @@ public class StandardStream implements IStream @Override public void process(DataFrame frame, ByteBuffer data) { - if (!opened) + if (!canReceive()) { session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR)); return; @@ -286,6 +286,7 @@ public class StandardStream implements IStream @Override public void reply(ReplyInfo replyInfo, long timeout, TimeUnit unit, Handler handler) { + openState = OpenState.REPLY_SENT; updateCloseState(replyInfo.isClose()); SynReplyFrame frame = new SynReplyFrame(session.getVersion(), replyInfo.getFlags(), getId(), replyInfo.getHeaders()); session.control(this, frame, timeout, unit, handler, null); @@ -302,6 +303,12 @@ public class StandardStream implements IStream @Override public void data(DataInfo dataInfo, long timeout, TimeUnit unit, Handler handler) { + if (!canSend()) + { + session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR)); + throw new IllegalStateException("Cannot send DATA frames before a SYN_REPLY frame"); + } + // Cannot update the close state here, because the data that we send may // be flow controlled, so we need the stream to update the window size. session.data(this, dataInfo, timeout, unit, handler, null); @@ -318,6 +325,12 @@ public class StandardStream implements IStream @Override public void headers(HeadersInfo headersInfo, long timeout, TimeUnit unit, Handler handler) { + if (!canSend()) + { + session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR)); + throw new IllegalStateException("Cannot send a HEADERS frame before a SYN_REPLY frame"); + } + updateCloseState(headersInfo.isClose()); HeadersFrame frame = new HeadersFrame(session.getVersion(), headersInfo.getFlags(), getId(), headersInfo.getHeaders()); session.control(this, frame, timeout, unit, handler, null); @@ -334,4 +347,21 @@ public class StandardStream implements IStream { return String.format("stream=%d v%d closed=%s", getId(), session.getVersion(), isClosed() ? "true" : isHalfClosed() ? "half" : "false"); } + + private boolean canSend() + { + OpenState openState = this.openState; + return openState == OpenState.SYN_SENT || openState == OpenState.REPLY_RECV || openState == OpenState.REPLY_SENT; + } + + private boolean canReceive() + { + OpenState openState = this.openState; + return openState == OpenState.SYN_RECV || openState == OpenState.REPLY_RECV || openState == OpenState.REPLY_SENT; + } + + private enum OpenState + { + SYN_SENT, SYN_RECV, REPLY_SENT, REPLY_RECV + } } diff --git a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/APIUsageTest.java b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/APIUsageTest.java new file mode 100644 index 00000000000..36a0a2cb7bf --- /dev/null +++ b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/APIUsageTest.java @@ -0,0 +1,98 @@ +package org.eclipse.jetty.spdy; + +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.spdy.api.BytesDataInfo; +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.SessionFrameListener; +import org.eclipse.jetty.spdy.api.SessionStatus; +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.api.server.ServerSessionFrameListener; +import org.eclipse.jetty.spdy.frames.ControlFrameType; +import org.eclipse.jetty.spdy.frames.GoAwayFrame; +import org.eclipse.jetty.spdy.generator.Generator; +import org.junit.Assert; +import org.junit.Test; + +public class APIUsageTest extends AbstractTest +{ + @Test + public void testSendDataBeforeReplyIsIllegal() throws Exception + { + final CountDownLatch resetLatch = new CountDownLatch(1); + final CountDownLatch latch = new CountDownLatch(1); + Session session = startClient(startServer(new ServerSessionFrameListener.Adapter() + { + @Override + public StreamFrameListener onSyn(Stream stream, SynInfo synInfo) + { + try + { + stream.data(new StringDataInfo("failure", true)); + return null; + } + catch (IllegalStateException x) + { + latch.countDown(); + return null; + } + } + }), new SessionFrameListener.Adapter() + { + @Override + public void onRst(Session session, RstInfo rstInfo) + { + Assert.assertSame(StreamStatus.PROTOCOL_ERROR, rstInfo.getStreamStatus()); + resetLatch.countDown(); + } + }); + session.syn(new SynInfo(true), null); + Assert.assertTrue(latch.await(5, TimeUnit.SECONDS)); + Assert.assertTrue(resetLatch.await(5, TimeUnit.SECONDS)); + } + + @Test + public void testReceiveDataBeforeReplyIsIllegal() throws Exception + { + ServerSocketChannel server = ServerSocketChannel.open(); + server.bind(new InetSocketAddress("localhost", 0)); + + Session session = startClient(new InetSocketAddress("localhost", server.socket().getLocalPort()), null); + session.syn(new SynInfo(true), null); + + SocketChannel channel = server.accept(); + ByteBuffer readBuffer = ByteBuffer.allocate(1024); + channel.read(readBuffer); + readBuffer.flip(); + int streamId = readBuffer.getInt(8); + + Generator generator = new Generator(new StandardByteBufferPool(), new StandardCompressionFactory.StandardCompressor()); + byte[] bytes = new byte[1]; + ByteBuffer writeBuffer = generator.data(streamId, bytes.length, new BytesDataInfo(bytes, true)); + channel.write(writeBuffer); + + readBuffer.clear(); + channel.read(readBuffer); + readBuffer.flip(); + Assert.assertEquals(ControlFrameType.RST_STREAM.getCode(), readBuffer.getShort(2)); + Assert.assertEquals(streamId, readBuffer.getInt(8)); + + writeBuffer = generator.control(new GoAwayFrame(SPDY.V2, 0, SessionStatus.OK.getCode())); + channel.write(writeBuffer); + channel.shutdownOutput(); + channel.close(); + + server.close(); + } +} diff --git a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SynReplyTest.java b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SynReplyTest.java index 7e5d67fdd2f..207e1335b03 100644 --- a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SynReplyTest.java +++ b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SynReplyTest.java @@ -30,12 +30,10 @@ import org.eclipse.jetty.spdy.api.DataInfo; import org.eclipse.jetty.spdy.api.Handler; import org.eclipse.jetty.spdy.api.Headers; import org.eclipse.jetty.spdy.api.ReplyInfo; -import org.eclipse.jetty.spdy.api.RstInfo; import org.eclipse.jetty.spdy.api.Session; import org.eclipse.jetty.spdy.api.SessionFrameListener; 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.api.server.ServerSessionFrameListener; @@ -324,39 +322,6 @@ public class SynReplyTest extends AbstractTest Assert.assertTrue(clientDataLatch.await(5, TimeUnit.SECONDS)); } - @Test - public void testSynDataRst() throws Exception - { - final AtomicReference ref = new AtomicReference<>(); - final CountDownLatch latch = new CountDownLatch(1); - ServerSessionFrameListener serverSessionFrameListener = new ServerSessionFrameListener.Adapter() - { - @Override - public StreamFrameListener onSyn(Stream stream, SynInfo synInfo) - { - // Do not send the reply, we expect a RST_STREAM - stream.data(new StringDataInfo("foo", true)); - return null; - } - - @Override - public void onRst(Session session, RstInfo rstInfo) - { - ref.set(rstInfo); - latch.countDown(); - } - }; - Session session = startClient(startServer(serverSessionFrameListener), null); - - Stream stream = session.syn(new SynInfo(true), null).get(5, TimeUnit.SECONDS); - - Assert.assertTrue(latch.await(5, TimeUnit.SECONDS)); - RstInfo rstInfo = ref.get(); - Assert.assertNotNull(rstInfo); - Assert.assertEquals(stream.getId(), rstInfo.getStreamId()); - Assert.assertSame(StreamStatus.PROTOCOL_ERROR, rstInfo.getStreamStatus()); - } - @Test public void testSynReplyDataSynReplyData() throws Exception { From 5b7fe58593b3250b4f70ea6bc6c9d51a35c9b635 Mon Sep 17 00:00:00 2001 From: Thomas Becker Date: Wed, 11 Apr 2012 10:55:32 +0200 Subject: [PATCH 086/100] 376373: GzipFilter now does not ignore _excludePath + fix for ignored _excludeAgentPatterns if _excludeAgent is set Change-Id: I1f0ac1b5a12d75b755a85cc9bdb4906c6b7a84a6 --- .../eclipse/jetty/servlets/GzipFilter.java | 12 +++- .../jetty/servlets/GzipFilterDefaultTest.java | 70 +++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java index 1b993e6eedf..4428ec1e862 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java @@ -238,7 +238,7 @@ public class GzipFilter extends UserAgentFilter return true; } } - else if (_excludedAgentPatterns != null) + if (_excludedAgentPatterns != null) { for (Pattern pattern : _excludedAgentPatterns) { @@ -263,6 +263,16 @@ public class GzipFilter extends UserAgentFilter { if (requestURI == null) return false; + if (_excludedPaths != null) + { + for (String excludedPath : _excludedPaths) + { + if (requestURI.contains(excludedPath)) + { + return true; + } + } + } if (_excludedPathPatterns != null) { for (Pattern pattern : _excludedPathPatterns) diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java index 82fd54dc11f..b9f7081d138 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java @@ -25,6 +25,8 @@ public class GzipFilterDefaultTest public static class HttpStatusServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + private int _status = 204; public HttpStatusServlet() @@ -159,4 +161,72 @@ public class GzipFilterDefaultTest tester.stop(); } } + + @Test + public void testUserAgentExclusionByExcludedAgentPatterns() throws Exception + { + GzipTester tester = new GzipTester(testingdir); + + FilterHolder holder = tester.setContentServlet(DefaultServlet.class); + holder.setInitParameter("excludedAgents", "bar"); + holder.setInitParameter("excludeAgentPatterns", "fo.*"); + tester.setUserAgent("foo"); + + int filesize = GzipResponseWrapper.DEFAULT_BUFFER_SIZE * 4; + tester.prepareServerFile("file.txt",filesize); + + try + { + tester.start(); + tester.assertIsResponseNotGzipCompressed("file.txt", filesize, HttpStatus.OK_200); + } + finally + { + tester.stop(); + } + } + + @Test + public void testExcludePaths() throws Exception + { + GzipTester tester = new GzipTester(testingdir); + + FilterHolder holder = tester.setContentServlet(DefaultServlet.class); + holder.setInitParameter("excludePaths", "/context/"); + + int filesize = GzipResponseWrapper.DEFAULT_BUFFER_SIZE * 4; + tester.prepareServerFile("file.txt",filesize); + + try + { + tester.start(); + tester.assertIsResponseNotGzipCompressed("file.txt", filesize, HttpStatus.OK_200); + } + finally + { + tester.stop(); + } + } + + @Test + public void testExcludePathPatterns() throws Exception + { + GzipTester tester = new GzipTester(testingdir); + + FilterHolder holder = tester.setContentServlet(DefaultServlet.class); + holder.setInitParameter("excludePathPatterns", "/cont.*"); + + int filesize = GzipResponseWrapper.DEFAULT_BUFFER_SIZE * 4; + tester.prepareServerFile("file.txt",filesize); + + try + { + tester.start(); + tester.assertIsResponseNotGzipCompressed("file.txt", filesize, HttpStatus.OK_200); + } + finally + { + tester.stop(); + } + } } From 942c8a19f56d31a9f7305b31ca3bd714518723b7 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Wed, 11 Apr 2012 19:53:55 +1000 Subject: [PATCH 087/100] 373269 Make ServletHandler.notFound() method impl do nothing - override to send back 404. --- .../src/main/java/org/eclipse/jetty/servlet/ServletHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java index b9e2c24e58f..76f360592ad 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java @@ -1233,7 +1233,7 @@ public class ServletHandler extends ScopedHandler { if(LOG.isDebugEnabled()) LOG.debug("Not Found "+request.getRequestURI()); - response.sendError(HttpServletResponse.SC_NOT_FOUND); + //Override to send an error back, eg with: response.sendError(HttpServletResponse.SC_NOT_FOUND); } /* ------------------------------------------------------------ */ From 972087d0684fa46341e7c6ef32dcd95c407400c1 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 11 Apr 2012 12:18:56 +0200 Subject: [PATCH 088/100] 376201 - HalfClosed state not handled properly. --- .../java/org/eclipse/jetty/spdy/IStream.java | 3 +- .../eclipse/jetty/spdy/StandardSession.java | 11 ++- .../eclipse/jetty/spdy/StandardStream.java | 80 ++++++++++++++----- .../eclipse/jetty/spdy/FlowControlTest.java | 2 +- ...eTest.java => ProtocolViolationsTest.java} | 68 +++++++++++++++- 5 files changed, 141 insertions(+), 23 deletions(-) rename jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/{APIUsageTest.java => ProtocolViolationsTest.java} (58%) diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/IStream.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/IStream.java index 86e3bd98066..2291cf78b64 100644 --- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/IStream.java +++ b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/IStream.java @@ -68,8 +68,9 @@ public interface IStream extends Stream * of true puts the stream into closed state.

    * * @param close whether the close state should be updated + * @param local whether the close is local or remote */ - public void updateCloseState(boolean close); + public void updateCloseState(boolean close, boolean local); /** *

    Processes the given control frame, 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 4caa3df86c4..8b1a53dda42 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 @@ -398,6 +398,7 @@ public class StandardSession implements ISession, Parser.Listener, Handler frameBytes = new ControlFrameBytes<>(stream, handler, context, frame, buffer); if (timeout > 0) frameBytes.task = scheduler.schedule(frameBytes, timeout, unit); - append(frameBytes); + + // Special handling for PING frames, they must be sent as soon as possible + if (ControlFrameType.PING == frame.getType()) + prepend(frameBytes); + else + append(frameBytes); } flush(); @@ -1089,7 +1096,7 @@ public class StandardSession implements ISession, Parser.Listener, Handler handler) { openState = OpenState.REPLY_SENT; - updateCloseState(replyInfo.isClose()); + updateCloseState(replyInfo.isClose(), true); SynReplyFrame frame = new SynReplyFrame(session.getVersion(), replyInfo.getFlags(), getId(), replyInfo.getHeaders()); session.control(this, frame, timeout, unit, handler, null); } @@ -306,7 +329,12 @@ public class StandardStream implements IStream if (!canSend()) { session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR)); - throw new IllegalStateException("Cannot send DATA frames before a SYN_REPLY frame"); + throw new IllegalStateException("Protocol violation: cannot send a DATA frame before a SYN_REPLY frame"); + } + if (isLocallyClosed()) + { + session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR)); + throw new IllegalStateException("Protocol violation: cannot send a DATA frame on a closed stream"); } // Cannot update the close state here, because the data that we send may @@ -328,10 +356,15 @@ public class StandardStream implements IStream if (!canSend()) { session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR)); - throw new IllegalStateException("Cannot send a HEADERS frame before a SYN_REPLY frame"); + throw new IllegalStateException("Protocol violation: cannot send a HEADERS frame before a SYN_REPLY frame"); + } + if (isLocallyClosed()) + { + session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR)); + throw new IllegalStateException("Protocol violation: cannot send a HEADERS frame on a closed stream"); } - updateCloseState(headersInfo.isClose()); + updateCloseState(headersInfo.isClose(), true); HeadersFrame frame = new HeadersFrame(session.getVersion(), headersInfo.getFlags(), getId(), headersInfo.getHeaders()); session.control(this, frame, timeout, unit, handler, null); } @@ -339,13 +372,19 @@ public class StandardStream implements IStream @Override public boolean isClosed() { - return closed; + return closeState == CloseState.CLOSED; + } + + private boolean isLocallyClosed() + { + CloseState closeState = this.closeState; + return closeState == CloseState.LOCALLY_CLOSED || closeState == CloseState.CLOSED; } @Override public String toString() { - return String.format("stream=%d v%d closed=%s", getId(), session.getVersion(), isClosed() ? "true" : isHalfClosed() ? "half" : "false"); + return String.format("stream=%d v%d %s", getId(), session.getVersion(), closeState); } private boolean canSend() @@ -364,4 +403,9 @@ public class StandardStream implements IStream { SYN_SENT, SYN_RECV, REPLY_SENT, REPLY_RECV } + + private enum CloseState + { + OPENED, LOCALLY_CLOSED, REMOTELY_CLOSED, CLOSED + } } diff --git a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/FlowControlTest.java b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/FlowControlTest.java index 6e246409d58..f1908e73bcc 100644 --- a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/FlowControlTest.java +++ b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/FlowControlTest.java @@ -307,7 +307,7 @@ public class FlowControlTest extends AbstractTest Assert.assertTrue(settingsLatch.await(5, TimeUnit.SECONDS)); - Stream stream = session.syn(new SynInfo(true), null).get(5, TimeUnit.SECONDS); + Stream stream = session.syn(new SynInfo(false), null).get(5, TimeUnit.SECONDS); final int length = 5 * windowSize; stream.data(new BytesDataInfo(new byte[length], true)); diff --git a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/APIUsageTest.java b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/ProtocolViolationsTest.java similarity index 58% rename from jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/APIUsageTest.java rename to jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/ProtocolViolationsTest.java index 36a0a2cb7bf..92e642f2b13 100644 --- a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/APIUsageTest.java +++ b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/ProtocolViolationsTest.java @@ -8,6 +8,9 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.spdy.api.BytesDataInfo; +import org.eclipse.jetty.spdy.api.DataInfo; +import org.eclipse.jetty.spdy.api.Headers; +import org.eclipse.jetty.spdy.api.HeadersInfo; import org.eclipse.jetty.spdy.api.RstInfo; import org.eclipse.jetty.spdy.api.SPDY; import org.eclipse.jetty.spdy.api.Session; @@ -21,11 +24,12 @@ import org.eclipse.jetty.spdy.api.SynInfo; import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener; import org.eclipse.jetty.spdy.frames.ControlFrameType; import org.eclipse.jetty.spdy.frames.GoAwayFrame; +import org.eclipse.jetty.spdy.frames.SynReplyFrame; import org.eclipse.jetty.spdy.generator.Generator; import org.junit.Assert; import org.junit.Test; -public class APIUsageTest extends AbstractTest +public class ProtocolViolationsTest extends AbstractTest { @Test public void testSendDataBeforeReplyIsIllegal() throws Exception @@ -95,4 +99,66 @@ public class APIUsageTest extends AbstractTest server.close(); } + + @Test(expected = IllegalStateException.class) + public void testSendDataAfterCloseIsIllegal() throws Exception + { + Session session = startClient(startServer(null), null); + Stream stream = session.syn(new SynInfo(true), null).get(5, TimeUnit.SECONDS); + stream.data(new StringDataInfo("test", true)); + } + + @Test(expected = IllegalStateException.class) + public void testSendHeadersAfterCloseIsIllegal() throws Exception + { + Session session = startClient(startServer(null), null); + Stream stream = session.syn(new SynInfo(true), null).get(5, TimeUnit.SECONDS); + stream.headers(new HeadersInfo(new Headers(), true)); + } + + @Test + public void testDataSentAfterCloseIsDiscardedByRecipient() throws Exception + { + ServerSocketChannel server = ServerSocketChannel.open(); + server.bind(new InetSocketAddress("localhost", 0)); + + Session session = startClient(new InetSocketAddress("localhost", server.socket().getLocalPort()), null); + final CountDownLatch dataLatch = new CountDownLatch(2); + session.syn(new SynInfo(true), new StreamFrameListener.Adapter() + { + @Override + public void onData(Stream stream, DataInfo dataInfo) + { + dataLatch.countDown(); + } + }); + + SocketChannel channel = server.accept(); + ByteBuffer readBuffer = ByteBuffer.allocate(1024); + channel.read(readBuffer); + readBuffer.flip(); + int streamId = readBuffer.getInt(8); + + Generator generator = new Generator(new StandardByteBufferPool(), new StandardCompressionFactory.StandardCompressor()); + + ByteBuffer writeBuffer = generator.control(new SynReplyFrame(SPDY.V2, (byte)0, streamId, new Headers())); + channel.write(writeBuffer); + + byte[] bytes = new byte[1]; + writeBuffer = generator.data(streamId, bytes.length, new BytesDataInfo(bytes, true)); + channel.write(writeBuffer); + + // Write again to simulate the faulty condition + writeBuffer.flip(); + channel.write(writeBuffer); + + Assert.assertFalse(dataLatch.await(1, TimeUnit.SECONDS)); + + writeBuffer = generator.control(new GoAwayFrame(SPDY.V2, 0, SessionStatus.OK.getCode())); + channel.write(writeBuffer); + channel.shutdownOutput(); + channel.close(); + + server.close(); + } } From 543d2a18caf3d10c2b3a91014d8fe93124ce7f69 Mon Sep 17 00:00:00 2001 From: Thomas Becker Date: Wed, 11 Apr 2012 13:03:33 +0200 Subject: [PATCH 089/100] 376373: GzipFilter now does not ignore _excludePath + fix for ignored _excludeAgentPatterns if _excludeAgent is set Change-Id: I8d3d0fd62677c3a54cbe93febf4cde49aa24cc74 --- .../src/main/java/org/eclipse/jetty/servlets/GzipFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java index db36f51f220..94d50dee76d 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java @@ -350,7 +350,7 @@ public class GzipFilter extends UserAgentFilter { for (String excludedPath : _excludedPaths) { - if (requestURI.contains(excludedPath)) + if (requestURI.startsWith(excludedPath)) { return true; } From 08573701efc447fb95da22bfc711f79b6908a60e Mon Sep 17 00:00:00 2001 From: Thomas Becker Date: Wed, 11 Apr 2012 14:47:28 +0200 Subject: [PATCH 090/100] 376373: GzipFilter now does not ignore _excludePath + fix for ignored _excludeAgentPatterns if _excludeAgent is set Change-Id: Ie9940141f9b92b267f4b405ef4ec3ab5dee43be5 --- .../eclipse/jetty/servlets/GzipFilter.java | 6 +- .../jetty/servlets/GzipFilterDefaultTest.java | 79 +++++++++---------- 2 files changed, 42 insertions(+), 43 deletions(-) diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java index 94d50dee76d..650632b7f38 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java @@ -303,7 +303,7 @@ public class GzipFilter extends UserAgentFilter } /** - * Checks to see if the UserAgent is excluded + * Checks to see if the userAgent is excluded * * @param ua * the user agent @@ -336,9 +336,9 @@ public class GzipFilter extends UserAgentFilter } /** - * Checks to see if the Path is excluded + * Checks to see if the path is excluded * - * @param ua + * @param requestURI * the request uri * @return boolean true if excluded */ diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java index 89f2f458534..05f53c97e3e 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java @@ -31,11 +31,10 @@ public class GzipFilterDefaultTest public static Collection data() { String[][] data = new String[][] - { - { GzipFilter.GZIP }, - { GzipFilter.DEFLATE } - }; - + { + { GzipFilter.GZIP }, + { GzipFilter.DEFLATE } }; + return Arrays.asList(data); } @@ -166,88 +165,88 @@ public class GzipFilterDefaultTest @Test public void testUserAgentExclusion() throws Exception { - GzipTester tester = new GzipTester(testingdir, compressionType); - + GzipTester tester = new GzipTester(testingdir,compressionType); + FilterHolder holder = tester.setContentServlet(DefaultServlet.class); - holder.setInitParameter("excludedAgents", "foo"); + holder.setInitParameter("excludedAgents","foo"); tester.setUserAgent("foo"); - + int filesize = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE * 4; tester.prepareServerFile("file.txt",filesize); - + try { tester.start(); - tester.assertIsResponseNotGzipCompressed("file.txt", filesize, HttpStatus.OK_200); - } + tester.assertIsResponseNotGzipCompressed("file.txt",filesize,HttpStatus.OK_200); + } finally { tester.stop(); } } - + @Test public void testUserAgentExclusionByExcludedAgentPatterns() throws Exception { - GzipTester tester = new GzipTester(testingdir); - + GzipTester tester = new GzipTester(testingdir,compressionType); + FilterHolder holder = tester.setContentServlet(DefaultServlet.class); - holder.setInitParameter("excludedAgents", "bar"); - holder.setInitParameter("excludeAgentPatterns", "fo.*"); + holder.setInitParameter("excludedAgents","bar"); + holder.setInitParameter("excludeAgentPatterns","fo.*"); tester.setUserAgent("foo"); - - int filesize = GzipResponseWrapper.DEFAULT_BUFFER_SIZE * 4; + + int filesize = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE * 4; tester.prepareServerFile("file.txt",filesize); - + try { tester.start(); - tester.assertIsResponseNotGzipCompressed("file.txt", filesize, HttpStatus.OK_200); - } + tester.assertIsResponseNotGzipCompressed("file.txt",filesize,HttpStatus.OK_200); + } finally { tester.stop(); } } - + @Test public void testExcludePaths() throws Exception { - GzipTester tester = new GzipTester(testingdir); - + GzipTester tester = new GzipTester(testingdir,compressionType); + FilterHolder holder = tester.setContentServlet(DefaultServlet.class); - holder.setInitParameter("excludePaths", "/context/"); - - int filesize = GzipResponseWrapper.DEFAULT_BUFFER_SIZE * 4; + holder.setInitParameter("excludePaths","/context/"); + + int filesize = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE * 4; tester.prepareServerFile("file.txt",filesize); - + try { tester.start(); - tester.assertIsResponseNotGzipCompressed("file.txt", filesize, HttpStatus.OK_200); - } + tester.assertIsResponseNotGzipCompressed("file.txt",filesize,HttpStatus.OK_200); + } finally { tester.stop(); } } - + @Test public void testExcludePathPatterns() throws Exception { - GzipTester tester = new GzipTester(testingdir); - + GzipTester tester = new GzipTester(testingdir,compressionType); + FilterHolder holder = tester.setContentServlet(DefaultServlet.class); - holder.setInitParameter("excludePathPatterns", "/cont.*"); - - int filesize = GzipResponseWrapper.DEFAULT_BUFFER_SIZE * 4; + holder.setInitParameter("excludePathPatterns","/cont.*"); + + int filesize = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE * 4; tester.prepareServerFile("file.txt",filesize); - + try { tester.start(); - tester.assertIsResponseNotGzipCompressed("file.txt", filesize, HttpStatus.OK_200); - } + tester.assertIsResponseNotGzipCompressed("file.txt",filesize,HttpStatus.OK_200); + } finally { tester.stop(); From d98f699bea4a8ee62e01a3c32d0f8feda4e1fc62 Mon Sep 17 00:00:00 2001 From: Thomas Becker Date: Wed, 11 Apr 2012 20:38:16 +0200 Subject: [PATCH 091/100] 376519: Change compression type of deflate compression in GzipFilter and IncludableGzipFilter Change-Id: I83ed4a43ad432502ef5d5ca52c0e7370d8a5dd9f --- .../src/main/java/org/eclipse/jetty/servlets/GzipFilter.java | 3 ++- .../java/org/eclipse/jetty/servlets/IncludableGzipFilter.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java index 650632b7f38..f30ff4189ca 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java @@ -17,6 +17,7 @@ import java.util.HashSet; import java.util.Set; import java.util.StringTokenizer; import java.util.regex.Pattern; +import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; import java.util.zip.GZIPOutputStream; @@ -255,7 +256,7 @@ public class GzipFilter extends UserAgentFilter @Override protected DeflaterOutputStream createStream() throws IOException { - return new DeflaterOutputStream(_response.getOutputStream()); + return new DeflaterOutputStream(_response.getOutputStream(),new Deflater(Deflater.DEFAULT_COMPRESSION)); } }; } 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 972393e1644..95de423bc4b 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 @@ -18,6 +18,7 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; +import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; import java.util.zip.GZIPOutputStream; @@ -94,7 +95,7 @@ public class IncludableGzipFilter extends GzipFilter @Override protected DeflaterOutputStream createStream() throws IOException { - return new DeflaterOutputStream(_response.getOutputStream()); + return new DeflaterOutputStream(_response.getOutputStream(),new Deflater(Deflater.DEFAULT_COMPRESSION)); } }; } From c9ce3eb108a1362b73ed54a4c6d24fa47edd002f Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 12 Apr 2012 11:32:28 +1000 Subject: [PATCH 092/100] 362113: fixed StdErrLog so that it does not hold a copy of System.err and thus avoid being redirected if System.err is redirected --- .../org/eclipse/jetty/util/log/StdErrLog.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/log/StdErrLog.java b/jetty-util/src/main/java/org/eclipse/jetty/util/log/StdErrLog.java index 1848e7ad8c6..7636bd870dc 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/log/StdErrLog.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/log/StdErrLog.java @@ -77,7 +77,7 @@ public class StdErrLog extends AbstractLogger private int _level = LEVEL_INFO; // Level that this Logger was configured as (remembered in special case of .setDebugEnabled()) private int _configuredLevel; - private PrintStream _stderr = System.err; + private PrintStream _stderr = null; private boolean _source = __source; // Print the long form names, otherwise use abbreviated private boolean _printLongNames = __long; @@ -271,7 +271,7 @@ public class StdErrLog extends AbstractLogger { StringBuilder buffer = new StringBuilder(64); format(buffer,":WARN:",msg,args); - _stderr.println(buffer); + (_stderr==null?System.err:_stderr).println(buffer); } } @@ -286,7 +286,7 @@ public class StdErrLog extends AbstractLogger { StringBuilder buffer = new StringBuilder(64); format(buffer,":WARN:",msg,thrown); - _stderr.println(buffer); + (_stderr==null?System.err:_stderr).println(buffer); } } @@ -296,7 +296,7 @@ public class StdErrLog extends AbstractLogger { StringBuilder buffer = new StringBuilder(64); format(buffer,":INFO:",msg,args); - _stderr.println(buffer); + (_stderr==null?System.err:_stderr).println(buffer); } } @@ -311,7 +311,7 @@ public class StdErrLog extends AbstractLogger { StringBuilder buffer = new StringBuilder(64); format(buffer,":INFO:",msg,thrown); - _stderr.println(buffer); + (_stderr==null?System.err:_stderr).println(buffer); } } @@ -369,7 +369,7 @@ public class StdErrLog extends AbstractLogger public void setStdErrStream(PrintStream stream) { - this._stderr = stream; + this._stderr = stream==System.err?null:stream; } public void debug(String msg, Object... args) @@ -378,7 +378,7 @@ public class StdErrLog extends AbstractLogger { StringBuilder buffer = new StringBuilder(64); format(buffer,":DBUG:",msg,args); - _stderr.println(buffer); + (_stderr==null?System.err:_stderr).println(buffer); } } @@ -393,7 +393,7 @@ public class StdErrLog extends AbstractLogger { StringBuilder buffer = new StringBuilder(64); format(buffer,":DBUG:",msg,thrown); - _stderr.println(buffer); + (_stderr==null?System.err:_stderr).println(buffer); } } @@ -616,7 +616,7 @@ public class StdErrLog extends AbstractLogger { StringBuilder buffer = new StringBuilder(64); format(buffer,":IGNORED:","",ignored); - _stderr.println(buffer); + (_stderr==null?System.err:_stderr).println(buffer); } } } From a565c72adbd52184537af54492f7710787b362b6 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 12 Apr 2012 16:51:59 +1000 Subject: [PATCH 093/100] 374550: remove printStackTrace calls --- .../eclipse/jetty/client/HttpDestination.java | 8 +++++--- .../client/security/DigestAuthentication.java | 6 ++---- .../eclipse/jetty/io/bio/StringEndPoint.java | 8 +++++--- .../jetty/servlets/MultiPartFilter.java | 2 +- .../jetty/util/MultiPartOutputStream.java | 13 ++---------- .../jetty/util/RolloverFileOutputStream.java | 1 + .../java/org/eclipse/jetty/util/TypeUtil.java | 20 +++++++++---------- .../org/eclipse/jetty/util/ajax/JSON.java | 4 ++-- .../jetty/util/ajax/JSONObjectConvertor.java | 1 - .../util/ajax/JSONPojoConvertorFactory.java | 4 ++-- .../eclipse/jetty/xml/XmlConfiguration.java | 7 +------ 11 files changed, 31 insertions(+), 43 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java index 18a197ced6a..5ea60430766 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java @@ -475,10 +475,12 @@ public class HttpDestination implements Dumpable HttpEventListener elistener = (HttpEventListener)constructor.newInstance(this, ex); ex.setEventListener(elistener); } - catch (Exception e) + catch (final Exception e) { - e.printStackTrace(); - throw new IOException("Unable to instantiate registered listener for destination: " + listenerClass); + throw new IOException("Unable to instantiate registered listener for destination: " + listenerClass) + { + {initCause(e);} + }; } } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/security/DigestAuthentication.java b/jetty-client/src/main/java/org/eclipse/jetty/client/security/DigestAuthentication.java index 032a2aafab2..a5ba37ee740 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/security/DigestAuthentication.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/security/DigestAuthentication.java @@ -104,8 +104,7 @@ public class DigestAuthentication implements Authentication } catch(Exception e) { - e.printStackTrace(); - return null; + throw new RuntimeException(e); } } @@ -119,8 +118,7 @@ public class DigestAuthentication implements Authentication } catch(Exception e) { - e.printStackTrace(); - return null; + throw new RuntimeException(e); } } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StringEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StringEndPoint.java index 1698249d438..e55d4aeb6b6 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StringEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StringEndPoint.java @@ -70,10 +70,12 @@ public class StringEndPoint extends StreamEndPoint _bout.reset(); return s; } - catch(Exception e) + catch(final Exception e) { - e.printStackTrace(); - throw new IllegalStateException(_encoding+": "+e.toString()); + throw new IllegalStateException(_encoding) + { + {initCause(e);} + }; } } diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java index 787191e49e4..e7207592227 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java @@ -503,7 +503,7 @@ public class MultiPartFilter implements Filter } catch(Exception e) { - e.printStackTrace(); + throw new RuntimeException(e); } } else if (o instanceof String) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartOutputStream.java b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartOutputStream.java index 5653e446ed9..5f129e0d8cb 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartOutputStream.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartOutputStream.java @@ -27,20 +27,11 @@ import java.io.OutputStream; public class MultiPartOutputStream extends FilterOutputStream { /* ------------------------------------------------------------ */ - private static byte[] __CRLF; - private static byte[] __DASHDASH; + private static final byte[] __CRLF={'\r','\n'}; + private static final byte[] __DASHDASH={'-','-'}; public static String MULTIPART_MIXED="multipart/mixed"; public static String MULTIPART_X_MIXED_REPLACE="multipart/x-mixed-replace"; - static - { - try - { - __CRLF="\015\012".getBytes(StringUtil.__ISO_8859_1); - __DASHDASH="--".getBytes(StringUtil.__ISO_8859_1); - } - catch (Exception e) {e.printStackTrace(); System.exit(1);} - } /* ------------------------------------------------------------ */ private String boundary; diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/RolloverFileOutputStream.java b/jetty-util/src/main/java/org/eclipse/jetty/util/RolloverFileOutputStream.java index f937c13ad17..18de6d34e5a 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/RolloverFileOutputStream.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/RolloverFileOutputStream.java @@ -326,6 +326,7 @@ public class RolloverFileOutputStream extends FilterOutputStream } catch(IOException e) { + // Cannot log this exception to a LOG, as RolloverFOS can be used by logging e.printStackTrace(); } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java b/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java index c304427d74f..e87a16fc7ee 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java @@ -44,7 +44,7 @@ public class TypeUtil public static int LF = '\012'; /* ------------------------------------------------------------ */ - private static final HashMap name2Class=new HashMap(); + private static final HashMap> name2Class=new HashMap>(); static { name2Class.put("boolean",java.lang.Boolean.TYPE); @@ -92,7 +92,7 @@ public class TypeUtil } /* ------------------------------------------------------------ */ - private static final HashMap class2Name=new HashMap(); + private static final HashMap, String> class2Name=new HashMap, String>(); static { class2Name.put(java.lang.Boolean.TYPE,"boolean"); @@ -119,12 +119,12 @@ public class TypeUtil } /* ------------------------------------------------------------ */ - private static final HashMap class2Value=new HashMap(); + private static final HashMap, Method> class2Value=new HashMap, Method>(); static { try { - Class[] s ={java.lang.String.class}; + Class[] s ={java.lang.String.class}; class2Value.put(java.lang.Boolean.TYPE, java.lang.Boolean.class.getMethod("valueOf",s)); @@ -158,7 +158,7 @@ public class TypeUtil } catch(Exception e) { - e.printStackTrace(); + throw new Error(e); } } @@ -180,7 +180,7 @@ public class TypeUtil * @param name A class or type name. * @return A class , which may be a primitive TYPE field.. */ - public static Class fromName(String name) + public static Class fromName(String name) { return name2Class.get(name); } @@ -190,7 +190,7 @@ public class TypeUtil * @param type A class , which may be a primitive TYPE field. * @return Canonical name. */ - public static String toName(Class type) + public static String toName(Class type) { return class2Name.get(type); } @@ -201,7 +201,7 @@ public class TypeUtil * @param value The value as a string. * @return The value as an Object. */ - public static Object valueOf(Class type, String value) + public static Object valueOf(Class type, String value) { try { @@ -216,7 +216,7 @@ public class TypeUtil type.equals(java.lang.Character.class)) return new Character(value.charAt(0)); - Constructor c = type.getConstructor(java.lang.String.class); + Constructor c = type.getConstructor(java.lang.String.class); return c.newInstance(value); } catch(NoSuchMethodException e) @@ -431,7 +431,7 @@ public class TypeUtil } - public static void dump(Class c) + public static void dump(Class c) { System.err.println("Dump: "+c); dump(c.getClassLoader()); diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSON.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSON.java index 84824567afa..f01013dd17d 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSON.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSON.java @@ -86,7 +86,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class JSON { - private static final Logger LOG = Log.getLogger(JSON.class); + static final Logger LOG = Log.getLogger(JSON.class); public final static JSON DEFAULT = new JSON(); private Map _convertors = new ConcurrentHashMap(); @@ -950,7 +950,7 @@ public class JSON } catch (ClassNotFoundException e) { - e.printStackTrace(); + LOG.warn(e); } } return map; diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSONObjectConvertor.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSONObjectConvertor.java index 470564c1f31..6adfdd75e7f 100755 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSONObjectConvertor.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSONObjectConvertor.java @@ -97,7 +97,6 @@ public class JSONObjectConvertor implements JSON.Convertor } catch (Throwable e) { - // e.printStackTrace(); throw new IllegalArgumentException(e); } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorFactory.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorFactory.java index d6b51e84022..64020e2f86a 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorFactory.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorFactory.java @@ -66,7 +66,7 @@ public class JSONPojoConvertorFactory implements JSON.Convertor } catch (ClassNotFoundException e) { - e.printStackTrace(); + JSON.LOG.warn(e); } } if (convertor!=null) @@ -92,7 +92,7 @@ public class JSONPojoConvertorFactory implements JSON.Convertor } catch (ClassNotFoundException e) { - e.printStackTrace(); + JSON.LOG.warn(e); } } if (convertor!=null) diff --git a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java index 3945d9c5933..af8aec2b666 100644 --- a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java +++ b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java @@ -1135,7 +1135,7 @@ public class XmlConfiguration final AtomicReference exception = new AtomicReference(); - AccessController.doPrivileged(new PrivilegedAction() + AccessController.doPrivileged(new PrivilegedAction() { public Object run() { @@ -1216,11 +1216,6 @@ public class XmlConfiguration } } } - catch (AccessControlException ace) - { - ace.printStackTrace(System.err); - exception.set(ace); - } catch (Exception e) { LOG.debug(Log.EXCEPTION,e); From 436743e7d5ad268b9a32311af31bcef4928098cc Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Thu, 12 Apr 2012 17:05:55 +1000 Subject: [PATCH 094/100] 367172 Remove detection for slf4j NOPLogger --- .../java/org/eclipse/jetty/util/log/Slf4jLog.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/log/Slf4jLog.java b/jetty-util/src/main/java/org/eclipse/jetty/util/log/Slf4jLog.java index 2dca95127f2..eacb02a795c 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/log/Slf4jLog.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/log/Slf4jLog.java @@ -29,17 +29,7 @@ public class Slf4jLog extends AbstractLogger public Slf4jLog(String name) { - // This checks to make sure that an slf4j implementation is present. - // It is needed because slf4j-api 1.6.x defaults to using NOPLogger. - try - { - Class.forName("org.slf4j.impl.StaticLoggerBinder"); - } - catch (ClassNotFoundException ex) - { - throw new NoClassDefFoundError("org.slf4j.impl.StaticLoggerBinder"); - } - + //NOTE: if only an slf4j-api jar is on the classpath, slf4j will use a NOPLogger org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger( name ); // Fix LocationAwareLogger use to indicate FQCN of this class - From 325c484950e51a858af9944b127688c5fc7acc60 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 12 Apr 2012 17:16:45 +1000 Subject: [PATCH 095/100] fixed merge issues --- .../osgi/boot/internal/webapp/WebBundleTrackerCustomizer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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/WebBundleTrackerCustomizer.java index 47c44c42dd9..137c49bb271 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/WebBundleTrackerCustomizer.java @@ -225,7 +225,7 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer } } - private String getWebContextPath(Bundle bundle, Dictionary dic) + private String getWebContextPath(Bundle bundle, Dictionary dic, boolean webinfWebxmlExists) { String rfc66ContextPath = (String) dic.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH); if (rfc66ContextPath == null) From 6f54239cb5b57baa31062e369d0b5c04c09efec6 Mon Sep 17 00:00:00 2001 From: Thomas Becker Date: Thu, 12 Apr 2012 10:15:48 +0200 Subject: [PATCH 096/100] 376519: deflate compression level and noWrap setting are now configurable for GZipFilter Change-Id: I77a69921fc712bc2aa6d10b92f9b1b035a9c53f4 --- .../eclipse/jetty/servlets/GzipFilter.java | 42 ++++++++++++++++++- .../jetty/servlets/IncludableGzipFilter.java | 2 +- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java index f30ff4189ca..9b81e18812c 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java @@ -63,7 +63,37 @@ import org.eclipse.jetty.util.log.Logger; * This filter extends {@link UserAgentFilter} and if the the initParameter excludedAgents * is set to a comma separated list of user agents, then these agents will be excluded from gzip content. *

    + *

    Init Parameters:

    + *
    + * bufferSize                 The output buffer size. Defaults to 8192. Be careful as values <= 0 will lead to an 
    + *                            {@link IllegalArgumentException}. 
    + *                            @see java.util.zip.GZIPOutputStream#GZIPOutputStream(java.io.OutputStream, int)
    + *                            @see java.util.zip.DeflaterOutputStream#DeflaterOutputStream(java.io.OutputStream, Deflater, int)
    + *                      
    + * minGzipSize                Content will only be compressed if content length is either unknown or greater
    + *                            than minGzipSize.
    + *                      
    + * deflateCompressionLevel    The compression level used for deflate compression. (0-9).
    + *                            @see java.util.zip.Deflater#Deflater(int, boolean)
    + *                            
    + * deflateNoWrap              The noWrap setting for deflate compression. Defaults to true. (true/false)
    + *                            @see java.util.zip.Deflater#Deflater(int, boolean)
      *
    + * mimeTypes                  Comma separated list of mime types to compress. See description above.
    + * 
    + * excludedAgents             Comma separated list of user agents to exclude from compression. Does a 
    + *                            {@link String#contains(CharSequence)} to check if the excluded agent occurs
    + *                            in the user-agent header. If it does -> no compression
    + *                            
    + * excludeAgentPatterns       Same as excludedAgents, but accepts regex patterns for more complex matching.
    + * 
    + * excludePaths               Comma separated list of paths to exclude from compression. 
    + *                            Does a {@link String#startsWith(String)} comparison to check if the path matches.
    + *                            If it does match -> no compression. To match subpaths use excludePathPatterns
    + *                            instead.
    + * 
    + * excludePathPatterns        Same as excludePath, but accepts regex patterns for more complex matching.
    + * 
    */ public class GzipFilter extends UserAgentFilter { @@ -74,6 +104,8 @@ public class GzipFilter extends UserAgentFilter protected Set _mimeTypes; protected int _bufferSize=8192; protected int _minGzipSize=256; + protected int _deflateCompressionLevel=Deflater.DEFAULT_COMPRESSION; + protected boolean _deflateNoWrap = true; protected Set _excludedAgents; protected Set _excludedAgentPatterns; protected Set _excludedPaths; @@ -97,6 +129,14 @@ public class GzipFilter extends UserAgentFilter if (tmp!=null) _minGzipSize=Integer.parseInt(tmp); + tmp=filterConfig.getInitParameter("deflateCompressionLevel"); + if (tmp!=null) + _deflateCompressionLevel=Integer.parseInt(tmp); + + tmp=filterConfig.getInitParameter("deflateNoWrap"); + if (tmp!=null) + _deflateNoWrap=Boolean.parseBoolean(tmp); + tmp=filterConfig.getInitParameter("mimeTypes"); if (tmp!=null) { @@ -256,7 +296,7 @@ public class GzipFilter extends UserAgentFilter @Override protected DeflaterOutputStream createStream() throws IOException { - return new DeflaterOutputStream(_response.getOutputStream(),new Deflater(Deflater.DEFAULT_COMPRESSION)); + return new DeflaterOutputStream(_response.getOutputStream(),new Deflater(_deflateCompressionLevel,_deflateNoWrap)); } }; } 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 95de423bc4b..50ee23ae346 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 @@ -95,7 +95,7 @@ public class IncludableGzipFilter extends GzipFilter @Override protected DeflaterOutputStream createStream() throws IOException { - return new DeflaterOutputStream(_response.getOutputStream(),new Deflater(Deflater.DEFAULT_COMPRESSION)); + return new DeflaterOutputStream(_response.getOutputStream(),new Deflater(_deflateCompressionLevel, _deflateNoWrap)); } }; } From 4089f3af779e70c87191394a6d6e2cf50bcbfd2b Mon Sep 17 00:00:00 2001 From: Thomas Becker Date: Thu, 12 Apr 2012 11:18:15 +0200 Subject: [PATCH 097/100] 376519: adapt GZipFilter tests to follow new default for Deflate Change-Id: Ia87902ae10cc139bc17551e3496de62a0f89957a --- .../jetty/servlets/GzipWithPipeliningTest.java | 12 +++++++++--- .../jetty/servlets/IncludableGzipFilterTest.java | 3 ++- .../org/eclipse/jetty/servlets/gzip/GzipTester.java | 3 ++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipWithPipeliningTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipWithPipeliningTest.java index 4144b0702d1..a77d1a39e58 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipWithPipeliningTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipWithPipeliningTest.java @@ -1,7 +1,12 @@ package org.eclipse.jetty.servlets; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import java.io.File; import java.io.FileInputStream; @@ -16,6 +21,7 @@ import java.util.Collection; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.GZIPInputStream; +import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; import org.eclipse.jetty.server.Connector; @@ -183,7 +189,7 @@ public class GzipWithPipeliningTest InputStream uncompressedStream = null; if (GzipFilter.DEFLATE.equals(encodingHeader)) { - uncompressedStream = new InflaterInputStream(rawInputStream); + uncompressedStream = new InflaterInputStream(rawInputStream, new Inflater(true)); } else { diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java index 9872c198014..61622061c7a 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java @@ -25,6 +25,7 @@ import java.io.InputStream; import java.util.Arrays; import java.util.Collection; import java.util.zip.GZIPInputStream; +import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; import javax.servlet.http.HttpServletResponse; @@ -139,7 +140,7 @@ public class IncludableGzipFilterTest } else if (compressionType.equals(GzipFilter.DEFLATE)) { - testIn = new InflaterInputStream(compressedResponseStream); + testIn = new InflaterInputStream(compressedResponseStream, new Inflater(true)); } ByteArrayOutputStream testOut = new ByteArrayOutputStream(); IO.copy(testIn,testOut); diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java index 36cec8037b9..331975cbbb8 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java @@ -20,6 +20,7 @@ import java.util.Enumeration; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.GZIPInputStream; +import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; import javax.servlet.Servlet; @@ -101,7 +102,7 @@ public class GzipTester } else if (compressionType.equals(GzipFilter.DEFLATE)) { - in = new InflaterInputStream(bais); + in = new InflaterInputStream(bais, new Inflater(true)); } out = new ByteArrayOutputStream(); IO.copy(in,out); From f9a75984f05d8cce6e15b452b322eaa96729c03c Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 12 Apr 2012 20:24:50 +1000 Subject: [PATCH 098/100] 374504: updated cookies for rfc6265 --- .../org/eclipse/jetty/http/HttpFields.java | 55 +++++-------------- .../eclipse/jetty/http/HttpFieldsTest.java | 24 ++------ .../jetty/server/AbstractHttpConnection.java | 4 +- .../org/eclipse/jetty/server/Response.java | 2 +- .../java/org/eclipse/jetty/server/Server.java | 12 ++-- .../eclipse/jetty/server/ResponseTest.java | 2 +- 6 files changed, 27 insertions(+), 72 deletions(-) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java index ed2989b7ff5..aed0c3945d3 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java @@ -293,7 +293,6 @@ public class HttpFields /* -------------------------------------------------------------- */ private final ArrayList _fields = new ArrayList(20); private final HashMap _names = new HashMap(32); - private final int _maxCookieVersion; /* ------------------------------------------------------------ */ /** @@ -301,19 +300,8 @@ public class HttpFields */ public HttpFields() { - _maxCookieVersion=1; } - /* ------------------------------------------------------------ */ - /** - * Constructor. - */ - public HttpFields(int maxCookieVersion) - { - _maxCookieVersion=maxCookieVersion; - } - - // TODO externalize this cache so it can be configurable private static ConcurrentMap __cache = new ConcurrentHashMap(); private static int __cacheSize = Integer.getInteger("org.eclipse.jetty.http.HttpFields.CACHE",2000); @@ -929,7 +917,7 @@ public class HttpFields final boolean isHttpOnly, int version) { - String delim=_maxCookieVersion==0?"":__COOKIE_DELIM; + String delim=__COOKIE_DELIM; // Check arguments if (name == null || name.length() == 0) @@ -938,29 +926,18 @@ public class HttpFields // Format value and params StringBuilder buf = new StringBuilder(128); String name_value_params; - boolean quoted = QuotedStringTokenizer.quoteIfNeeded(buf, name, delim); + QuotedStringTokenizer.quoteIfNeeded(buf, name, delim); buf.append('='); String start=buf.toString(); if (value != null && value.length() > 0) - quoted|=QuotedStringTokenizer.quoteIfNeeded(buf, value, delim); - - // upgrade to version 1 cookies if quoted. - if (quoted&&version==0 && _maxCookieVersion>=1) - version=1; + QuotedStringTokenizer.quoteIfNeeded(buf, value, delim); - if (version>_maxCookieVersion) - version=_maxCookieVersion; - - if (version > 0) + if (comment != null && comment.length() > 0) { - buf.append(";Version="); - buf.append(version); - if (comment != null && comment.length() > 0) - { - buf.append(";Comment="); - QuotedStringTokenizer.quoteIfNeeded(buf, comment, delim); - } + buf.append(";Comment="); + QuotedStringTokenizer.quoteIfNeeded(buf, comment, delim); } + if (path != null && path.length() > 0) { buf.append(";Path="); @@ -977,23 +954,19 @@ public class HttpFields if (maxAge >= 0) { - // Always add the expires param as some browsers still don't handle max-age - buf.append(";Expires="); - if (maxAge == 0) - buf.append(__01Jan1970_COOKIE); - else - formatCookieDate(buf, System.currentTimeMillis() + 1000L * maxAge); - + // Always add the expires param as some browsers still don't handle max-age + buf.append(";Expires="); + if (maxAge == 0) + buf.append(__01Jan1970_COOKIE); + else + formatCookieDate(buf, System.currentTimeMillis() + 1000L * maxAge); + if (version >0) { buf.append(";Max-Age="); buf.append(maxAge); } } - else if (version > 0) - { - buf.append(";Discard"); - } if (isSecure) buf.append(";Secure"); diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java index 3ae9a409fd0..4d36e9aa3b7 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java @@ -361,28 +361,18 @@ public class HttpFieldsTest fields.clear(); fields.addSetCookie("everything","wrong","wrong","wrong",0,"to be replaced",true,true,0); fields.addSetCookie("everything","value","domain","path",0,"comment",true,true,0); - assertEquals("everything=value;Path=path;Domain=domain;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",fields.getStringField("Set-Cookie")); + assertEquals("everything=value;Comment=comment;Path=path;Domain=domain;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",fields.getStringField("Set-Cookie")); Enumeration e =fields.getValues("Set-Cookie"); assertTrue(e.hasMoreElements()); - assertEquals("everything=value;Path=path;Domain=domain;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",e.nextElement()); + assertEquals("everything=value;Comment=comment;Path=path;Domain=domain;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",e.nextElement()); assertFalse(e.hasMoreElements()); - assertEquals("Thu, 01 Jan 1970 00:00:00 GMT",fields.getStringField("Expires")); - + assertEquals("Thu, 01 Jan 1970 00:00:00 GMT",fields.getStringField("Expires")); fields.clear(); fields.addSetCookie("ev erything","va lue","do main","pa th",1,"co mment",true,true,2); String setCookie=fields.getStringField("Set-Cookie"); - assertTrue(setCookie.startsWith("\"ev erything\"=\"va lue\";Version=1;Comment=\"co mment\";Path=\"pa th\";Domain=\"do main\";Expires=")); + assertTrue(setCookie.startsWith("\"ev erything\"=\"va lue\";Comment=\"co mment\";Path=\"pa th\";Domain=\"do main\";Expires=")); assertTrue(setCookie.endsWith("GMT;Max-Age=1;Secure;HttpOnly")); - - fields.clear(); - fields.addSetCookie("name","value",null,null,-1,null,false,false,0); - setCookie=fields.getStringField("Set-Cookie"); - assertEquals(-1,setCookie.indexOf("Version=")); - fields.clear(); - fields.addSetCookie("name","v a l u e",null,null,-1,null,false,false,0); - setCookie=fields.getStringField("Set-Cookie"); - assertEquals(17,setCookie.indexOf("Version=1")); fields.clear(); fields.addSetCookie("json","{\"services\":[\"cwa\", \"aa\"]}",null,null,-1,null,false,false,-1); @@ -401,12 +391,6 @@ public class HttpFieldsTest e=fields.getValues("Set-Cookie"); assertEquals("name=more;Domain=domain",e.nextElement()); assertEquals("foo=bob;Domain=domain",e.nextElement()); - - fields=new HttpFields(0); - fields.addSetCookie("name","value==",null,null,-1,null,false,false,0); - setCookie=fields.getStringField("Set-Cookie"); - assertEquals("name=value==",setCookie); - } private Set enum2set(Enumeration e) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java index a30c70f78cc..2a5ba0d8f0f 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java @@ -146,7 +146,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection HttpBuffers ab = (HttpBuffers)_connector; _parser = newHttpParser(ab.getRequestBuffers(), endpoint, new RequestHandler()); _requestFields = new HttpFields(); - _responseFields = new HttpFields(server.getMaxCookieVersion()); + _responseFields = new HttpFields(); _request = new Request(this); _response = new Response(this); _generator = newHttpGenerator(ab.getResponseBuffers(), endpoint); @@ -164,7 +164,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection _connector = connector; _parser = parser; _requestFields = new HttpFields(); - _responseFields = new HttpFields(server.getMaxCookieVersion()); + _responseFields = new HttpFields(); _request = request; _response = new Response(this); _generator = generator; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java index 9189dbb8e9b..e362aaaafde 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java @@ -136,7 +136,7 @@ public class Response implements HttpServletResponse if (i>=0) { http_only=true; - comment=comment.substring(i,i+HTTP_ONLY_COMMENT.length()).trim(); + comment=comment.replace(HTTP_ONLY_COMMENT,"").trim(); if (comment.length()==0) comment=null; } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java index 9a01f509562..32850f47a5d 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java @@ -72,7 +72,6 @@ public class Server extends HandlerWrapper implements Attributes private boolean _sendDateHeader = false; //send Date: header private int _graceful=0; private boolean _stopAtShutdown; - private int _maxCookieVersion=1; private boolean _dumpAfterStart=false; private boolean _dumpBeforeStop=false; private boolean _uncheckedPrintWriter=false; @@ -450,21 +449,20 @@ public class Server extends HandlerWrapper implements Attributes } /* ------------------------------------------------------------ */ - /** Get the maximum cookie version. - * @return the maximum set-cookie version sent by this server + /** */ + @Deprecated public int getMaxCookieVersion() { - return _maxCookieVersion; + return 1; } /* ------------------------------------------------------------ */ - /** Set the maximum cookie version. - * @param maxCookieVersion the maximum set-cookie version sent by this server + /** */ + @Deprecated public void setMaxCookieVersion(int maxCookieVersion) { - _maxCookieVersion = maxCookieVersion; } /* ------------------------------------------------------------ */ diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java index b936a5f6513..a3af0709931 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java @@ -516,7 +516,7 @@ public class ResponseTest String set = response.getHttpFields().getStringField("Set-Cookie"); - assertEquals("name=value;Path=/path;Domain=domain;Secure;HttpOnly",set); + assertEquals("name=value;Comment=comment;Path=/path;Domain=domain;Secure;HttpOnly",set); } private Response newResponse() From a389d08c26d7fc139130198abe29739dd54c9f3b Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Thu, 12 Apr 2012 12:57:04 +0200 Subject: [PATCH 099/100] 376201 - HalfClosed state not handled properly. Addendum to restore previous behavior, where a closed stream was also half closed. --- .../src/main/java/org/eclipse/jetty/spdy/StandardStream.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java index 8b1ae148ded..1de9e1b121d 100644 --- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java +++ b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java @@ -94,7 +94,9 @@ public class StandardStream implements IStream public boolean isHalfClosed() { CloseState closeState = this.closeState; - return closeState == CloseState.LOCALLY_CLOSED || closeState == CloseState.REMOTELY_CLOSED; + return closeState == CloseState.LOCALLY_CLOSED || + closeState == CloseState.REMOTELY_CLOSED || + closeState == CloseState.CLOSED; } @Override From 1449a97a94d09b9f8b9b1b6a93c6e149af6a35d1 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Thu, 12 Apr 2012 09:55:52 -0500 Subject: [PATCH 100/100] add releaseBackup to ignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 12ab1b6945c..815d2963057 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,4 @@ target/ #maven *.versionsBackup +*.releaseBackup