From bdbd92dbc9c574dbd1d30bc8c4c5ef8e73de5eb5 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Tue, 21 May 2013 13:10:07 -0500 Subject: [PATCH 01/32] [Bug 408600] set correct jetty.url in all pom files --- example-jetty-embedded/pom.xml | 1 + jetty-aggregate/jetty-all-server/pom.xml | 1 + jetty-aggregate/jetty-all/pom.xml | 1 + 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 | 1 + jetty-ajp/pom.xml | 1 + jetty-annotations/pom.xml | 1 + jetty-client/pom.xml | 4 +--- jetty-continuation/pom.xml | 1 + jetty-deploy/pom.xml | 1 + jetty-distribution/pom.xml | 1 + jetty-http-spi/pom.xml | 1 + jetty-http/pom.xml | 1 + jetty-io/pom.xml | 1 + jetty-jaspi/pom.xml | 1 + jetty-jmx/pom.xml | 1 + jetty-jndi/pom.xml | 1 + jetty-jsp/pom.xml | 1 + jetty-monitor/pom.xml | 1 + jetty-nested/pom.xml | 1 + jetty-nosql/pom.xml | 1 + jetty-osgi/jetty-osgi-boot-jsp/pom.xml | 1 + jetty-osgi/jetty-osgi-boot-logback/pom.xml | 1 + jetty-osgi/jetty-osgi-boot-warurl/pom.xml | 1 + jetty-osgi/jetty-osgi-boot/pom.xml | 1 + jetty-osgi/jetty-osgi-equinoxtools/pom.xml | 1 + jetty-osgi/jetty-osgi-httpservice/pom.xml | 1 + jetty-osgi/jetty-osgi-servletbridge/pom.xml | 1 + jetty-osgi/pom.xml | 1 + jetty-osgi/test-jetty-osgi-context/pom.xml | 1 + jetty-osgi/test-jetty-osgi-webapp/pom.xml | 1 + jetty-osgi/test-jetty-osgi/pom.xml | 1 + jetty-overlay-deployer/pom.xml | 1 + jetty-plus/pom.xml | 1 + jetty-policy/pom.xml | 1 + jetty-rewrite/pom.xml | 1 + jetty-security/pom.xml | 1 + jetty-server/pom.xml | 1 + jetty-servlet/pom.xml | 1 + jetty-servlets/pom.xml | 1 + 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 | 1 + jetty-util/pom.xml | 1 + jetty-webapp/pom.xml | 1 + jetty-websocket/pom.xml | 2 +- jetty-xml/pom.xml | 1 + pom.xml | 4 ++-- test-continuation-jetty6/pom.xml | 1 + test-continuation/pom.xml | 1 + test-jetty-nested/pom.xml | 1 + test-jetty-servlet/pom.xml | 1 + test-jetty-webapp/pom.xml | 1 + tests/pom.xml | 1 + tests/test-integration/pom.xml | 1 + tests/test-loginservice/pom.xml | 1 + tests/test-sessions/pom.xml | 1 + tests/test-sessions/test-hash-sessions/pom.xml | 1 + tests/test-sessions/test-jdbc-sessions/pom.xml | 1 + tests/test-sessions/test-mongodb-sessions/pom.xml | 1 + tests/test-sessions/test-sessions-common/pom.xml | 1 + tests/test-webapps/pom.xml | 1 + tests/test-webapps/test-webapp-rfc2616/pom.xml | 1 + 71 files changed, 72 insertions(+), 17 deletions(-) diff --git a/example-jetty-embedded/pom.xml b/example-jetty-embedded/pom.xml index 30e0f5f8b16..93f75e38a91 100644 --- a/example-jetty-embedded/pom.xml +++ b/example-jetty-embedded/pom.xml @@ -8,6 +8,7 @@ example-jetty-embedded Example :: Jetty Embedded Jetty Embedded Examples + http://www.eclipse.org/jetty org.eclipse.jetty diff --git a/jetty-aggregate/jetty-all-server/pom.xml b/jetty-aggregate/jetty-all-server/pom.xml index 6abf6b28d97..9c23cae0f24 100644 --- a/jetty-aggregate/jetty-all-server/pom.xml +++ b/jetty-aggregate/jetty-all-server/pom.xml @@ -8,6 +8,7 @@ 4.0.0 jetty-all-server Jetty :: Aggregate :: All Server + http://www.eclipse.org/jetty ${project.groupId}.${project.artifactId} diff --git a/jetty-aggregate/jetty-all/pom.xml b/jetty-aggregate/jetty-all/pom.xml index f34db4d7a0e..302483835c4 100644 --- a/jetty-aggregate/jetty-all/pom.xml +++ b/jetty-aggregate/jetty-all/pom.xml @@ -8,6 +8,7 @@ 4.0.0 jetty-all Jetty :: Aggregate :: All core Jetty + http://www.eclipse.org/jetty ${project.build.directory}/sources diff --git a/jetty-aggregate/jetty-client/pom.xml b/jetty-aggregate/jetty-client/pom.xml index 5cf229adc51..1fc0ab74262 100644 --- a/jetty-aggregate/jetty-client/pom.xml +++ b/jetty-aggregate/jetty-client/pom.xml @@ -7,7 +7,7 @@ 4.0.0 jetty-client Jetty :: Aggregate :: HTTP Client - + http://www.eclipse.org/jetty ${project.build.directory}/sources diff --git a/jetty-aggregate/jetty-plus/pom.xml b/jetty-aggregate/jetty-plus/pom.xml index 6d89b328f81..6eedc50ef5b 100644 --- a/jetty-aggregate/jetty-plus/pom.xml +++ b/jetty-aggregate/jetty-plus/pom.xml @@ -7,7 +7,7 @@ 4.0.0 jetty-plus Jetty :: Aggregate :: Plus Server - + http://www.eclipse.org/jetty ${project.build.directory}/sources diff --git a/jetty-aggregate/jetty-server/pom.xml b/jetty-aggregate/jetty-server/pom.xml index 0f0a765d1de..7c658ed4b84 100644 --- a/jetty-aggregate/jetty-server/pom.xml +++ b/jetty-aggregate/jetty-server/pom.xml @@ -7,7 +7,7 @@ 4.0.0 jetty-server Jetty :: Aggregate :: HTTP Server - + http://www.eclipse.org/jetty ${project.build.directory}/sources diff --git a/jetty-aggregate/jetty-servlet/pom.xml b/jetty-aggregate/jetty-servlet/pom.xml index 43d91cb4962..ad4d4b13b3e 100644 --- a/jetty-aggregate/jetty-servlet/pom.xml +++ b/jetty-aggregate/jetty-servlet/pom.xml @@ -7,7 +7,7 @@ 4.0.0 jetty-servlet Jetty :: Aggregate :: Servlet Server - + http://www.eclipse.org/jetty ${project.build.directory}/sources diff --git a/jetty-aggregate/jetty-webapp/pom.xml b/jetty-aggregate/jetty-webapp/pom.xml index ef6b015d657..3eb1748eda1 100644 --- a/jetty-aggregate/jetty-webapp/pom.xml +++ b/jetty-aggregate/jetty-webapp/pom.xml @@ -7,7 +7,7 @@ 4.0.0 jetty-webapp Jetty :: Aggregate :: WebApp Server - + http://www.eclipse.org/jetty ${project.build.directory}/sources diff --git a/jetty-aggregate/jetty-websocket/pom.xml b/jetty-aggregate/jetty-websocket/pom.xml index 1deb7450085..c45885c2cb7 100644 --- a/jetty-aggregate/jetty-websocket/pom.xml +++ b/jetty-aggregate/jetty-websocket/pom.xml @@ -7,7 +7,7 @@ 4.0.0 jetty-websocket Jetty :: Aggregate :: Websocket - + http://www.eclipse.org/jetty ${project.build.directory}/sources diff --git a/jetty-aggregate/pom.xml b/jetty-aggregate/pom.xml index 19e3bdd3605..b23767e4b58 100644 --- a/jetty-aggregate/pom.xml +++ b/jetty-aggregate/pom.xml @@ -9,6 +9,7 @@ org.eclipse.jetty.aggregate jetty-aggregate-project Jetty :: Aggregate Project + http://www.eclipse.org/jetty pom diff --git a/jetty-ajp/pom.xml b/jetty-ajp/pom.xml index c705665e924..e56816d1981 100644 --- a/jetty-ajp/pom.xml +++ b/jetty-ajp/pom.xml @@ -7,6 +7,7 @@ 4.0.0 jetty-ajp Jetty :: AJP + http://www.eclipse.org/jetty ${project.groupId}.ajp diff --git a/jetty-annotations/pom.xml b/jetty-annotations/pom.xml index 88c211b992c..75decf36e45 100644 --- a/jetty-annotations/pom.xml +++ b/jetty-annotations/pom.xml @@ -8,6 +8,7 @@ jetty-annotations Jetty :: Servlet Annotations Annotation support for deploying servlets in jetty. + http://www.eclipse.org/jetty ${project.groupId}.annotations diff --git a/jetty-client/pom.xml b/jetty-client/pom.xml index 4606738348b..506bb889098 100644 --- a/jetty-client/pom.xml +++ b/jetty-client/pom.xml @@ -8,13 +8,11 @@ 4.0.0 jetty-client Jetty :: Asynchronous HTTP Client - {$jetty.url} - + http://www.eclipse.org/jetty ${project.groupId}.client target/test-policy - diff --git a/jetty-continuation/pom.xml b/jetty-continuation/pom.xml index e14b8a9579e..f7aaf2581bd 100644 --- a/jetty-continuation/pom.xml +++ b/jetty-continuation/pom.xml @@ -8,6 +8,7 @@ jetty-continuation Jetty :: Continuation Asynchronous API + http://www.eclipse.org/jetty ${project.groupId}.continuation diff --git a/jetty-deploy/pom.xml b/jetty-deploy/pom.xml index e213b349448..c3c136a1121 100644 --- a/jetty-deploy/pom.xml +++ b/jetty-deploy/pom.xml @@ -8,6 +8,7 @@ jetty-deploy Jetty :: Deployers Jetty deployers + http://www.eclipse.org/jetty ${project.groupId}.deploy diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml index c7b9c4898e2..b0157c48e1d 100644 --- a/jetty-distribution/pom.xml +++ b/jetty-distribution/pom.xml @@ -7,6 +7,7 @@ jetty-distribution Jetty :: Distribution Assemblies + http://www.eclipse.org/jetty pom target/distribution diff --git a/jetty-http-spi/pom.xml b/jetty-http-spi/pom.xml index cdbc8ec35b1..1ffbc9992f1 100644 --- a/jetty-http-spi/pom.xml +++ b/jetty-http-spi/pom.xml @@ -7,6 +7,7 @@ 4.0.0 jetty-http-spi Jetty :: Http Service Provider Interface + http://www.eclipse.org/jetty ${project.groupId}.http.spi diff --git a/jetty-http/pom.xml b/jetty-http/pom.xml index 006c9686f16..8c8777bdac7 100644 --- a/jetty-http/pom.xml +++ b/jetty-http/pom.xml @@ -8,6 +8,7 @@ 4.0.0 jetty-http Jetty :: Http Utility + http://www.eclipse.org/jetty ${project.groupId}.http diff --git a/jetty-io/pom.xml b/jetty-io/pom.xml index 73a2cd33e74..5fdb30e795f 100644 --- a/jetty-io/pom.xml +++ b/jetty-io/pom.xml @@ -7,6 +7,7 @@ 4.0.0 jetty-io Jetty :: IO Utility + http://www.eclipse.org/jetty ${project.groupId}.io diff --git a/jetty-jaspi/pom.xml b/jetty-jaspi/pom.xml index 5a390594e9c..3206b4ac550 100644 --- a/jetty-jaspi/pom.xml +++ b/jetty-jaspi/pom.xml @@ -8,6 +8,7 @@ jetty-jaspi Jetty :: JASPI Security Jetty security infrastructure + http://www.eclipse.org/jetty ${project.groupId}.jaspi diff --git a/jetty-jmx/pom.xml b/jetty-jmx/pom.xml index 254bdebc693..91c3439edf8 100644 --- a/jetty-jmx/pom.xml +++ b/jetty-jmx/pom.xml @@ -8,6 +8,7 @@ jetty-jmx Jetty :: JMX Management JMX management artifact for jetty. + http://www.eclipse.org/jetty ${project.groupId}.jmx diff --git a/jetty-jndi/pom.xml b/jetty-jndi/pom.xml index f90ac421d5d..27d7eb27199 100644 --- a/jetty-jndi/pom.xml +++ b/jetty-jndi/pom.xml @@ -8,6 +8,7 @@ jetty-jndi Jetty :: JNDI Naming JNDI spi impl for java namespace. + http://www.eclipse.org/jetty ${project.groupId}.jndi diff --git a/jetty-jsp/pom.xml b/jetty-jsp/pom.xml index 0a7b0189687..d1e3d0445f3 100644 --- a/jetty-jsp/pom.xml +++ b/jetty-jsp/pom.xml @@ -7,6 +7,7 @@ 4.0.0 jetty-jsp Jetty :: JSP dependencies + http://www.eclipse.org/jetty jar diff --git a/jetty-monitor/pom.xml b/jetty-monitor/pom.xml index 7e5c98dd7be..a68de9649a0 100644 --- a/jetty-monitor/pom.xml +++ b/jetty-monitor/pom.xml @@ -24,6 +24,7 @@ 4.0.0 jetty-monitor Jetty :: Monitoring + http://www.eclipse.org/jetty Performance monitoring artifact for jetty. ${project.groupId}.monitor diff --git a/jetty-nested/pom.xml b/jetty-nested/pom.xml index 94adfd075aa..d202472ccf1 100644 --- a/jetty-nested/pom.xml +++ b/jetty-nested/pom.xml @@ -10,6 +10,7 @@ Jetty :: Nested jar Local Servlet Connector for jetty. + http://www.eclipse.org/jetty ${project.groupId}.nested diff --git a/jetty-nosql/pom.xml b/jetty-nosql/pom.xml index d505046c94d..e7f1e1de956 100644 --- a/jetty-nosql/pom.xml +++ b/jetty-nosql/pom.xml @@ -7,6 +7,7 @@ 4.0.0 jetty-nosql Jetty :: NoSQL Session Managers + http://www.eclipse.org/jetty ${project.groupId}.nosql diff --git a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml index c8dbaca95e0..c12f777b32d 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml @@ -9,6 +9,7 @@ jetty-osgi-boot-jsp Jetty :: OSGi :: Boot JSP Jetty OSGi Boot JSP bundle + http://www.eclipse.org/jetty ${project.groupId}.boot.jsp diff --git a/jetty-osgi/jetty-osgi-boot-logback/pom.xml b/jetty-osgi/jetty-osgi-boot-logback/pom.xml index 1b2368e408e..f1985b7e05a 100644 --- a/jetty-osgi/jetty-osgi-boot-logback/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-logback/pom.xml @@ -9,6 +9,7 @@ jetty-osgi-boot-logback Jetty :: OSGi :: Boot Logback Jetty OSGi Boot Logback bundle + http://www.eclipse.org/jetty ${project.groupId}.boot.logback diff --git a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml index 582ded07b41..af0c6205454 100644 --- a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml @@ -9,6 +9,7 @@ jetty-osgi-boot-warurl Jetty :: OSGi :: Boot :: Warurl Jetty OSGi Boot-Warurl bundle + http://www.eclipse.org/jetty ${project.groupId}.boot.warurl diff --git a/jetty-osgi/jetty-osgi-boot/pom.xml b/jetty-osgi/jetty-osgi-boot/pom.xml index 697f54931dc..4e6ccf50eca 100644 --- a/jetty-osgi/jetty-osgi-boot/pom.xml +++ b/jetty-osgi/jetty-osgi-boot/pom.xml @@ -9,6 +9,7 @@ jetty-osgi-boot Jetty :: OSGi :: Boot Jetty OSGi Boot bundle + http://www.eclipse.org/jetty ${project.groupId}.boot diff --git a/jetty-osgi/jetty-osgi-equinoxtools/pom.xml b/jetty-osgi/jetty-osgi-equinoxtools/pom.xml index a0d3f07ca4e..1db3f81076a 100644 --- a/jetty-osgi/jetty-osgi-equinoxtools/pom.xml +++ b/jetty-osgi/jetty-osgi-equinoxtools/pom.xml @@ -9,6 +9,7 @@ jetty-osgi-equinoxtools Jetty :: OSGi :: Example Equinox Tools Jetty OSGi Example Equinox Tools + http://www.eclipse.org/jetty ${project.groupId}.equinoxtools diff --git a/jetty-osgi/jetty-osgi-httpservice/pom.xml b/jetty-osgi/jetty-osgi-httpservice/pom.xml index 44190f03d81..6fb469e8ee6 100644 --- a/jetty-osgi/jetty-osgi-httpservice/pom.xml +++ b/jetty-osgi/jetty-osgi-httpservice/pom.xml @@ -9,6 +9,7 @@ jetty-httpservice Jetty :: OSGi :: HttpService Jetty OSGi HttpService bundle + http://www.eclipse.org/jetty ${project.groupId}.httpservice diff --git a/jetty-osgi/jetty-osgi-servletbridge/pom.xml b/jetty-osgi/jetty-osgi-servletbridge/pom.xml index db10d11a577..4da36c2e85f 100644 --- a/jetty-osgi/jetty-osgi-servletbridge/pom.xml +++ b/jetty-osgi/jetty-osgi-servletbridge/pom.xml @@ -10,6 +10,7 @@ jetty-osgi-servletbridge Jetty :: OSGi :: Servletbridge Jetty OSGi Servletbridge webapp + http://www.eclipse.org/jetty war false diff --git a/jetty-osgi/pom.xml b/jetty-osgi/pom.xml index d1013a96893..84dfb5018f9 100644 --- a/jetty-osgi/pom.xml +++ b/jetty-osgi/pom.xml @@ -9,6 +9,7 @@ org.eclipse.jetty.osgi jetty-osgi-project Jetty :: OSGi + http://www.eclipse.org/jetty pom 3.6.0.v20100517 diff --git a/jetty-osgi/test-jetty-osgi-context/pom.xml b/jetty-osgi/test-jetty-osgi-context/pom.xml index 3f5f7edc547..3b218e7f10a 100644 --- a/jetty-osgi/test-jetty-osgi-context/pom.xml +++ b/jetty-osgi/test-jetty-osgi-context/pom.xml @@ -9,6 +9,7 @@ test-jetty-osgi-context Jetty :: OSGi :: Context Test Jetty OSGi bundle with a ContextHandler + http://www.eclipse.org/jetty ${project.groupId}.testcontext diff --git a/jetty-osgi/test-jetty-osgi-webapp/pom.xml b/jetty-osgi/test-jetty-osgi-webapp/pom.xml index d5ecfc52da3..c242e831830 100644 --- a/jetty-osgi/test-jetty-osgi-webapp/pom.xml +++ b/jetty-osgi/test-jetty-osgi-webapp/pom.xml @@ -9,6 +9,7 @@ test-jetty-osgi-webapp Jetty :: OSGi :: WebApp Test Jetty OSGi Webapp bundle + http://www.eclipse.org/jetty ${project.groupId}.webapp diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index 1b4c95c3614..571f8d41f56 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -9,6 +9,7 @@ test-jetty-osgi Jetty :: OSGi :: Test Jetty OSGi Integration test + http://www.eclipse.org/jetty ${project.groupId}.boot.test target/distribution diff --git a/jetty-overlay-deployer/pom.xml b/jetty-overlay-deployer/pom.xml index c1299f03851..953446f1fd0 100644 --- a/jetty-overlay-deployer/pom.xml +++ b/jetty-overlay-deployer/pom.xml @@ -8,6 +8,7 @@ jetty-overlay-deployer Jetty :: Overlay Deployer Overlayed deployer + http://www.eclipse.org/jetty diff --git a/jetty-plus/pom.xml b/jetty-plus/pom.xml index 3c113cd963d..e6fe9982772 100644 --- a/jetty-plus/pom.xml +++ b/jetty-plus/pom.xml @@ -8,6 +8,7 @@ jetty-plus Jetty :: Plus Jetty JavaEE style services + http://www.eclipse.org/jetty ${project.groupId}.plus diff --git a/jetty-policy/pom.xml b/jetty-policy/pom.xml index c4175046518..e9fc1e8bd98 100644 --- a/jetty-policy/pom.xml +++ b/jetty-policy/pom.xml @@ -8,6 +8,7 @@ jetty-policy Jetty :: Policy Tool jar + http://www.eclipse.org/jetty target/test-policy ${project.groupId}.policy diff --git a/jetty-rewrite/pom.xml b/jetty-rewrite/pom.xml index 1dd812fb0ce..7f7cd66d9d5 100644 --- a/jetty-rewrite/pom.xml +++ b/jetty-rewrite/pom.xml @@ -8,6 +8,7 @@ jetty-rewrite Jetty :: Rewrite Handler Jetty Rewrite Handler + http://www.eclipse.org/jetty ${project.groupId}.rewrite diff --git a/jetty-security/pom.xml b/jetty-security/pom.xml index 6cc9e14c546..71141432be7 100644 --- a/jetty-security/pom.xml +++ b/jetty-security/pom.xml @@ -8,6 +8,7 @@ jetty-security Jetty :: Security Jetty security infrastructure + http://www.eclipse.org/jetty ${project.groupId}.security diff --git a/jetty-server/pom.xml b/jetty-server/pom.xml index 2c9910469db..dc94ea0306e 100644 --- a/jetty-server/pom.xml +++ b/jetty-server/pom.xml @@ -8,6 +8,7 @@ jetty-server Jetty :: Server Core The core jetty server artifact. + http://www.eclipse.org/jetty ${project.groupId}.server diff --git a/jetty-servlet/pom.xml b/jetty-servlet/pom.xml index ee7be7dbce8..0edc06b31eb 100644 --- a/jetty-servlet/pom.xml +++ b/jetty-servlet/pom.xml @@ -9,6 +9,7 @@ jetty-servlet Jetty :: Servlet Handling Jetty Servlet Container + http://www.eclipse.org/jetty ${project.groupId}.servlet diff --git a/jetty-servlets/pom.xml b/jetty-servlets/pom.xml index 69b046189a1..34146df63a0 100644 --- a/jetty-servlets/pom.xml +++ b/jetty-servlets/pom.xml @@ -9,6 +9,7 @@ jetty-servlets Jetty :: Utility Servlets and Filters Utility Servlets from Jetty + http://www.eclipse.org/jetty ${project.groupId}.servlets diff --git a/jetty-spdy/pom.xml b/jetty-spdy/pom.xml index ed898b0ba34..2564a1547aa 100644 --- a/jetty-spdy/pom.xml +++ b/jetty-spdy/pom.xml @@ -11,7 +11,7 @@ spdy-parent pom Jetty :: SPDY :: Parent - + http://www.eclipse.org/jetty 1.1.5.v20130313 1.1.0.v20120525 diff --git a/jetty-spdy/spdy-core/pom.xml b/jetty-spdy/spdy-core/pom.xml index 2d5ceb5de1c..46c0768d8af 100644 --- a/jetty-spdy/spdy-core/pom.xml +++ b/jetty-spdy/spdy-core/pom.xml @@ -9,7 +9,7 @@ 4.0.0 spdy-core Jetty :: SPDY :: Core - + http://www.eclipse.org/jetty org.eclipse.jetty diff --git a/jetty-spdy/spdy-jetty-http-webapp/pom.xml b/jetty-spdy/spdy-jetty-http-webapp/pom.xml index faea44fd0e6..ede38aae3b4 100644 --- a/jetty-spdy/spdy-jetty-http-webapp/pom.xml +++ b/jetty-spdy/spdy-jetty-http-webapp/pom.xml @@ -9,7 +9,7 @@ spdy-jetty-http-webapp war Jetty :: SPDY :: Jetty HTTP Web Application - + http://www.eclipse.org/jetty diff --git a/jetty-spdy/spdy-jetty-http/pom.xml b/jetty-spdy/spdy-jetty-http/pom.xml index 391bac2ffad..cb91b0e15b6 100644 --- a/jetty-spdy/spdy-jetty-http/pom.xml +++ b/jetty-spdy/spdy-jetty-http/pom.xml @@ -8,7 +8,7 @@ 4.0.0 spdy-jetty-http Jetty :: SPDY :: Jetty HTTP Layer - + http://www.eclipse.org/jetty diff --git a/jetty-spdy/spdy-jetty/pom.xml b/jetty-spdy/spdy-jetty/pom.xml index 20000cbab45..86db5621962 100644 --- a/jetty-spdy/spdy-jetty/pom.xml +++ b/jetty-spdy/spdy-jetty/pom.xml @@ -8,7 +8,7 @@ 4.0.0 spdy-jetty Jetty :: SPDY :: Jetty Binding - + http://www.eclipse.org/jetty diff --git a/jetty-start/pom.xml b/jetty-start/pom.xml index 10714c4e928..ec379fb2ad9 100644 --- a/jetty-start/pom.xml +++ b/jetty-start/pom.xml @@ -8,6 +8,7 @@ jetty-start Jetty :: Start The start utility + http://www.eclipse.org/jetty diff --git a/jetty-util/pom.xml b/jetty-util/pom.xml index 696dd471af4..5de56521027 100644 --- a/jetty-util/pom.xml +++ b/jetty-util/pom.xml @@ -8,6 +8,7 @@ jetty-util Jetty :: Utilities Utility classes for Jetty + http://www.eclipse.org/jetty ${project.groupId}.util diff --git a/jetty-webapp/pom.xml b/jetty-webapp/pom.xml index 53a5e470b8b..acdbbae04bd 100644 --- a/jetty-webapp/pom.xml +++ b/jetty-webapp/pom.xml @@ -8,6 +8,7 @@ jetty-webapp Jetty :: Webapp Application Support Jetty web application support + http://www.eclipse.org/jetty ${project.groupId}.webapp diff --git a/jetty-websocket/pom.xml b/jetty-websocket/pom.xml index 5b7b821c504..af02cf71db1 100644 --- a/jetty-websocket/pom.xml +++ b/jetty-websocket/pom.xml @@ -9,7 +9,7 @@ 4.0.0 jetty-websocket Jetty :: Websocket - + http://www.eclipse.org/jetty ${project.groupId}.websocket diff --git a/jetty-xml/pom.xml b/jetty-xml/pom.xml index ff838081d99..1ebb78f5f42 100644 --- a/jetty-xml/pom.xml +++ b/jetty-xml/pom.xml @@ -8,6 +8,7 @@ jetty-xml Jetty :: XML utilities The jetty xml utilities. + http://www.eclipse.org/jetty ${project.groupId}.xml diff --git a/pom.xml b/pom.xml index 56acfd39a1f..e742156b1da 100644 --- a/pom.xml +++ b/pom.xml @@ -8,11 +8,11 @@ jetty-project 7.6.11-SNAPSHOT Jetty :: Project - ${jetty.url} + http://www.eclipse.org/jetty pom - UTF-8 http://www.eclipse.org/jetty + UTF-8 2.5.0.v201103041518 1.1 1.6.1 diff --git a/test-continuation-jetty6/pom.xml b/test-continuation-jetty6/pom.xml index 02fa6e29176..9f7f4e1f1df 100644 --- a/test-continuation-jetty6/pom.xml +++ b/test-continuation-jetty6/pom.xml @@ -9,6 +9,7 @@ jar Test :: Continuation - (Jetty 6) Asynchronous API + http://www.eclipse.org/jetty diff --git a/test-continuation/pom.xml b/test-continuation/pom.xml index 0f82e6d2b57..9abbc299c25 100644 --- a/test-continuation/pom.xml +++ b/test-continuation/pom.xml @@ -9,6 +9,7 @@ jar Test :: Continuation Asynchronous API + http://www.eclipse.org/jetty diff --git a/test-jetty-nested/pom.xml b/test-jetty-nested/pom.xml index c24dd96edb1..37548f1e3d9 100644 --- a/test-jetty-nested/pom.xml +++ b/test-jetty-nested/pom.xml @@ -8,6 +8,7 @@ test-jetty-nested Jetty :: Nested Test + http://www.eclipse.org/jetty war diff --git a/test-jetty-servlet/pom.xml b/test-jetty-servlet/pom.xml index 76445fc385a..a04abf7acdf 100644 --- a/test-jetty-servlet/pom.xml +++ b/test-jetty-servlet/pom.xml @@ -8,6 +8,7 @@ test-jetty-servlet jar Test :: Jetty Servlet Tester + http://www.eclipse.org/jetty org.eclipse.jetty diff --git a/test-jetty-webapp/pom.xml b/test-jetty-webapp/pom.xml index 27bfe32c142..1d4602a3738 100644 --- a/test-jetty-webapp/pom.xml +++ b/test-jetty-webapp/pom.xml @@ -7,6 +7,7 @@ 4.0.0 test-jetty-webapp Test :: Jetty Test Webapp + http://www.eclipse.org/jetty war diff --git a/tests/pom.xml b/tests/pom.xml index 28c9b913788..fcf9ecdac1c 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -26,6 +26,7 @@ org.eclipse.jetty.tests tests-parent Jetty Tests :: Parent + http://www.eclipse.org/jetty pom diff --git a/tests/test-integration/pom.xml b/tests/test-integration/pom.xml index 3a1dd98a18b..5a7ccac2e24 100644 --- a/tests/test-integration/pom.xml +++ b/tests/test-integration/pom.xml @@ -26,6 +26,7 @@ test-integration jar Jetty Tests :: Integrations + http://www.eclipse.org/jetty ${project.build.directory}/test-wars ${project.build.directory}/test-libs diff --git a/tests/test-loginservice/pom.xml b/tests/test-loginservice/pom.xml index c57352d492b..877cd109091 100644 --- a/tests/test-loginservice/pom.xml +++ b/tests/test-loginservice/pom.xml @@ -25,6 +25,7 @@ test-loginservice Jetty Tests :: Login Service + http://www.eclipse.org/jetty org.eclipse.jetty diff --git a/tests/test-sessions/pom.xml b/tests/test-sessions/pom.xml index a86bb113265..f342291d991 100644 --- a/tests/test-sessions/pom.xml +++ b/tests/test-sessions/pom.xml @@ -25,6 +25,7 @@ test-sessions-parent Jetty Tests :: Sessions :: Parent + http://www.eclipse.org/jetty pom diff --git a/tests/test-sessions/test-hash-sessions/pom.xml b/tests/test-sessions/test-hash-sessions/pom.xml index ed980b1fd41..943e16c06a7 100644 --- a/tests/test-sessions/test-hash-sessions/pom.xml +++ b/tests/test-sessions/test-hash-sessions/pom.xml @@ -25,6 +25,7 @@ test-hash-sessions Jetty Tests :: Sessions :: Hash + http://www.eclipse.org/jetty diff --git a/tests/test-sessions/test-jdbc-sessions/pom.xml b/tests/test-sessions/test-jdbc-sessions/pom.xml index 442a24f8fb2..e3ab0acba92 100644 --- a/tests/test-sessions/test-jdbc-sessions/pom.xml +++ b/tests/test-sessions/test-jdbc-sessions/pom.xml @@ -25,6 +25,7 @@ test-jdbc-sessions Jetty Tests :: Sessions :: JDBC + http://www.eclipse.org/jetty diff --git a/tests/test-sessions/test-mongodb-sessions/pom.xml b/tests/test-sessions/test-mongodb-sessions/pom.xml index 2ba10f22bb3..fbe57a5a183 100644 --- a/tests/test-sessions/test-mongodb-sessions/pom.xml +++ b/tests/test-sessions/test-mongodb-sessions/pom.xml @@ -25,6 +25,7 @@ test-mongodb-sessions Jetty Tests :: Sessions :: Mongo + http://www.eclipse.org/jetty diff --git a/tests/test-sessions/test-sessions-common/pom.xml b/tests/test-sessions/test-sessions-common/pom.xml index 0b70e2aa131..032aca9c12f 100644 --- a/tests/test-sessions/test-sessions-common/pom.xml +++ b/tests/test-sessions/test-sessions-common/pom.xml @@ -25,6 +25,7 @@ test-sessions-common Jetty Tests :: Sessions :: Common + http://www.eclipse.org/jetty diff --git a/tests/test-webapps/pom.xml b/tests/test-webapps/pom.xml index fd7d6eabe88..42985beb3df 100644 --- a/tests/test-webapps/pom.xml +++ b/tests/test-webapps/pom.xml @@ -25,6 +25,7 @@ test-webapps-parent Jetty Tests :: WebApps :: Parent + http://www.eclipse.org/jetty pom diff --git a/tests/test-webapps/test-webapp-rfc2616/pom.xml b/tests/test-webapps/test-webapp-rfc2616/pom.xml index ea437cf41e1..268d71b1738 100644 --- a/tests/test-webapps/test-webapp-rfc2616/pom.xml +++ b/tests/test-webapps/test-webapp-rfc2616/pom.xml @@ -25,6 +25,7 @@ test-webapp-rfc2616 Jetty Tests :: WebApp :: RFC2616 + http://www.eclipse.org/jetty war From 16994cbd6c60fad9a6c63a896794af5103770cdd Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Mon, 27 May 2013 16:09:12 +1000 Subject: [PATCH 02/32] 408909 GzipFilter setting of headers when reset and/or not compressed The gzip filter now sets deferred headers (content-length and etag) when it decides not to commit. Also does not allow a reset after a decision to commit --- .../http/gzip/AbstractCompressedStream.java | 20 ++++-- .../http/gzip/CompressedResponseWrapper.java | 65 +++++++++++++------ .../servlets/GzipFilterContentLengthTest.java | 15 ++++- .../jetty/servlets/GzipFilterDefaultTest.java | 57 +++++++++++++++- .../jetty/servlets/gzip/GzipTester.java | 22 +++++-- .../TestServletLengthStreamTypeWrite.java | 1 + .../TestServletLengthTypeStreamWrite.java | 1 + .../TestServletStreamLengthTypeWrite.java | 1 + .../TestServletStreamTypeLengthWrite.java | 1 + .../TestServletTypeLengthStreamWrite.java | 1 + .../TestServletTypeStreamLengthWrite.java | 1 + .../org/eclipse/jetty/testing/HttpTester.java | 8 +++ 12 files changed, 159 insertions(+), 34 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 3094d3a4661..e1c805e8b20 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 @@ -65,22 +65,31 @@ public abstract class AbstractCompressedStream extends ServletOutputStream doCompress(); } + /* ------------------------------------------------------------ */ /** * Reset buffer. */ public void resetBuffer() { - if (_response.isCommitted()) + if (_response.isCommitted() || _compressedOutputStream!=null ) throw new IllegalStateException("Committed"); _closed = false; _out = null; _bOut = null; - if (_compressedOutputStream != null) - _response.setHeader("Content-Encoding",null); - _compressedOutputStream = null; _doNotCompress = false; } + /* ------------------------------------------------------------ */ + public void setBufferSize(int bufferSize) + { + if (_bOut!=null && _bOut.getBuf().length 0 && length < _wrapper.getMinCompressSize()) + if (length >= 0 && length < _wrapper.getMinCompressSize()) doNotCompress(false); else doCompress(); @@ -359,4 +368,5 @@ public abstract class AbstractCompressedStream extends ServletOutputStream */ 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 index 0ddf8199871..f23799c9d8b 100644 --- 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 @@ -107,6 +107,8 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp public void setBufferSize(int bufferSize) { _bufferSize = bufferSize; + if (_compressedStream!=null) + _compressedStream.setBufferSize(bufferSize); } /* ------------------------------------------------------------ */ @@ -127,18 +129,21 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp { super.setContentType(ct); - if (ct!=null) + if (!_noCompression) { - 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(); + 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(); + } } } @@ -173,7 +178,10 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp @Override public void setContentLength(int length) { - setContentLength((long)length); + if (_noCompression) + super.setContentLength(length); + else + setContentLength((long)length); } /* ------------------------------------------------------------ */ @@ -311,6 +319,8 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp */ public void noCompression() { + if (!_noCompression) + setDeferredHeaders(); _noCompression=true; if (_compressedStream!=null) { @@ -335,6 +345,25 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp _writer.flush(); if (_compressedStream!=null) _compressedStream.finish(); + else + setDeferredHeaders(); + } + + /* ------------------------------------------------------------ */ + private void setDeferredHeaders() + { + if (!isCommitted()) + { + if (_contentLength>=0) + { + if (_contentLength < Integer.MAX_VALUE) + super.setContentLength((int)_contentLength); + else + super.setHeader("Content-Length",Long.toString(_contentLength)); + } + if(_etag!=null) + super.setHeader("ETag",_etag); + } } /* ------------------------------------------------------------ */ @@ -344,7 +373,9 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp @Override public void setHeader(String name, String value) { - if ("content-length".equalsIgnoreCase(name)) + if (_noCompression) + super.setHeader(name,value); + else if ("content-length".equalsIgnoreCase(name)) { setContentLength(Long.parseLong(value)); } @@ -370,7 +401,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp @Override public boolean containsHeader(String name) { - if ("etag".equalsIgnoreCase(name) && _etag!=null) + if (!_noCompression && "etag".equalsIgnoreCase(name) && _etag!=null) return true; return super.containsHeader(name); } @@ -385,10 +416,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp if (_compressedStream==null) { if (getResponse().isCommitted() || _noCompression) - { - setContentLength(_contentLength); return getResponse().getOutputStream(); - } _compressedStream=newCompressedStream(_request,(HttpServletResponse)getResponse()); } @@ -411,10 +439,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp throw new IllegalStateException("getOutputStream() called"); if (getResponse().isCommitted() || _noCompression) - { - setContentLength(_contentLength); return getResponse().getWriter(); - } _compressedStream=newCompressedStream(_request,(HttpServletResponse)getResponse()); _writer=newWriter(_compressedStream,getCharacterEncoding()); 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 0b1d21891bb..885a01d0c4f 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 @@ -33,7 +33,10 @@ import org.eclipse.jetty.servlets.gzip.TestServletStreamLengthTypeWrite; import org.eclipse.jetty.servlets.gzip.TestServletStreamTypeLengthWrite; import org.eclipse.jetty.servlets.gzip.TestServletTypeLengthStreamWrite; import org.eclipse.jetty.servlets.gzip.TestServletTypeStreamLengthWrite; +import org.eclipse.jetty.testing.HttpTester; import org.eclipse.jetty.toolchain.test.TestingDir; +import org.hamcrest.Matchers; +import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -131,7 +134,8 @@ public class GzipFilterContentLengthTest try { tester.start(); - tester.assertIsResponseNotGzipCompressed("GET",testfile.getName(),filesize,HttpStatus.OK_200); + HttpTester response = tester.assertIsResponseNotGzipCompressed("GET",testfile.getName(),filesize,HttpStatus.OK_200); + Assert.assertThat(response.getHeader("ETAG"),Matchers.startsWith("w/etag-")); } finally { @@ -139,6 +143,15 @@ public class GzipFilterContentLengthTest } } + /** + * Tests gzip compression of a small size file + */ + @Test + public void testEmpty() throws Exception + { + assertIsNotGzipCompressed("empty.txt",0); + } + /** * Tests gzip compression of a small size file */ 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 c420c4ce1e4..f6db6389041 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 @@ -79,6 +79,7 @@ public class GzipFilterDefaultTest protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setStatus(_status); + resp.setHeader("ETag","W/\"204\""); } } @@ -141,11 +142,40 @@ public class GzipFilterDefaultTest @Override public void service(HttpServletRequest req, HttpServletResponse resp) throws IOException,ServletException { + String uri=req.getRequestURI(); + if (uri.endsWith(".deferred")) + { + System.err.println("type for "+uri.substring(0,uri.length()-9)+" is "+getServletContext().getMimeType(uri.substring(0,uri.length()-9))); + resp.setContentType(getServletContext().getMimeType(uri.substring(0,uri.length()-9))); + } + doGet(req,resp); } } + + @Test + public void testIsGzipCompressedEmpty() throws Exception + { + GzipTester tester = new GzipTester(testingdir, compressionType); + + // Test content that is smaller than the buffer. + tester.prepareServerFile("empty.txt",0); + + FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class); + holder.setInitParameter("mimeTypes","text/plain"); + + try + { + tester.start(); + HttpTester http = tester.assertIsResponseNotGzipCompressed("GET","empty.txt",0,200); + } + finally + { + tester.stop(); + } + } @Test public void testIsGzipCompressedTiny() throws Exception @@ -242,7 +272,7 @@ public class GzipFilterDefaultTest tester.stop(); } } - + @Test public void testIsNotGzipCompressedWithQ() throws Exception { @@ -267,7 +297,7 @@ public class GzipFilterDefaultTest } @Test - public void testIsNotGzipCompressed() throws Exception + public void testIsNotGzipCompressedByContentType() throws Exception { GzipTester tester = new GzipTester(testingdir, compressionType); @@ -289,6 +319,29 @@ public class GzipFilterDefaultTest } } + @Test + public void testIsNotGzipCompressedByDeferredContentType() throws Exception + { + GzipTester tester = new GzipTester(testingdir, compressionType); + + int filesize = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE * 4; + tester.prepareServerFile("file.mp3.deferred",filesize); + + FilterHolder holder = tester.setContentServlet(GetServlet.class); + holder.setInitParameter("mimeTypes","text/plain"); + + try + { + tester.start(); + HttpTester http = tester.assertIsResponseNotGzipCompressed("GET","file.mp3.deferred", filesize, HttpStatus.OK_200); + Assert.assertNull(http.getHeader("Vary")); + } + finally + { + tester.stop(); + } + } + @Test public void testIsNotGzipCompressedHttpStatus() throws Exception { 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 179e5c957fb..95fe702d758 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 @@ -54,6 +54,7 @@ import org.eclipse.jetty.testing.ServletTester; import org.eclipse.jetty.toolchain.test.IO; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.TestingDir; +import org.hamcrest.Matchers; import org.junit.Assert; public class GzipTester @@ -108,6 +109,8 @@ public class GzipTester else Assert.assertThat("Response.header[Content-Encoding]", response.getHeader("Content-Encoding"),containsString(compressionType.substring(0,qindex))); + Assert.assertThat(response.getHeader("ETag"),Matchers.startsWith("W/")); + // Assert that the decompressed contents are what we expect. File serverFile = testdir.getFile(serverFilename); String expected = IO.readToString(serverFile); @@ -189,6 +192,8 @@ public class GzipTester Assert.assertThat(prefix + ".header[Content-Type] (should have a Content-Type associated with it)",response.getHeader("Content-Type"),notNullValue()); Assert.assertThat(prefix + ".header[Content-Type]",response.getHeader("Content-Type"),is(expectedContentType)); + Assert.assertThat(response.getHeader("ETAG"),Matchers.startsWith("w/etag-")); + ByteArrayInputStream bais = null; DigestOutputStream digester = null; try @@ -313,6 +318,10 @@ public class GzipTester int serverLength = Integer.parseInt(response.getHeader("Content-Length")); Assert.assertThat("Response.header[Content-Length]",serverLength,is(expectedFilesize)); } + + if (status>=200 && status<300) + Assert.assertThat(response.getHeader("ETAG"),Matchers.startsWith("W/")); + } private HttpTester executeRequest(String method,String uri) throws IOException, Exception @@ -345,11 +354,11 @@ public class GzipTester ByteArrayOutputStream out = null; try { - in = new ByteArrayInputStream(response.getContentBytes()); - out = new ByteArrayOutputStream(); - IO.copy(in,out); - - actual = out.toString(encoding); + byte[] content=response.getContentBytes(); + if (content!=null) + actual=new String(response.getContentBytes(),encoding); + else + actual=""; } finally { @@ -432,7 +441,7 @@ public class GzipTester finally { IO.close(in); - IO.close(fos); + IO.close(fos); } } @@ -464,6 +473,7 @@ public class GzipTester servletTester.setResourceBase(testdir.getDir().getCanonicalPath()); ServletHolder servletHolder = servletTester.addServlet(servletClass,"/"); servletHolder.setInitParameter("baseDir",testdir.getDir().getAbsolutePath()); + servletHolder.setInitParameter("etags","true"); FilterHolder holder = servletTester.addFilter(gzipFilterClass,"/*",0); holder.setInitParameter("vary","Accept-Encoding"); return holder; diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletLengthStreamTypeWrite.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletLengthStreamTypeWrite.java index 72fa2620ae7..c318facd9a4 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletLengthStreamTypeWrite.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletLengthStreamTypeWrite.java @@ -59,6 +59,7 @@ public class TestServletLengthStreamTypeWrite extends TestDirContentServlet response.setContentType("text/plain"); else if (fileName.endsWith("mp3")) response.setContentType("audio/mpeg"); + response.setHeader("ETag","w/etag-"+fileName); out.write(dataBytes); } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletLengthTypeStreamWrite.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletLengthTypeStreamWrite.java index 84a6ce3a6a8..227fc9f5f4b 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletLengthTypeStreamWrite.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletLengthTypeStreamWrite.java @@ -57,6 +57,7 @@ public class TestServletLengthTypeStreamWrite extends TestDirContentServlet response.setContentType("text/plain"); else if (fileName.endsWith("mp3")) response.setContentType("audio/mpeg"); + response.setHeader("ETag","w/etag-"+fileName); ServletOutputStream out = response.getOutputStream(); out.write(dataBytes); diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWrite.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWrite.java index a5046881e6f..b54fcdc77d8 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWrite.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWrite.java @@ -59,6 +59,7 @@ public class TestServletStreamLengthTypeWrite extends TestDirContentServlet response.setContentType("text/plain"); else if (fileName.endsWith("mp3")) response.setContentType("audio/mpeg"); + response.setHeader("ETag","w/etag-"+fileName); out.write(dataBytes); } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamTypeLengthWrite.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamTypeLengthWrite.java index 7b412d0cf3f..54ca2789b71 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamTypeLengthWrite.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamTypeLengthWrite.java @@ -57,6 +57,7 @@ public class TestServletStreamTypeLengthWrite extends TestDirContentServlet response.setContentType("text/plain"); else if (fileName.endsWith("mp3")) response.setContentType("audio/mpeg"); + response.setHeader("ETag","w/etag-"+fileName); response.setContentLength(dataBytes.length); diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletTypeLengthStreamWrite.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletTypeLengthStreamWrite.java index 1ae34f0ed54..2ae83eee2c6 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletTypeLengthStreamWrite.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletTypeLengthStreamWrite.java @@ -55,6 +55,7 @@ public class TestServletTypeLengthStreamWrite extends TestDirContentServlet response.setContentType("text/plain"); else if (fileName.endsWith("mp3")) response.setContentType("audio/mpeg"); + response.setHeader("ETag","w/etag-"+fileName); response.setContentLength(dataBytes.length); diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletTypeStreamLengthWrite.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletTypeStreamLengthWrite.java index 0d1def6f9bf..67c1e72d8d3 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletTypeStreamLengthWrite.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletTypeStreamLengthWrite.java @@ -55,6 +55,7 @@ public class TestServletTypeStreamLengthWrite extends TestDirContentServlet response.setContentType("text/plain"); else if (fileName.endsWith("mp3")) response.setContentType("audio/mpeg"); + response.setHeader("ETag","w/etag-"+fileName); ServletOutputStream out = response.getOutputStream(); diff --git a/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java b/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java index c47602d174d..67ed36b4d11 100644 --- a/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java +++ b/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java @@ -599,4 +599,12 @@ public class HttpTester } + @Override + public String toString() + { + if (_method!=null) + return super.toString()+" "+_method+" "+_uri+" "+_version+"\n"+_fields.toString(); + + return super.toString()+" HTTP/1.1 "+_status+" "+_reason+"\n"+_fields.toString(); + } } From 48c2a410b61e08412c72e4abd5173eee0cca9bdf Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Mon, 27 May 2013 17:48:08 +1000 Subject: [PATCH 03/32] 408909 GzipFilter setting of headers when reset and/or not compressed updated some more test harnesses for etag tests --- .../servlets/GzipFilterContentLengthTest.java | 2 +- .../servlets/GzipWithPipeliningTest.java | 263 ------------------ .../jetty/servlets/gzip/GzipTester.java | 2 +- .../servlets/gzip/TestMinGzipSizeServlet.java | 1 + .../TestServletLengthStreamTypeWrite.java | 2 +- .../TestServletLengthTypeStreamWrite.java | 2 +- .../TestServletStreamLengthTypeWrite.java | 2 +- .../TestServletStreamTypeLengthWrite.java | 2 +- .../TestServletTypeLengthStreamWrite.java | 2 +- .../TestServletTypeStreamLengthWrite.java | 2 +- .../gzip/TestStaticMimeTypeServlet.java | 1 + 11 files changed, 10 insertions(+), 271 deletions(-) delete mode 100644 jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipWithPipeliningTest.java 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 885a01d0c4f..8834aa688c1 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 @@ -135,7 +135,7 @@ public class GzipFilterContentLengthTest { tester.start(); HttpTester response = tester.assertIsResponseNotGzipCompressed("GET",testfile.getName(),filesize,HttpStatus.OK_200); - Assert.assertThat(response.getHeader("ETAG"),Matchers.startsWith("w/etag-")); + Assert.assertThat(response.getHeader("ETAG"),Matchers.startsWith("W/etag-")); } finally { 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 deleted file mode 100644 index 10a0fbc02df..00000000000 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipWithPipeliningTest.java +++ /dev/null @@ -1,263 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.servlets; - -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; -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.Inflater; -import java.util.zip.InflaterInputStream; - -import org.eclipse.jetty.server.Connector; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.servlet.DefaultServlet; -import org.eclipse.jetty.servlet.FilterHolder; -import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.servlets.gzip.Hex; -import org.eclipse.jetty.servlets.gzip.NoOpOutputStream; -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.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[][] - { - { GzipFilter.GZIP }, - { GzipFilter.DEFLATE + ", " + GzipFilter.GZIP }, - { GzipFilter.GZIP + ", " + GzipFilter.DEFLATE }, - { GzipFilter.DEFLATE } - }; - - 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 - { - // Configure Server - server = new Server(0); - - ServletContextHandler context = new ServletContextHandler(); - context.setContextPath("/"); - - DefaultServlet servlet = new DefaultServlet(); - ServletHolder holder = new ServletHolder(servlet); - holder.setInitParameter("resourceBase",MavenTestingUtils.getTestResourcesDir().getAbsolutePath()); - context.addServlet(holder,"/"); - - FilterHolder filter = context.addFilter(GzipFilter.class,"/*",0); - filter.setInitParameter("mimeTypes","text/plain"); - - server.setHandler(context); - - // Start Server - server.start(); - - Connector conn = server.getConnectors()[0]; - String host = conn.getHost(); - if (host == null) - { - host = "localhost"; - } - int port = conn.getLocalPort(); - serverUri = new URI(String.format("ws://%s:%d/",host,port)); - // System.out.printf("Server URI: %s%n",serverUri); - } - - @After - public void stopServer() throws Exception - { - server.stop(); - } - - @Test - public void testGzipThenImagePipelining() throws Exception - { - testingdir.ensureEmpty(); - File outputDir = testingdir.getDir(); - - PipelineHelper client = new PipelineHelper(serverUri, encodingHeader); - - try - { - File txtFile = MavenTestingUtils.getTestResourceFile("lots-of-fantasy-names.txt"); - File pngFile = MavenTestingUtils.getTestResourceFile("jetty_logo.png"); - - // Size of content, as it exists on disk, without gzip compression. - long rawsize = txtFile.length() + pngFile.length(); - assertThat("Ensure that we have sufficient file size to trigger chunking",rawsize,greaterThan(300000L)); - - String respHeader; - - client.connect(); - - // Request text that will be gzipped + chunked in the response - client.issueGET("/lots-of-fantasy-names.txt",true, false); - - respHeader = client.readResponseHeader(); - System.out.println("Response Header #1 --\n" + respHeader); - 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")); - - // Raw output / gzipped, writted to disk (checked for sha1sum later) - File rawOutputFile = new File(outputDir, "response-1.gz"); - FileOutputStream rawOutputStream = new FileOutputStream(rawOutputFile); - - long chunkSize = client.readChunkSize(); - System.out.println("Chunk Size: " + chunkSize); - - // Read only 20% - intentionally a partial read. - System.out.println("Attempting to read partial content ..."); - int readBytes = client.readBody(rawOutputStream,(int)(chunkSize * 0.20f)); - System.out.printf("Read %,d bytes%n",readBytes); - - // Issue another request - client.issueGET("/jetty_logo.png",true, false); - - // Finish reading chunks - System.out.println("Finish reading remaining chunks ..."); - String line; - chunkSize = chunkSize - readBytes; - while (chunkSize > 0) - { - readBytes = client.readBody(rawOutputStream,(int)chunkSize); - System.out.printf("Read %,d bytes%n",readBytes); - line = client.readLine(); - 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(); - assertThat("Inter-pipeline delim should be an empty line with CR+LF",line,is("")); - - // Sha1tracking for 1st Request - MessageDigest digestTxt = MessageDigest.getInstance("SHA1"); - DigestOutputStream digesterTxt = new DigestOutputStream(new NoOpOutputStream(),digestTxt); - - // Decompress 1st request and calculate sha1sum - IO.close(rawOutputStream); - FileInputStream rawInputStream = new FileInputStream(rawOutputFile); - InputStream uncompressedStream = null; - if (GzipFilter.DEFLATE.equals(encodingHeader)) - { - uncompressedStream = new InflaterInputStream(rawInputStream, new Inflater(true)); - } - 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); - 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"); - DigestOutputStream digesterImg = new DigestOutputStream(new NoOpOutputStream(),digestImg); - - // Read 2nd request body - int contentLength = client.getContentLength(respHeader); - assertThat("Image Content Length",(long)contentLength,is(pngFile.length())); - client.readBody(digesterImg,contentLength); - - // Validate checksums - IO.close(rawOutputStream); - assertChecksum("lots-of-fantasy-names.txt",digestTxt); - IO.close(digesterImg); - assertChecksum("jetty_logo.png",digestImg); - } - finally - { - client.disconnect(); - } - } - - private void assertChecksum(String testResourceFile, MessageDigest digest) throws IOException - { - String expectedSha1 = loadSha1sum(testResourceFile + ".sha1"); - String actualSha1 = Hex.asHex(digest.digest()); - assertEquals(testResourceFile + " / SHA1Sum of content",expectedSha1,actualSha1); - } - - private String loadSha1sum(String testResourceSha1Sum) throws IOException - { - File sha1File = MavenTestingUtils.getTestResourceFile(testResourceSha1Sum); - String contents = IO.readToString(sha1File); - Pattern pat = Pattern.compile("^[0-9A-Fa-f]*"); - Matcher mat = pat.matcher(contents); - 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/gzip/GzipTester.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java index 95fe702d758..4a034d4c883 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 @@ -192,7 +192,7 @@ public class GzipTester Assert.assertThat(prefix + ".header[Content-Type] (should have a Content-Type associated with it)",response.getHeader("Content-Type"),notNullValue()); Assert.assertThat(prefix + ".header[Content-Type]",response.getHeader("Content-Type"),is(expectedContentType)); - Assert.assertThat(response.getHeader("ETAG"),Matchers.startsWith("w/etag-")); + Assert.assertThat(response.getHeader("ETAG"),Matchers.startsWith("W/")); ByteArrayInputStream bais = null; DigestOutputStream digester = null; diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestMinGzipSizeServlet.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestMinGzipSizeServlet.java index 6883f9ab53d..697ee3b3b55 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestMinGzipSizeServlet.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestMinGzipSizeServlet.java @@ -51,6 +51,7 @@ public class TestMinGzipSizeServlet extends TestDirContentServlet byte[] dataBytes = loadContentFileBytes(fileName); response.setContentLength(dataBytes.length); + response.setHeader("ETag","W/etag-"+fileName); if (fileName.endsWith(".js")) { // intentionally long-form content type to test ";" splitting in code diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletLengthStreamTypeWrite.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletLengthStreamTypeWrite.java index c318facd9a4..8e873db95b2 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletLengthStreamTypeWrite.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletLengthStreamTypeWrite.java @@ -59,7 +59,7 @@ public class TestServletLengthStreamTypeWrite extends TestDirContentServlet response.setContentType("text/plain"); else if (fileName.endsWith("mp3")) response.setContentType("audio/mpeg"); - response.setHeader("ETag","w/etag-"+fileName); + response.setHeader("ETag","W/etag-"+fileName); out.write(dataBytes); } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletLengthTypeStreamWrite.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletLengthTypeStreamWrite.java index 227fc9f5f4b..bcde21bc5ea 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletLengthTypeStreamWrite.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletLengthTypeStreamWrite.java @@ -57,7 +57,7 @@ public class TestServletLengthTypeStreamWrite extends TestDirContentServlet response.setContentType("text/plain"); else if (fileName.endsWith("mp3")) response.setContentType("audio/mpeg"); - response.setHeader("ETag","w/etag-"+fileName); + response.setHeader("ETag","W/etag-"+fileName); ServletOutputStream out = response.getOutputStream(); out.write(dataBytes); diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWrite.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWrite.java index b54fcdc77d8..97131cae9ca 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWrite.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWrite.java @@ -59,7 +59,7 @@ public class TestServletStreamLengthTypeWrite extends TestDirContentServlet response.setContentType("text/plain"); else if (fileName.endsWith("mp3")) response.setContentType("audio/mpeg"); - response.setHeader("ETag","w/etag-"+fileName); + response.setHeader("ETag","W/etag-"+fileName); out.write(dataBytes); } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamTypeLengthWrite.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamTypeLengthWrite.java index 54ca2789b71..3f216b34338 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamTypeLengthWrite.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamTypeLengthWrite.java @@ -57,7 +57,7 @@ public class TestServletStreamTypeLengthWrite extends TestDirContentServlet response.setContentType("text/plain"); else if (fileName.endsWith("mp3")) response.setContentType("audio/mpeg"); - response.setHeader("ETag","w/etag-"+fileName); + response.setHeader("ETag","W/etag-"+fileName); response.setContentLength(dataBytes.length); diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletTypeLengthStreamWrite.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletTypeLengthStreamWrite.java index 2ae83eee2c6..4650b515d2f 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletTypeLengthStreamWrite.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletTypeLengthStreamWrite.java @@ -55,7 +55,7 @@ public class TestServletTypeLengthStreamWrite extends TestDirContentServlet response.setContentType("text/plain"); else if (fileName.endsWith("mp3")) response.setContentType("audio/mpeg"); - response.setHeader("ETag","w/etag-"+fileName); + response.setHeader("ETag","W/etag-"+fileName); response.setContentLength(dataBytes.length); diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletTypeStreamLengthWrite.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletTypeStreamLengthWrite.java index 67c1e72d8d3..b5152e09cbf 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletTypeStreamLengthWrite.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletTypeStreamLengthWrite.java @@ -55,7 +55,7 @@ public class TestServletTypeStreamLengthWrite extends TestDirContentServlet response.setContentType("text/plain"); else if (fileName.endsWith("mp3")) response.setContentType("audio/mpeg"); - response.setHeader("ETag","w/etag-"+fileName); + response.setHeader("ETag","W/etag-"+fileName); ServletOutputStream out = response.getOutputStream(); diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestStaticMimeTypeServlet.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestStaticMimeTypeServlet.java index 701088adf3b..16f00b0d2ec 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestStaticMimeTypeServlet.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestStaticMimeTypeServlet.java @@ -68,6 +68,7 @@ public class TestStaticMimeTypeServlet extends TestDirContentServlet byte[] dataBytes = loadContentFileBytes(fileName); response.setContentLength(dataBytes.length); + response.setHeader("ETag","W/etag-"+fileName); Buffer buf = mimeTypes.getMimeByExtension(fileName); if (buf == null) From 9f2a641dc075f4587068f2d43bf33521a3ddc488 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Wed, 29 May 2013 10:21:53 +1000 Subject: [PATCH 04/32] 409133 Empty causes StackOverflowError --- .../org/eclipse/jetty/webapp/StandardDescriptorProcessor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java index 5fc3be0af72..1b0089061d9 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java @@ -750,7 +750,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor String welcome = indexNode.toString(false, true); //Servlet Spec 3.0 p. 74 welcome files are additive - context.setWelcomeFiles((String[])LazyList.addToArray(context.getWelcomeFiles(),welcome,String.class)); + if (welcome != null && welcome.trim().length() > 0) + context.setWelcomeFiles((String[])LazyList.addToArray(context.getWelcomeFiles(),welcome,String.class)); } } From ecbb5328972b68da4a16c9af5650bb53adf726b9 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 30 May 2013 09:49:50 +1000 Subject: [PATCH 05/32] 408909 GzipFilter setting of headers when reset and/or not compressed defer commit until aggregate buffer overflows --- .../http/gzip/AbstractCompressedStream.java | 40 +++++++++++++------ 1 file changed, 28 insertions(+), 12 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 e1c805e8b20..4ff08a43eed 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 @@ -307,22 +307,38 @@ public abstract class AbstractCompressedStream extends ServletOutputStream throw new IOException("CLOSED"); if (_out == null) - { - long length=_wrapper.getContentLength(); - if (_response.isCommitted() || (length >= 0 && length < _wrapper.getMinCompressSize())) - doNotCompress(false); - else if (lengthToWrite > _wrapper.getMinCompressSize()) - doCompress(); + { + // If this first write is larger than buffer size, then we are committing now + if (lengthToWrite>_wrapper.getBufferSize()) + { + // if we know this is all the content and it is less than minimum, then do not compress, otherwise do compress + long length=_wrapper.getContentLength(); + if (length>=0 && length<_wrapper.getMinCompressSize()) + doNotCompress(false); // Not compressing by size, so no vary on request headers + else + doCompress(); + } else + { + // start aggregating writes into a buffered output stream _out = _bOut = new ByteArrayOutputStream2(_wrapper.getBufferSize()); + } } - else if (_bOut != null) + // else are we aggregating writes? + else if (_bOut !=null) { - long length=_wrapper.getContentLength(); - if (_response.isCommitted() || (length >= 0 && length < _wrapper.getMinCompressSize())) - doNotCompress(false); - else if (lengthToWrite >= (_bOut.getBuf().length - _bOut.getCount())) - doCompress(); + // We are aggregating into the buffered output stream. + + // If this write fills the buffer, then we are committing + if (lengthToWrite>=(_bOut.getBuf().length - _bOut.getCount())) + { + // if we know this is all the content and it is less than minimum, then do not compress, otherwise do compress + long length=_wrapper.getContentLength(); + if (length>=0 && length<_wrapper.getMinCompressSize()) + doNotCompress(false); // Not compressing by size, so no vary on request headers + else + doCompress(); + } } } From 219be496d91b3e60a726a762cc182a7bfd10f083 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Fri, 31 May 2013 10:59:34 +1000 Subject: [PATCH 06/32] 408529 Etags set in 304 response --- .../eclipse/jetty/servlet/DefaultServlet.java | 4 ++ .../jetty/servlets/GzipFilterDefaultTest.java | 53 ++++++++++++++++- .../jetty/servlets/gzip/GzipTester.java | 58 +++++++++++++++++-- 3 files changed, 110 insertions(+), 5 deletions(-) diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java index 5b5f32b8992..5ddcd6686ba 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java @@ -756,6 +756,8 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory { r.reset(true); r.setStatus(HttpServletResponse.SC_NOT_MODIFIED); + if (_etags) + r.getHttpFields().add(HttpHeaders.ETAG_BUFFER,content.getETag()); r.flushBuffer(); return false; } @@ -769,6 +771,8 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory { r.reset(true); r.setStatus(HttpServletResponse.SC_NOT_MODIFIED); + if (_etags) + r.getHttpFields().add(HttpHeaders.ETAG_BUFFER,content.getETag()); r.flushBuffer(); return false; } 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 f6db6389041..0298b6e8e61 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 @@ -145,7 +145,7 @@ public class GzipFilterDefaultTest String uri=req.getRequestURI(); if (uri.endsWith(".deferred")) { - System.err.println("type for "+uri.substring(0,uri.length()-9)+" is "+getServletContext().getMimeType(uri.substring(0,uri.length()-9))); + // System.err.println("type for "+uri.substring(0,uri.length()-9)+" is "+getServletContext().getMimeType(uri.substring(0,uri.length()-9))); resp.setContentType(getServletContext().getMimeType(uri.substring(0,uri.length()-9))); } @@ -272,6 +272,57 @@ public class GzipFilterDefaultTest tester.stop(); } } + + + @Test + public void testGzipedIfModified() throws Exception + { + GzipTester tester = new GzipTester(testingdir, compressionType); + + // Test content that is smaller than the buffer. + int filesize = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE * 4; + tester.prepareServerFile("file.txt",filesize); + + FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class); + holder.setInitParameter("mimeTypes","text/plain"); + + try + { + tester.start(); + HttpTester http = tester.assertIsResponseGzipCompressed("GET","file.txt",System.currentTimeMillis()-4000); + Assert.assertEquals("Accept-Encoding",http.getHeader("Vary")); + } + finally + { + tester.stop(); + } + } + + + @Test + public void testNotGzipedIfNotModified() throws Exception + { + GzipTester tester = new GzipTester(testingdir, compressionType); + + // Test content that is smaller than the buffer. + int filesize = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE * 4; + tester.prepareServerFile("file.txt",filesize); + + FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class); + holder.setInitParameter("mimeTypes","text/plain"); + holder.setInitParameter("etags","true"); + + try + { + tester.start(); + HttpTester http = tester.assertIsResponseNotModified("GET","file.txt",System.currentTimeMillis()+4000); + } + finally + { + tester.stop(); + } + } + @Test public void testIsNotGzipCompressedWithQ() throws Exception 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 4a034d4c883..9a16f333af4 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 @@ -45,6 +45,8 @@ import java.util.zip.InflaterInputStream; import javax.servlet.Servlet; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeaders; import org.eclipse.jetty.io.ByteArrayBuffer; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletHolder; @@ -54,6 +56,7 @@ import org.eclipse.jetty.testing.ServletTester; import org.eclipse.jetty.toolchain.test.IO; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.TestingDir; +import org.eclipse.jetty.util.DateCache; import org.hamcrest.Matchers; import org.junit.Assert; @@ -78,10 +81,20 @@ public class GzipTester { return assertIsResponseGzipCompressed(method,filename,filename); } + + public HttpTester assertIsResponseGzipCompressed(String method,String filename,long ifmodifiedsince) throws Exception + { + return assertIsResponseGzipCompressed(method,filename,filename,ifmodifiedsince); + } public HttpTester assertIsResponseGzipCompressed(String method,String requestedFilename, String serverFilename) throws Exception { - System.err.printf("[GzipTester] requesting /context/%s%n",requestedFilename); + return assertIsResponseGzipCompressed(method,requestedFilename,serverFilename,-1); + } + + public HttpTester assertIsResponseGzipCompressed(String method,String requestedFilename, String serverFilename, long ifmodifiedsince) throws Exception + { + //System.err.printf("[GzipTester] requesting /context/%s%n",requestedFilename); HttpTester request = new HttpTester(); HttpTester response = new HttpTester(); @@ -89,6 +102,8 @@ public class GzipTester request.setVersion("HTTP/1.0"); request.setHeader("Host","tester"); request.setHeader("Accept-Encoding",compressionType); + if (ifmodifiedsince>0) + request.setHeader(HttpHeaders.IF_MODIFIED_SINCE,HttpFields.formatDate(ifmodifiedsince)); if (this.userAgent != null) request.setHeader("User-Agent", this.userAgent); request.setURI("/context/" + requestedFilename); @@ -98,7 +113,7 @@ public class GzipTester // Collect the response(s) ByteArrayBuffer respBuff = servletTester.getResponses(reqsBuff); response.parse(respBuff.asArray()); - + // Assert the response headers Assert.assertThat("Response.method",response.getMethod(),nullValue()); // Assert.assertThat("Response.status",response.getStatus(),is(HttpServletResponse.SC_OK)); @@ -145,6 +160,41 @@ public class GzipTester return response; } + + + public HttpTester assertIsResponseNotModified(String method,String requestedFilename, long ifmodifiedsince) throws Exception + { + return assertIsResponseNotModified(method,requestedFilename,requestedFilename,ifmodifiedsince); + } + + public HttpTester assertIsResponseNotModified(String method,String requestedFilename, String serverFilename, long ifmodifiedsince) throws Exception + { + //System.err.printf("[GzipTester] requesting /context/%s%n",requestedFilename); + HttpTester request = new HttpTester(); + HttpTester response = new HttpTester(); + + request.setMethod(method); + request.setVersion("HTTP/1.0"); + request.setHeader("Host","tester"); + request.setHeader("Accept-Encoding",compressionType); + if (ifmodifiedsince>0) + request.setHeader(HttpHeaders.IF_MODIFIED_SINCE,HttpFields.formatDate(ifmodifiedsince)); + if (this.userAgent != null) + request.setHeader("User-Agent", this.userAgent); + request.setURI("/context/" + requestedFilename); + + // Issue the request + ByteArrayBuffer reqsBuff = new ByteArrayBuffer(request.generate().getBytes()); + // Collect the response(s) + ByteArrayBuffer respBuff = servletTester.getResponses(reqsBuff); + response.parse(respBuff.asArray()); + + Assert.assertThat(response.getStatus(),Matchers.equalTo(304)); + Assert.assertThat(response.getHeader("ETag"),Matchers.startsWith("W/")); + + return response; + } + /** * Makes sure that the response contains an unfiltered file contents. @@ -163,7 +213,7 @@ public class GzipTester */ public void assertIsResponseNotGzipFiltered(String requestedFilename, String testResourceSha1Sum, String expectedContentType) throws Exception { - System.err.printf("[GzipTester] requesting /context/%s%n",requestedFilename); + // System.err.printf("[GzipTester] requesting /context/%s%n",requestedFilename); HttpTester request = new HttpTester(); HttpTester response = new HttpTester(); @@ -326,7 +376,7 @@ public class GzipTester private HttpTester executeRequest(String method,String uri) throws IOException, Exception { - System.err.printf("[GzipTester] requesting %s%n",uri); + //System.err.printf("[GzipTester] requesting %s%n",uri); HttpTester request = new HttpTester(); HttpTester response = new HttpTester(); From 3094f93ed99c21ef4e6883282978496c3f0f8d01 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Fri, 31 May 2013 11:06:33 +1000 Subject: [PATCH 07/32] 408642 setContentType from addHeader --- .../src/main/java/org/eclipse/jetty/server/Response.java | 7 +++++++ .../test/java/org/eclipse/jetty/server/ResponseTest.java | 4 ++++ 2 files changed, 11 insertions(+) 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 7308f80fdd0..19ebd721293 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 @@ -570,6 +570,7 @@ public class Response implements HttpServletResponse */ public void addHeader(String name, String value) { + if (_connection.isIncluding()) { if (name.startsWith(SET_INCLUDE_HEADER_PREFIX)) @@ -578,6 +579,12 @@ public class Response implements HttpServletResponse return; } + if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name)) + { + setContentType(value); + return; + } + _connection.getResponseFields().add(name, value); if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name)) _connection._generator.setContentLength(Long.parseLong(value)); 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 233e2f04d09..8361cfd7ba5 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 @@ -170,6 +170,10 @@ public class ResponseTest response.setContentType("foo/bar"); assertEquals("foo/bar", response.getContentType()); + response.recycle(); + response.addHeader("Content-Type","text/something"); + assertEquals("text/something",response.getContentType()); + } @Test From 10845bfd284b5a1c86598a937d04825872e505c4 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Mon, 3 Jun 2013 15:13:28 +1000 Subject: [PATCH 08/32] 409556 FileInputStream not closed in DirectNIOBuffer --- .../eclipse/jetty/io/nio/DirectNIOBuffer.java | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/DirectNIOBuffer.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/DirectNIOBuffer.java index c8e4aecda68..ee0b0719e74 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/DirectNIOBuffer.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/DirectNIOBuffer.java @@ -31,6 +31,9 @@ import java.nio.channels.WritableByteChannel; import org.eclipse.jetty.io.AbstractBuffer; import org.eclipse.jetty.io.Buffer; +import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; /* ------------------------------------------------------------------------------- */ /** @@ -39,6 +42,8 @@ import org.eclipse.jetty.io.Buffer; */ public class DirectNIOBuffer extends AbstractBuffer implements NIOBuffer { + private static final Logger LOG = Log.getLogger(DirectNIOBuffer.class); + protected final ByteBuffer _buf; private ReadableByteChannel _in; private InputStream _inStream; @@ -69,12 +74,22 @@ public class DirectNIOBuffer extends AbstractBuffer implements NIOBuffer public DirectNIOBuffer(File file) throws IOException { super(READONLY,NON_VOLATILE); - FileInputStream fis = new FileInputStream(file); - FileChannel fc = fis.getChannel(); - _buf = fc.map(FileChannel.MapMode.READ_ONLY, 0, file.length()); - setGetIndex(0); - setPutIndex((int)file.length()); - _access=IMMUTABLE; + FileInputStream fis = null; + FileChannel fc = null; + try + { + fis = new FileInputStream(file); + fc = fis.getChannel(); + _buf = fc.map(FileChannel.MapMode.READ_ONLY, 0, file.length()); + setGetIndex(0); + setPutIndex((int)file.length()); + _access=IMMUTABLE; + } + finally + { + if (fc != null) try {fc.close();} catch (IOException e){LOG.ignore(e);} + IO.close(fis); + } } /* ------------------------------------------------------------ */ From 26c1e5bdbc99477670e04f7f3085a9a6b8805894 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Tue, 4 Jun 2013 10:34:52 +1000 Subject: [PATCH 09/32] 407342 ReloadedSessionMissingClassTest uses class compiled with jdk7 --- .../src/test/resources/foobar.jar | Bin 2531 -> 2448 bytes .../src/test/resources/foobarNOfoo.jar | Bin 1971 -> 1888 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/resources/foobar.jar b/tests/test-sessions/test-jdbc-sessions/src/test/resources/foobar.jar index 29b46ddee9f7fd818a0973f7768f89899d2d5165..ecf296c75c1966fa349a0023efc6b51fe1be80cf 100644 GIT binary patch delta 1511 zcmaDXJVBT@z?+#xgneOzY)ti0QK|n<# zE7YLT>CZN`Iw#kQ9#a(7-iR_!786)b2jap>d~p=P7U>k8T;);;?0^VMpl?_z5g`F8Ajbnj_XqT~XfVl3=lFvVz_*QAvX*L7CUSbU~d&*YBzM+Qq_e#7;O`HuwUW=A+QeoK!HKfI_@ zJ>t@b=1%#KQ!a#d>dmfboA2|d=eb(lL2h0#=lwm?w&^aPlc##DV9n+QX|lRaXV#q% zP~9GE_x&$}R^n35wbgf?^F2N3yJk`SnFDH?>{_|gALlJC`?PY$%bhjRc8mY7=I2S9 z+3h|peea{D;4K^7n5CbJwuBd+x_Kq9W8rpb<(DUyr~c+)e(U$?==41*n^vY~$sE-( z=}Nbl8sqo(yC#Rn+(fbKHhB{h*u6r}D{m~j);{Sir&+)znFR^P>y&>io3T;%{`sBP zy4KViTy)I8J;|&(&)~}q6HWo4GWk{}sh?e?j#o0<_s=V?NwieGH@7T!>H4j^SI+i) z{&U-c9Y4pSNe5(>Lo%-PT|G5-zXHF79@@Xr{CK)aUxuJk8d}S2a&OYF_e}*ZH4Q z!lzXW3R}XIzodQ%J-+?my-O`o4#_GEivtQ|)K9dm$dO3QXxTTrqx}^}yMcVTT6VyH zhdQT~%0f?WzVhxtqDKBq=T~L`_&9b^OzYJw(+we=gBQ$n_sbh zU<74xVD_ARnnl0#KCrAn=^Oj@R<_sVZuZ7mKi#z@?(MjBFVB2w z?mOSez`*m{md5&u9b7iO?)I8DcUqVKyYu_>)=ERkUmnI^CT!?ilps?7WRcO=;KJ~A zZ&!)-SfBivlqsFA^cpFhFopTieFwHxYuGuVu~ z)KlFiJWQBwovz0<_vg#~J@2mcNH-T>cq{#n5flWhwZYe30!t)wM&uAU8VPpddE+=@P0>hLOZUTsL42Yc)i}aFn5{ruiycwB9 z7$8OJmaxhBoH7d8ED-su#Ii(WX<#Hcf!sOSj#Df$0cfmSemh)XFxaB7EemzPZKtB`eo){S{;S<^=#J=2N09Q3arE&;)y|-DK|# z0DzCee|Hi^M3NMVUj|V`Bx<4!EtX2BpWD*C&1ef^v1PYKd{GcAodiK%jZ0HcpS?S!yEMaN<;>jh@O*Y4zz?(?T_~&0 z#D|1EazaDG3O8znSW66r`%o?i+iqMMsp=mV)m<5-ALC(!35;S|1}5=#^tJ`O_Q>vN zE^+(84ko6c_Vu5a1>uMf7q{2@R~B%KTla;M-!*oj=`Pcd!$Q5|$$j5rCUzb~>^QSU zcFV?tkYd(V>(+?7=`dBzj4v=AbdDk3EU)(vqFK$TT9q7Cq2bBnv?gryaSqB&fW0m5 zAIuA_>3}w9F#5QK0kFF)ep{Dy05-#+j&(hYhdTz1634u8tV^3i4I9iNmuVk6^|4(r z=877N@Ht%>>m|lSnFLPPq(Plwn{Vt9FTYY=LcOpi?n09Jpv~ElbNeNyjtv0Y2c5n1 zTYFMkKdW+Jo7&^#q51=k=nYBVpC2_Fh7(D* zEzq3OdW*PBZ`(s!EEV{Yx3M0bQ z=t#+jFXu-t8eq~54gBDfS_k$l3!HW9L4nY*@<&2dd6bviDUZyo?6D>$buG={zG>=S z$!;`JuhM^1JC*ww>`s&>yt%x75SOFbe;?ZOu+?||M8JHyiVa5OMH|a^YRfg7@M>(yaeL#yPnFKu*};QwK2E)QwM{3} zdKR>l4Cr6nc>j?a0HkX!Wk7F4Bs&gd%Rt>l+Gdc5Unnv`b#`n3Uw0F6vEwAzcpe}G zmcUw`e9Gj$x^Q&v^W0aM7>YB5RwC?m;3#v~U^`@6@rw*E*Ouzq@Dy@XqRf=yxEQJN z&}iGhz;so8cZ((7YVuWMeQmqh%P*q%Vh*=?roSwOaogF}!rLS&(^&6$2;wY*8Me9V zxYdV_hVTYv0?zFZ>$uUNw?iaC&n!{nfw3kp%|O;es<7yE*OAV{^Moc@L+$EwZ7O}c z*2^w+fgMoq6UV!Jd5(mI!e`uz3A6(`cTyh`lxwFJJMt$KU~^Gfx_15l(8teEm#Anc znA#n|KC4;&ldfzBu#@f&(2{;3lzkZNKvE=?^jvyVB|U#zt0MfxQpyGuRRr(@--?5i zlryn05F|sO4gl-p<9`r$X_a!msx^>R_Y_lGY5)NEcV|U3q{t|nM^lriOI6(p75r0o gR-B@yRN?Kz(!W*z01MrwYXATM diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/resources/foobarNOfoo.jar b/tests/test-sessions/test-jdbc-sessions/src/test/resources/foobarNOfoo.jar index fcb3ddf78c97ee9ce0ae1c1a03d2bb275579c7c4..593b9b12bd0d08e9a2e8cb6f680f6a10fb04f6f3 100644 GIT binary patch delta 1172 zcmdnY|A3D-z?+#xgneOzY)ti0QK|n<# zE7YLT>CZN`Iw#kQ9#a(7-iR_!786)b2jap>d~p=P7U>k8T;);;?0^VMpl?_z5g`F8Ajbnj_XqT~XfVl3=lFvVz_*QAvX*L7CUSbU~d&*YBzM+Qq_e#7;O`HuwUW=A+QeoK!HKfI_@ zJ>t@b=1%#KQ!a#d>dmfboA2|d=eb(lL2h0#=lwm?w&^aPlc##DV9n+QX|lRaXV#q% zP~9GE_x&$}R^n35wbgf?^F2N3yJk`SnFDH?>{_|gALlJC`?PY$%bhjRc8mY7=I2S9 z+3h|peea{D;4K^7n5CbJwuBd+x_Kq9W8rpb<(DUyr~c+)e(U$?==41*n^vY~$sE-( z=}Nbl8sqo(yC#Rn+(fbKHhB{h*u6r}D{m~j);{Sir&+)znFR^P>y&>io3T;%{`sBP zy4KViTy)I8J;|&(&)~}q6HWo4GWk{}sh?e?j#o0<_s=V?NwieGH@7T!>H4j^SI+i) z{&U-c9Y4pSNe5(>Lo%-PT|G5-zXHF79@@Xr{CK)aUxuJk8d}S2a&OYF_e}*ZH4Q z!lzXW3R}XIzodQ%J-+?my-O`o4#_GEivtQ|)K9dm$dO3QXxTTrqx}^}yMcVTT6VyH zhdQT~%0f?WzVhxtqDKBq=T~L`_&9b^OzYJwh6GI<;l&bSw1pC z^Z4XLY^DN`?Cu25#FN?CjjDix!2Ih3HwI`5Cop#-z%d}xDX~Z|IVZ8WIKZ2cNrVAX uh=8;$)8$m&&&a@_$;tpU2pMFvK(u8gmL&#wvjUA}U|<2lS3o)e%mV-dSOOdX delta 1258 zcmaFBx0#v;MW@5$PG)89&5T)t)cWvUn~o`b1oH z8pG7=PemV#7#RY***R>if(@M+7#LiD7-7<-xC|$t032`vSx$*XddWG7#l^j$XTzmK zMgH$iQOlp^oa4?z3D{amf_ZFMj{`ZvXwg-_QQ}d;WbrQ-%DzzQQxv9_}Cc z?p^&b&+iofk`D{}`af*6vAbB{>CP4@JN@IzHtoQeqo%T)G1L9I19cur9Z#1rFFCSt z$-`w=?qAxl=5cY&LdD~S^|O;(6^nLeh5yy&d6<$l*DRFmSg)whzC?u!+9H!E_B z$Kq*oXCF$B@O`%JjBK&_Th8+1LUmP_zh}RUE)j|93jMf4&&Ix5>C9@&ZR(qhUaxG* zpC)(LEZcF@f-N@3W&3u^tY++IIxf{*m%Lpit8S`{5k8n)df6_dT(Yc@pQ+xj4t+ zfnuh-*V|Q%TxPr>8&e+$u30cAai(tW%re!xdOZ(&^B%R=+-8WpYvw%V(7EbEpP8oe zJ`V^jZdK1&wK?s9VGNs@yQ#p|nbfM=gd#D}}9Vt?*eV$zDW z`}t^^M&Q29wbq+n+}L;HYyYi?(o3g*_L)hEKD=)jTO9qP>4g8*Z|gSC$a%G+>zJR8 z@9AWTmtQibPV&vYa4FzH*;esM(kuVpyTUN#?V~N*UUF^r(T-lVTaWjZhuz#aYnCll zJwMTF_KW&Osa0|33{Ow;Tf}`YagtpvFAuYrEsK=YSI)N_2_o9p7BAA>d~|Z^?a#iu zRjN+gy%92Ws5SL@xp{V0#+Y4FM1pAq7>jb**d zzF(_Ux-abLv{OxX>bxy#xoyt+rQChVoRgh1_mk~SiB`!H2NY`49;L`S3N7|{%u_q}7>Bjvi^4lg-R`RQvtK#Db?)#X z*FO!Oe_AyEG-dwj5^)ub@8lvCVPTzHXVxa|(KrtK=_UVANB*LMQ`^ya~1Frn{KX8 Date: Tue, 4 Jun 2013 09:04:12 -0700 Subject: [PATCH 10/32] Fixing JDK5 test error with comparison of query string --- .../org/eclipse/jetty/servlet/DispatcherTest.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DispatcherTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DispatcherTest.java index 8f3d61ebeaf..e6a8b4923c1 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DispatcherTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DispatcherTest.java @@ -18,8 +18,10 @@ package org.eclipse.jetty.servlet; +import static org.hamcrest.Matchers.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertThat; import java.io.IOException; import java.util.Arrays; @@ -55,6 +57,7 @@ import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.ResourceHandler; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.TypeUtil; +import org.eclipse.jetty.util.UrlEncoded; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -585,8 +588,15 @@ public class DispatcherTest assertTrue(requestAttributeNames.containsAll(expectedAttributeNames)); assertEquals(null, request.getPathInfo()); - assertEquals(null, request.getPathTranslated()); - assertTrue(request.getQueryString().startsWith("do=end&else=%D0%B2%D1%8B%D0%B1%D1%80%D0%B0%D0%BD%D0%BE%3D%D0%A2%D0%B5%D0%BC%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D1%83%D1%80%D0%B0&test=1&foreign=")); + assertEquals(null, request.getPathTranslated()); + + UrlEncoded query = new UrlEncoded(request.getQueryString()); + assertThat(query.getString("do"), is("end")); + // Russian for "selected=Temperature" + String russian = new UrlEncoded(query.getString("else")).encode(); + assertThat(russian, is("%D0%B2%D1%8B%D0%B1%D1%80%D0%B0%D0%BD%D0%BE=%D0%A2%D0%B5%D0%BC%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D1%83%D1%80%D0%B0")); + assertThat(query.getString("test"), is("1")); + assertThat(query.containsKey("foreign"), is(true)); String[] vals = request.getParameterValues("foreign"); assertTrue(vals!=null); From 559069cdd64f19113c7a2a44485be621306bb02f Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Tue, 4 Jun 2013 09:57:04 -0700 Subject: [PATCH 11/32] JDK5 fix for bad JarFile resource caching during deploy tests --- .../ScanningAppProviderRuntimeUpdatesTest.java | 12 ++++++++++-- .../jetty/deploy/test/XmlConfiguredJetty.java | 3 +++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderRuntimeUpdatesTest.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderRuntimeUpdatesTest.java index c127b7a5eff..34d36151ab2 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderRuntimeUpdatesTest.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderRuntimeUpdatesTest.java @@ -25,10 +25,12 @@ import org.eclipse.jetty.deploy.AppProvider; import org.eclipse.jetty.deploy.DeploymentManager; import org.eclipse.jetty.deploy.test.XmlConfiguredJetty; import org.eclipse.jetty.toolchain.test.OS; +import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.toolchain.test.TestingDir; import org.eclipse.jetty.util.Scanner; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.resource.Resource; import org.junit.After; import org.junit.Assume; import org.junit.Before; @@ -43,6 +45,9 @@ public class ScanningAppProviderRuntimeUpdatesTest { private static final Logger LOG = Log.getLogger(ScanningAppProviderRuntimeUpdatesTest.class); + @Rule + public TestTracker tracker = new TestTracker(); + @Rule public TestingDir testdir = new TestingDir(); private static XmlConfiguredJetty jetty; @@ -52,6 +57,9 @@ public class ScanningAppProviderRuntimeUpdatesTest @Before public void setupEnvironment() throws Exception { + testdir.ensureEmpty(); + Resource.setDefaultUseCaches(false); + jetty = new XmlConfiguredJetty(testdir); jetty.addConfiguration("jetty.xml"); jetty.addConfiguration("jetty-deploymgr-contexts.xml"); @@ -90,7 +98,7 @@ public class ScanningAppProviderRuntimeUpdatesTest public void waitForDirectoryScan() { - int scan=_scans.get()+2*_providers; + int scan=_scans.get()+(2*_providers); do { try @@ -167,8 +175,8 @@ public class ScanningAppProviderRuntimeUpdatesTest waitForDirectoryScan(); System.out.println("Updating war files"); - jetty.copyContext("foo.xml","foo.xml"); // essentially "touch" the context xml jetty.copyWebapp("foo-webapp-2.war","foo.war"); + jetty.copyContext("foo.xml","foo.xml"); // essentially "touch" the context xml // This should result in the existing foo.war being replaced with the new foo.war waitForDirectoryScan(); diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java index d538e8d1dae..c2f61be5b51 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java @@ -18,6 +18,8 @@ package org.eclipse.jetty.deploy.test; +import static org.hamcrest.Matchers.*; + import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -213,6 +215,7 @@ public class XmlConfiguredJetty if (context.getContextPath().equals(expectedPath)) { found = true; + Assert.assertThat("Context[" + context.getContextPath() + "].state", context.getState(), is("STARTED")); break; } } From 4b458792c90bddc134f830a00fc9a1535e589bb2 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Tue, 4 Jun 2013 10:42:32 -0700 Subject: [PATCH 12/32] JDK5 build fix with Resource caching and path lookups --- .../ReloadedSessionMissingClassTest.java | 29 ++++++++----------- .../session/WebAppObjectInSessionTest.java | 2 ++ 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java index 54094cd206f..3021e8d7c68 100644 --- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java +++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java @@ -18,9 +18,7 @@ package org.eclipse.jetty.server.session; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import java.io.File; import java.io.FileWriter; @@ -32,35 +30,32 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.client.ContentExchange; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.http.HttpMethods; -import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.toolchain.test.TestingDir; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.StdErrLog; +import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.webapp.WebAppContext; +import org.junit.Rule; import org.junit.Test; /** * ReloadedSessionMissingClassTest - * - * - * */ public class ReloadedSessionMissingClassTest { + @Rule + public TestingDir testdir = new TestingDir(); @Test public void testSessionReloadWithMissingClass() throws Exception { ((StdErrLog)Log.getLogger(org.eclipse.jetty.server.session.JDBCSessionManager.class)).setHideStacks(true); + Resource.setDefaultUseCaches(false); String contextPath = "/foo"; - File srcDir = new File(System.getProperty("basedir"), "src"); - File targetDir = new File(System.getProperty("basedir"), "target"); - File testDir = new File (srcDir, "test"); - File resourcesDir = new File (testDir, "resources"); - File unpackedWarDir = new File (targetDir, "foo"); - if (unpackedWarDir.exists()) - IO.delete(unpackedWarDir); - unpackedWarDir.mkdir(); + File unpackedWarDir = testdir.getDir(); + testdir.ensureEmpty(); File webInfDir = new File (unpackedWarDir, "WEB-INF"); webInfDir.mkdir(); @@ -81,8 +76,8 @@ public class ReloadedSessionMissingClassTest w.write(xml); w.close(); - File foobarJar = new File (resourcesDir, "foobar.jar"); - File foobarNOfooJar = new File (resourcesDir, "foobarNOfoo.jar"); + File foobarJar = MavenTestingUtils.getTestResourceFile("foobar.jar"); + File foobarNOfooJar = MavenTestingUtils.getTestResourceFile("foobarNOfoo.jar"); URL[] foobarUrls = new URL[]{foobarJar.toURI().toURL()}; URL[] barUrls = new URL[]{foobarNOfooJar.toURI().toURL()}; diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/WebAppObjectInSessionTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/WebAppObjectInSessionTest.java index bc6d47cac69..fe6675b2012 100644 --- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/WebAppObjectInSessionTest.java +++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/WebAppObjectInSessionTest.java @@ -18,6 +18,7 @@ package org.eclipse.jetty.server.session; +import org.eclipse.jetty.util.resource.Resource; import org.junit.Test; /** @@ -30,6 +31,7 @@ public class WebAppObjectInSessionTest extends AbstractWebAppObjectInSessionTest public AbstractTestServer createServer(int port) { + Resource.setDefaultUseCaches(false); return new JdbcTestServer(port); } From 52994f336a0e4b5d901d28693cec684218964882 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Fri, 7 Jun 2013 15:39:20 +1000 Subject: [PATCH 13/32] 408662 In pax-web servlet services requests even if init() has not finished running --- .../src/main/java/org/eclipse/jetty/servlet/ServletHolder.java | 2 ++ 1 file changed, 2 insertions(+) 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 1c6e95432b3..4e689069ba2 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 @@ -625,6 +625,8 @@ public class ServletHolder extends Holder implements UserIdentity.Scope Servlet servlet=_servlet; synchronized(this) { + if (!isStarted()) + throw new UnavailableException("Servlet not initialized", -1); if (_unavailable!=0 || !_initOnStartup) servlet=getServlet(); if (servlet==null) From f9e6cb932cea3c73eee63bf0d785f8754852ace9 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Wed, 12 Jun 2013 16:43:14 -0500 Subject: [PATCH 14/32] [Bug 410630] MongoSessionManager conflicting session update op --- .../nosql/mongodb/MongoSessionManager.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 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 22285ca3517..efea7e3420d 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 @@ -131,25 +131,25 @@ public class MongoSessionManager extends NoSqlSessionManager BasicDBObject sets = new BasicDBObject(); BasicDBObject unsets = new BasicDBObject(); - // handle new or existing - if (version == null) - { - // New session - upsert = true; - version = new Long(1); - sets.put(__CREATED,session.getCreationTime()); - sets.put(__VALID,true); - sets.put(getContextKey(__VERSION),version); - } - else - { - version = new Long(((Number)version).longValue() + 1); - update.put("$inc",__version_1); - } - // handle valid or invalid if (session.isValid()) { + // handle new or existing + if (version == null) + { + // New session + upsert = true; + version = new Long(1); + sets.put(__CREATED,session.getCreationTime()); + sets.put(__VALID,true); + sets.put(getContextKey(__VERSION),version); + } + else + { + version = new Long(((Number)version).longValue() + 1); + update.put("$inc",__version_1); + } + sets.put(__ACCESSED,session.getAccessed()); Set names = session.takeDirty(); if (isSaveAllAttributes() || upsert) From bd944080fccac082594aa22a682f524840e940cc Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Thu, 13 Jun 2013 09:54:20 -0500 Subject: [PATCH 15/32] [Bug 397193] MongoSessionManager refresh updates last access time --- .../nosql/mongodb/MongoSessionManager.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) 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 efea7e3420d..47d69094ff7 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 @@ -247,6 +247,7 @@ public class MongoSessionManager extends NoSqlSessionManager DBObject attrs = (DBObject)getNestedValue(o,getContextKey()); + if (attrs != null) { for (String name : attrs.keySet()) @@ -280,6 +281,22 @@ public class MongoSessionManager extends NoSqlSessionManager } } + /* + * We are refreshing so we should update the last accessed time. + */ + BasicDBObject key = new BasicDBObject(__ID,session.getClusterId()); + BasicDBObject sets = new BasicDBObject(); + // Form updates + BasicDBObject update = new BasicDBObject(); + sets.put(__ACCESSED,System.currentTimeMillis()); + // Do the upsert + if (!sets.isEmpty()) + { + update.put("$set",sets); + } + + _sessions.update(key,update,false,false); + session.didActivate(); return version; From a582b42d45a2ef54768f8d75e7e64fcdf0a73e05 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Thu, 13 Jun 2013 10:31:23 -0500 Subject: [PATCH 16/32] add logging properties for testing --- .../src/test/resources/jetty-logging.properties | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 tests/test-sessions/test-mongodb-sessions/src/test/resources/jetty-logging.properties diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/resources/jetty-logging.properties b/tests/test-sessions/test-mongodb-sessions/src/test/resources/jetty-logging.properties new file mode 100644 index 00000000000..fd2d21f9748 --- /dev/null +++ b/tests/test-sessions/test-mongodb-sessions/src/test/resources/jetty-logging.properties @@ -0,0 +1,4 @@ +# Setup default logging implementation for during testing +org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog + +#org.eclipse.jetty.server.LEVEL=DEBUG \ No newline at end of file From 953ab44909c1ebcc613ed7ec98d0a82fed458f5c Mon Sep 17 00:00:00 2001 From: Marko Mihovilic Date: Thu, 13 Jun 2013 18:40:39 +0200 Subject: [PATCH 17/32] [Bug 410750] NoSQLSessions: implement session context data persistence across server restarts --- .../jetty/nosql/NoSqlSessionManager.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionManager.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionManager.java index 38f148e6532..3a70ef61dc9 100644 --- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionManager.java +++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionManager.java @@ -40,6 +40,7 @@ public abstract class NoSqlSessionManager extends AbstractSessionManager impleme private int _savePeriod=0; private int _idlePeriod=-1; private boolean _invalidateOnStop; + private boolean _preserveOnStop; private boolean _saveAllAttributes; /* ------------------------------------------------------------ */ @@ -104,7 +105,10 @@ public abstract class NoSqlSessionManager extends AbstractSessionManager impleme for (NoSqlSession session : sessions) { session.save(false); - removeSession(session,false); + + if (!_preserveOnStop) { + removeSession(session,false); + } } } else @@ -277,6 +281,16 @@ public abstract class NoSqlSessionManager extends AbstractSessionManager impleme return _invalidateOnStop; } + /* ------------------------------------------------------------ */ + /** + * Preserve sessions when the session manager is stopped otherwise remove them from the DB. + * @return the removeOnStop + */ + public boolean isPreserveOnStop() + { + return _preserveOnStop; + } + /* ------------------------------------------------------------ */ /** * Invalidate sessions when the session manager is stopped otherwise save them to the DB. @@ -287,6 +301,16 @@ public abstract class NoSqlSessionManager extends AbstractSessionManager impleme _invalidateOnStop = invalidateOnStop; } + /* ------------------------------------------------------------ */ + /** + * Preserve sessions when the session manager is stopped otherwise remove them from the DB. + * @param removeOnStop the removeOnStop to set + */ + public void setPreserveOnStop(boolean preserveOnStop) + { + _preserveOnStop = preserveOnStop; + } + /* ------------------------------------------------------------ */ /** * Save all attributes of a session or only update the dirty attributes. From 78cd94edb32f6bf250ce856f76cb8d9209b43b1d Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Fri, 14 Jun 2013 11:24:30 -0500 Subject: [PATCH 18/32] [Bug 396706] CGI support parameters --- .../java/org/eclipse/jetty/servlets/CGI.java | 163 +++++++++++++----- 1 file changed, 116 insertions(+), 47 deletions(-) diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CGI.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CGI.java index c7b2b4f1fb7..6bd15d612c6 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CGI.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CGI.java @@ -22,6 +22,8 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; import java.util.Enumeration; import java.util.HashMap; import java.util.Locale; @@ -32,8 +34,11 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpMethods; import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.MultiMap; import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.UrlEncoded; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -222,35 +227,55 @@ public class CGI extends HttpServlet if ((pathTranslated == null) || (pathTranslated.length() == 0)) pathTranslated = path; + String bodyFormEncoded = null; + if ((HttpMethods.POST.equals(req.getMethod()) || HttpMethods.PUT.equals(req.getMethod())) && "application/x-www-form-urlencoded".equals(req.getContentType())) + { + MultiMap parameterMap = new MultiMap(); + Enumeration names = req.getParameterNames(); + while (names.hasMoreElements()) + { + String parameterName = (String)names.nextElement(); + parameterMap.addValues(parameterName, req.getParameterValues(parameterName)); + } + bodyFormEncoded = UrlEncoded.encode(parameterMap, req.getCharacterEncoding(), true); + } + EnvList env = new EnvList(_env); // these ones are from "The WWW Common Gateway Interface Version 1.1" // look at : // http://Web.Golux.Com/coar/cgi/draft-coar-cgi-v11-03-clean.html#6.1.1 - env.set("AUTH_TYPE",req.getAuthType()); - env.set("CONTENT_LENGTH",Integer.toString(len)); - env.set("CONTENT_TYPE",req.getContentType()); - env.set("GATEWAY_INTERFACE","CGI/1.1"); + env.set("AUTH_TYPE", req.getAuthType()); + if (bodyFormEncoded != null) + { + env.set("CONTENT_LENGTH", Integer.toString(bodyFormEncoded.length())); + } + else + { + env.set("CONTENT_LENGTH", Integer.toString(len)); + } + env.set("CONTENT_TYPE", req.getContentType()); + env.set("GATEWAY_INTERFACE", "CGI/1.1"); if ((pathInfo != null) && (pathInfo.length() > 0)) { - env.set("PATH_INFO",pathInfo); + env.set("PATH_INFO", pathInfo); } - env.set("PATH_TRANSLATED",pathTranslated); - env.set("QUERY_STRING",req.getQueryString()); - env.set("REMOTE_ADDR",req.getRemoteAddr()); - env.set("REMOTE_HOST",req.getRemoteHost()); + env.set("PATH_TRANSLATED", pathTranslated); + env.set("QUERY_STRING", req.getQueryString()); + env.set("REMOTE_ADDR", req.getRemoteAddr()); + env.set("REMOTE_HOST", req.getRemoteHost()); // The identity information reported about the connection by a // RFC 1413 [11] request to the remote agent, if // available. Servers MAY choose not to support this feature, or // not to request the data for efficiency reasons. // "REMOTE_IDENT" => "NYI" - env.set("REMOTE_USER",req.getRemoteUser()); - env.set("REQUEST_METHOD",req.getMethod()); - env.set("SCRIPT_NAME",scriptName); - env.set("SCRIPT_FILENAME",scriptPath); - env.set("SERVER_NAME",req.getServerName()); - env.set("SERVER_PORT",Integer.toString(req.getServerPort())); - env.set("SERVER_PROTOCOL",req.getProtocol()); - env.set("SERVER_SOFTWARE",getServletContext().getServerInfo()); + env.set("REMOTE_USER", req.getRemoteUser()); + env.set("REQUEST_METHOD", req.getMethod()); + env.set("SCRIPT_NAME", scriptName); + env.set("SCRIPT_FILENAME", scriptPath); + env.set("SERVER_NAME", req.getServerName()); + env.set("SERVER_PORT", Integer.toString(req.getServerPort())); + env.set("SERVER_PROTOCOL", req.getProtocol()); + env.set("SERVER_SOFTWARE", getServletContext().getServerInfo()); Enumeration enm = req.getHeaderNames(); while (enm.hasMoreElements()) @@ -261,7 +286,7 @@ public class CGI extends HttpServlet } // these extra ones were from printenv on www.dev.nomura.co.uk - env.set("HTTPS",(req.isSecure()?"ON":"OFF")); + env.set("HTTPS", (req.isSecure()?"ON":"OFF")); // "DOCUMENT_ROOT" => root + "/docs", // "SERVER_URL" => "NYI - http://us0245", // "TZ" => System.getProperty("user.timezone"), @@ -275,31 +300,22 @@ public class CGI extends HttpServlet if (_cmdPrefix != null) execCmd = _cmdPrefix + " " + execCmd; - Process p = (dir == null)?Runtime.getRuntime().exec(execCmd,env.getEnvArray()):Runtime.getRuntime().exec(execCmd,env.getEnvArray(),dir); + LOG.debug("Environment: " + env.getExportString()); + LOG.debug("Command: " + execCmd); + + Process p; + if (dir == null) + p = Runtime.getRuntime().exec(execCmd, env.getEnvArray()); + else + p = Runtime.getRuntime().exec(execCmd, env.getEnvArray(), dir); // hook processes input to browser's output (async) - final InputStream inFromReq = req.getInputStream(); - final OutputStream outToCgi = p.getOutputStream(); - final int inLength = len; + if (bodyFormEncoded != null) + writeProcessInput(p, bodyFormEncoded); + else if (len > 0) + writeProcessInput(p, req.getInputStream(), len); - IO.copyThread(p.getErrorStream(),System.err); - - new Thread(new Runnable() - { - public void run() - { - try - { - if (inLength > 0) - IO.copy(inFromReq,outToCgi,inLength); - outToCgi.close(); - } - catch (IOException e) - { - LOG.ignore(e); - } - } - }).start(); + IO.copyThread(p.getErrorStream(), System.err); // hook processes output to browser's input (sync) // if browser closes stream, we should detect it and kill process... @@ -376,15 +392,56 @@ public class CGI extends HttpServlet } catch (Exception e) { - LOG.ignore(e); + LOG.debug(e); } } - os = null; p.destroy(); // LOG.debug("CGI: terminated!"); } } + private static void writeProcessInput(final Process p, final String input) + { + new Thread(new Runnable() + { + public void run() + { + try + { + Writer outToCgi = new OutputStreamWriter(p.getOutputStream()); + outToCgi.write(input); + outToCgi.close(); + } + catch (IOException e) + { + LOG.debug(e); + } + } + }).start(); + } + + private static void writeProcessInput(final Process p, final InputStream input, final int len) + { + if (len <= 0) return; + + new Thread(new Runnable() + { + public void run() + { + try + { + OutputStream outToCgi = p.getOutputStream(); + IO.copy(input, outToCgi, len); + outToCgi.close(); + } + catch (IOException e) + { + LOG.debug(e); + } + } + }).start(); + } + /** * Utility method to get a line of text from the input stream. * @@ -393,7 +450,7 @@ public class CGI extends HttpServlet * @return the line of text * @throws IOException */ - private String getTextLineFromStream(InputStream is) throws IOException + private static String getTextLineFromStream(InputStream is) throws IOException { StringBuilder buffer = new StringBuilder(); int b; @@ -411,16 +468,16 @@ public class CGI extends HttpServlet */ private static class EnvList { - private Map envMap; + private Map envMap; EnvList() { - envMap = new HashMap(); + envMap = new HashMap(); } EnvList(EnvList l) { - envMap = new HashMap(l.envMap); + envMap = new HashMap(l.envMap); } /** @@ -434,7 +491,19 @@ public class CGI extends HttpServlet /** Get representation suitable for passing to exec. */ public String[] getEnvArray() { - return (String[])envMap.values().toArray(new String[envMap.size()]); + return envMap.values().toArray(new String[envMap.size()]); + } + + public String getExportString() + { + StringBuilder sb = new StringBuilder(); + for (String variable : getEnvArray()) + { + sb.append("export \""); + sb.append(variable); + sb.append("\"; "); + } + return sb.toString(); } @Override From 0bca1974b799e3a85e459b0f212bb5b9faf35e93 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 19 Jun 2013 19:43:49 +0200 Subject: [PATCH 19/32] 411135 - HttpClient may send proxied https requests to the proxy instead of the target server. Made sure to always tunnel the connection if needs to be tunnelled. --- .../eclipse/jetty/client/HttpDestination.java | 154 +++++++++--------- .../jetty/client/ProxyTunnellingTest.java | 93 ++++++++++- 2 files changed, 169 insertions(+), 78 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 1181eb80592..73c85d23161 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 @@ -52,10 +52,10 @@ public class HttpDestination implements Dumpable { private static final Logger LOG = Log.getLogger(HttpDestination.class); - private final List _queue = new LinkedList(); + private final List _exchanges = new LinkedList(); private final List _connections = new LinkedList(); - private final BlockingQueue _newQueue = new ArrayBlockingQueue(10, true); - private final List _idle = new ArrayList(); + private final BlockingQueue _reservedConnections = new ArrayBlockingQueue(10, true); + private final List _idleConnections = new ArrayList(); private final HttpClient _client; private final Address _address; private final boolean _ssl; @@ -63,14 +63,12 @@ public class HttpDestination implements Dumpable private volatile int _maxConnections; private volatile int _maxQueueSize; private int _pendingConnections = 0; - private int _newConnection = 0; + private int _pendingReservedConnections = 0; private volatile Address _proxy; private Authentication _proxyAuthentication; private PathMap _authorizations; private List _cookies; - - HttpDestination(HttpClient client, Address address, boolean ssl) { _client = client; @@ -136,7 +134,7 @@ public class HttpDestination implements Dumpable { synchronized (this) { - return _idle.size(); + return _idleConnections.size(); } } @@ -185,7 +183,7 @@ public class HttpDestination implements Dumpable int totalConnections = _connections.size() + _pendingConnections; if (totalConnections < _maxConnections) { - _newConnection++; + _pendingReservedConnections++; startConnection = true; } } @@ -195,7 +193,7 @@ public class HttpDestination implements Dumpable startNewConnection(); try { - Object o = _newQueue.take(); + Object o = _reservedConnections.take(); if (o instanceof AbstractHttpConnection) { connection = (AbstractHttpConnection)o; @@ -246,15 +244,15 @@ public class HttpDestination implements Dumpable connection.close(); connection = null; } - if (_idle.size() > 0) - connection = _idle.remove(_idle.size() - 1); + if (_idleConnections.size() > 0) + connection = _idleConnections.remove(_idleConnections.size() - 1); } if (connection == null) { return null; } - + // Check if the connection was idle, // but it expired just a moment ago if (connection.cancelIdleTimeout()) @@ -291,20 +289,20 @@ public class HttpDestination implements Dumpable synchronized (this) { _pendingConnections--; - if (_newConnection > 0) + if (_pendingReservedConnections > 0) { connect_failure = throwable; - _newConnection--; + _pendingReservedConnections--; } - else if (_queue.size() > 0) + else if (_exchanges.size() > 0) { - HttpExchange ex = _queue.remove(0); + HttpExchange ex = _exchanges.remove(0); if (ex.setStatus(HttpExchange.STATUS_EXCEPTED)) ex.getEventListener().onConnectionFailed(throwable); // Since an existing connection had failed, we need to create a // connection if the queue is not empty and client is running. - if (!_queue.isEmpty() && _client.isStarted()) + if (!_exchanges.isEmpty() && _client.isStarted()) startConnection = true; } } @@ -316,7 +314,7 @@ public class HttpDestination implements Dumpable { try { - _newQueue.put(connect_failure); + _reservedConnections.put(connect_failure); } catch (InterruptedException e) { @@ -330,10 +328,10 @@ public class HttpDestination implements Dumpable synchronized (this) { _pendingConnections--; - if (_queue.size() > 0) + if (_exchanges.size() > 0) { - HttpExchange ex = _queue.remove(0); - if(ex.setStatus(HttpExchange.STATUS_EXCEPTED)) + HttpExchange ex = _exchanges.remove(0); + if (ex.setStatus(HttpExchange.STATUS_EXCEPTED)) ex.getEventListener().onException(throwable); } } @@ -341,47 +339,53 @@ public class HttpDestination implements Dumpable public void onNewConnection(final AbstractHttpConnection connection) throws IOException { - Connection q_connection = null; + Connection reservedConnection = null; synchronized (this) { _pendingConnections--; _connections.add(connection); - if (_newConnection > 0) + if (_pendingReservedConnections > 0) { - q_connection = connection; - _newConnection--; - } - else if (_queue.size() == 0) - { - connection.setIdleTimeout(); - _idle.add(connection); + reservedConnection = connection; + _pendingReservedConnections--; } else { + // Establish the tunnel if needed EndPoint endPoint = connection.getEndPoint(); if (isProxied() && endPoint instanceof SelectConnector.UpgradableEndPoint) { SelectConnector.UpgradableEndPoint proxyEndPoint = (SelectConnector.UpgradableEndPoint)endPoint; - HttpExchange exchange = _queue.get(0); - ConnectExchange connect = new ConnectExchange(getAddress(), proxyEndPoint, exchange); + ConnectExchange connect = new ConnectExchange(getAddress(), proxyEndPoint); connect.setAddress(getProxy()); + LOG.debug("Establishing tunnel to {} via {}", getAddress(), getProxy()); send(connection, connect); } else { - HttpExchange exchange = _queue.remove(0); - send(connection, exchange); + // Another connection stole the exchange that caused the creation of this connection ? + if (_exchanges.size() == 0) + { + LOG.debug("No exchanges for new connection {}", connection); + connection.setIdleTimeout(); + _idleConnections.add(connection); + } + else + { + HttpExchange exchange = _exchanges.remove(0); + send(connection, exchange); + } } } } - if (q_connection != null) + if (reservedConnection != null) { try { - _newQueue.put(q_connection); + _reservedConnections.put(reservedConnection); } catch (InterruptedException e) { @@ -414,14 +418,14 @@ public class HttpDestination implements Dumpable { synchronized (this) { - if (_queue.size() == 0) + if (_exchanges.size() == 0) { connection.setIdleTimeout(); - _idle.add(connection); + _idleConnections.add(connection); } else { - HttpExchange ex = _queue.remove(0); + HttpExchange ex = _exchanges.remove(0); send(connection, ex); } this.notifyAll(); @@ -433,7 +437,7 @@ public class HttpDestination implements Dumpable synchronized (this) { _connections.remove(connection); - if (!_queue.isEmpty()) + if (!_exchanges.isEmpty()) startConnection = true; } @@ -445,16 +449,16 @@ public class HttpDestination implements Dumpable public void returnIdleConnection(AbstractHttpConnection connection) { // TODO work out the real idle time; - long idleForMs=connection!=null&&connection.getEndPoint()!=null?connection.getEndPoint().getMaxIdleTime():-1; + long idleForMs = connection.getEndPoint() != null ? connection.getEndPoint().getMaxIdleTime() : -1; connection.onIdleExpired(idleForMs); boolean startConnection = false; synchronized (this) { - _idle.remove(connection); + _idleConnections.remove(connection); _connections.remove(connection); - if (!_queue.isEmpty() && _client.isStarted()) + if (!_exchanges.isEmpty() && _client.isStarted()) startConnection = true; } @@ -472,10 +476,9 @@ public class HttpDestination implements Dumpable for (int i = listeners.size(); i > 0; --i) { String listenerClass = listeners.get(i - 1); - try { - Class listener = Class.forName(listenerClass); + Class listener = Class.forName(listenerClass); Constructor constructor = listener.getDeclaredConstructor(HttpDestination.class, HttpExchange.class); HttpEventListener elistener = (HttpEventListener)constructor.newInstance(this, ex); ex.setEventListener(elistener); @@ -484,7 +487,9 @@ public class HttpDestination implements Dumpable { throw new IOException("Unable to instantiate registered listener for destination: " + listenerClass) { - {initCause(e);} + { + initCause(e); + } }; } } @@ -549,10 +554,10 @@ public class HttpDestination implements Dumpable boolean startConnection = false; synchronized (this) { - if (_queue.size() == _maxQueueSize) + if (_exchanges.size() == _maxQueueSize) throw new RejectedExecutionException("Queue full for address " + _address); - _queue.add(ex); + _exchanges.add(ex); if (_connections.size() + _pendingConnections < _maxConnections) startConnection = true; } @@ -568,7 +573,7 @@ public class HttpDestination implements Dumpable // destination queue, make sure it is removed synchronized (this) { - _queue.remove(exchange); + _exchanges.remove(exchange); } } @@ -581,7 +586,7 @@ public class HttpDestination implements Dumpable if (!connection.send(exchange)) { if (exchange.getStatus() <= HttpExchange.STATUS_WAITING_FOR_CONNECTION) - _queue.add(0, exchange); + _exchanges.add(0, exchange); returnIdleConnection(connection); } } @@ -590,7 +595,7 @@ public class HttpDestination implements Dumpable @Override public synchronized String toString() { - return String.format("HttpDestination@%x//%s:%d(%d/%d,%d,%d/%d)%n",hashCode(),_address.getHost(),_address.getPort(),_connections.size(),_maxConnections,_idle.size(),_queue.size(),_maxQueueSize); + return String.format("HttpDestination@%x//%s:%d(%d/%d,%d,%d/%d)%n", hashCode(), _address.getHost(), _address.getPort(), _connections.size(), _maxConnections, _idleConnections.size(), _exchanges.size(), _maxQueueSize); } public synchronized String toDetailString() @@ -603,7 +608,7 @@ public class HttpDestination implements Dumpable for (AbstractHttpConnection connection : _connections) { b.append(connection.toDetailString()); - if (_idle.contains(connection)) + if (_idleConnections.contains(connection)) b.append(" IDLE"); b.append('\n'); } @@ -650,39 +655,33 @@ public class HttpDestination implements Dumpable } } - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.util.component.Dumpable#dump() - */ public String dump() { return AggregateLifeCycle.dump(this); } - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.util.component.Dumpable#dump(java.lang.Appendable, java.lang.String) - */ public void dump(Appendable out, String indent) throws IOException { synchronized (this) { - out.append(String.valueOf(this)+"idle="+_idle.size()+" pending="+_pendingConnections).append("\n"); - AggregateLifeCycle.dump(out,indent,_connections); + out.append(String.valueOf(this)); + out.append("idle="); + out.append(String.valueOf(_idleConnections.size())); + out.append(" pending="); + out.append(String.valueOf(_pendingConnections)); + out.append("\n"); + AggregateLifeCycle.dump(out, indent, _connections); } } private class ConnectExchange extends ContentExchange { private final SelectConnector.UpgradableEndPoint proxyEndPoint; - private final HttpExchange exchange; - public ConnectExchange(Address serverAddress, SelectConnector.UpgradableEndPoint proxyEndPoint, HttpExchange exchange) + public ConnectExchange(Address serverAddress, SelectConnector.UpgradableEndPoint proxyEndPoint) { this.proxyEndPoint = proxyEndPoint; - this.exchange = exchange; setMethod(HttpMethods.CONNECT); - setVersion(exchange.getVersion()); String serverHostAndPort = serverAddress.toString(); setRequestURI(serverHostAndPort); addRequestHeader(HttpHeaders.HOST, serverHostAndPort); @@ -698,13 +697,13 @@ public class HttpDestination implements Dumpable { proxyEndPoint.upgrade(); } - else if(responseStatus == HttpStatus.GATEWAY_TIMEOUT_504) + else if (responseStatus == HttpStatus.GATEWAY_TIMEOUT_504) { onExpire(); } else { - onException(new ProtocolException("Proxy: " + proxyEndPoint.getRemoteAddr() +":" + proxyEndPoint.getRemotePort() + " didn't return http return code 200, but " + responseStatus + " while trying to request: " + exchange.getAddress().toString())); + onException(new ProtocolException("Proxy: " + proxyEndPoint.getRemoteAddr() + ":" + proxyEndPoint.getRemotePort() + " didn't return http return code 200, but " + responseStatus)); } } @@ -717,18 +716,27 @@ public class HttpDestination implements Dumpable @Override protected void onException(Throwable x) { - _queue.remove(exchange); - if (exchange.setStatus(STATUS_EXCEPTED)) + HttpExchange exchange = null; + synchronized (HttpDestination.this) + { + if (!_exchanges.isEmpty()) + exchange = _exchanges.remove(0); + } + if (exchange != null && exchange.setStatus(STATUS_EXCEPTED)) exchange.getEventListener().onException(x); } @Override protected void onExpire() { - _queue.remove(exchange); - if (exchange.setStatus(STATUS_EXPIRED)) + HttpExchange exchange = null; + synchronized (HttpDestination.this) + { + if (!_exchanges.isEmpty()) + exchange = _exchanges.remove(0); + } + if (exchange != null && exchange.setStatus(STATUS_EXPIRED)) exchange.getEventListener().onExpire(); } - } } diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ProxyTunnellingTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ProxyTunnellingTest.java index 521710c057c..550c5418ea0 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ProxyTunnellingTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ProxyTunnellingTest.java @@ -18,13 +18,12 @@ package org.eclipse.jetty.client; -import static org.junit.Assert.*; - import java.io.IOException; +import java.io.InterruptedIOException; import java.net.URLEncoder; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; - +import java.util.concurrent.atomic.AtomicReference; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; @@ -32,6 +31,7 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpHeaders; import org.eclipse.jetty.http.HttpMethods; +import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.io.ByteArrayBuffer; import org.eclipse.jetty.server.Connector; @@ -45,8 +45,12 @@ import org.eclipse.jetty.server.ssl.SslSelectChannelConnector; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.junit.After; +import org.junit.Assert; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + public class ProxyTunnellingTest { private Server server; @@ -113,7 +117,7 @@ public class ProxyTunnellingTest } @Test - public void testOneMessageSSL() throws Exception + public void testOneExchangeViaSSL() throws Exception { startSSLServer(new ServerHandler()); startProxy(); @@ -141,7 +145,7 @@ public class ProxyTunnellingTest } @Test - public void testTwoMessagesSSL() throws Exception + public void testTwoExchangesViaSSL() throws Exception { startSSLServer(new ServerHandler()); startProxy(); @@ -181,6 +185,85 @@ public class ProxyTunnellingTest } } + @Test + public void testTwoConcurrentExchangesViaSSL() throws Exception + { + startSSLServer(new ServerHandler()); + startProxy(); + + final HttpClient httpClient = new HttpClient(); + httpClient.setProxy(new Address("localhost", proxyPort())); + httpClient.start(); + + try + { + final AtomicReference connection = new AtomicReference(); + final CountDownLatch connectionLatch = new CountDownLatch(1); + ContentExchange exchange1 = new ContentExchange(true) + { + @Override + protected void onRequestCommitted() throws IOException + { + // Simulate the concurrent send of a second exchange which + // triggers the opening of a second connection but then + // it's "stolen" by the first connection, so that the + // second connection is put into the idle connections. + + HttpDestination destination = httpClient.getDestination(new Address("localhost", serverConnector.getLocalPort()), true); + destination.startNewConnection(); + + // Wait until we have the new connection + AbstractHttpConnection httpConnection = null; + while (httpConnection == null) + { + try + { + Thread.sleep(10); + httpConnection = destination.getIdleConnection(); + } + catch (InterruptedException x) + { + throw new InterruptedIOException(); + } + } + + connection.set(httpConnection); + connectionLatch.countDown(); + } + }; + exchange1.setMethod(HttpMethods.GET); + String body1 = "BODY"; + exchange1.setURL("https://localhost:" + serverConnector.getLocalPort() + "/echo?body=" + URLEncoder.encode(body1, "UTF-8")); + + httpClient.send(exchange1); + assertEquals(HttpExchange.STATUS_COMPLETED, exchange1.waitForDone()); + assertEquals(HttpStatus.OK_200, exchange1.getResponseStatus()); + String content1 = exchange1.getResponseContent(); + assertEquals(body1, content1); + + Assert.assertTrue(connectionLatch.await(5, TimeUnit.SECONDS)); + + ContentExchange exchange2 = new ContentExchange(true); + exchange2.setMethod(HttpMethods.POST); + exchange2.setURL("https://localhost:" + serverConnector.getLocalPort() + "/echo"); + exchange2.setRequestHeader(HttpHeaders.CONTENT_TYPE, MimeTypes.FORM_ENCODED); + String body2 = "body=" + body1; + exchange2.setRequestHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(body2.length())); + exchange2.setRequestContent(new ByteArrayBuffer(body2, "UTF-8")); + + // Make sure the second connection can send the exchange via the tunnel + connection.get().send(exchange2); + assertEquals(HttpExchange.STATUS_COMPLETED, exchange2.waitForDone()); + assertEquals(HttpStatus.OK_200, exchange2.getResponseStatus()); + String content2 = exchange2.getResponseContent(); + assertEquals(body1, content2); + } + finally + { + httpClient.stop(); + } + } + @Test public void testProxyDown() throws Exception { From 0daddd1a3acf1609169de229b1f33aa2307ce981 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Mon, 24 Jun 2013 16:20:04 +1000 Subject: [PATCH 20/32] 411458 MultiPartFilter getParameterMap doesn't preserve multivalued parameters 411459 MultiPartFilter.Wrapper getParameter should use charset encoding of part --- .../jetty/servlets/MultiPartFilter.java | 32 +++++++-- .../jetty/servlets/MultipartFilterTest.java | 72 +++++++++++++++++-- .../org/eclipse/jetty/testing/HttpTester.java | 9 +++ 3 files changed, 103 insertions(+), 10 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 c872e936faa..f8d2d3e8b1d 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 @@ -48,12 +48,15 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; +import org.eclipse.jetty.http.MimeTypes; +import org.eclipse.jetty.io.ByteArrayBuffer; import org.eclipse.jetty.util.B64Code; import org.eclipse.jetty.util.LazyList; import org.eclipse.jetty.util.MultiMap; import org.eclipse.jetty.util.QuotedStringTokenizer; import org.eclipse.jetty.util.ReadLineInputStream; import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -513,12 +516,11 @@ public class MultiPartFilter implements Filter { try { - String s=new String((byte[])o,_encoding); - return s; + return getParameterBytesAsString(name, (byte[])o); } catch(Exception e) { - e.printStackTrace(); + LOG.warn(e); } } else if (o!=null) @@ -533,11 +535,11 @@ public class MultiPartFilter implements Filter @Override public Map getParameterMap() { - Map cmap = new HashMap(); + Map cmap = new HashMap(); for ( Object key : _params.keySet() ) { - cmap.put((String)key,getParameter((String)key)); + cmap.put((String)key,getParameterValues((String)key)); } return Collections.unmodifiableMap(cmap); @@ -571,7 +573,7 @@ public class MultiPartFilter implements Filter { try { - v[i]=new String((byte[])o,_encoding); + v[i]=getParameterBytesAsString(name, (byte[])o); } catch(Exception e) { @@ -594,6 +596,24 @@ public class MultiPartFilter implements Filter { _encoding=enc; } + + + /* ------------------------------------------------------------------------------- */ + private String getParameterBytesAsString (String name, byte[] bytes) + throws UnsupportedEncodingException + { + //check if there is a specific encoding for the parameter + Object ct = _params.get(name+CONTENT_TYPE_SUFFIX); + //use default if not + String contentType = _encoding; + if (ct != null) + { + String tmp = MimeTypes.getCharsetFromContentType(new ByteArrayBuffer((String)ct)); + contentType = (tmp == null?_encoding:tmp); + } + + return new String(bytes,contentType); + } } private static class Base64InputStream extends InputStream 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 5f12d70442c..a610a0f3705 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 @@ -21,21 +21,26 @@ package org.eclipse.jetty.servlets; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.PrintWriter; +import java.lang.reflect.Array; +import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.io.ByteArrayBuffer; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.FilterMapping; import org.eclipse.jetty.testing.HttpTester; import org.eclipse.jetty.testing.ServletTester; import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.StringUtil; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -747,7 +752,7 @@ public class MultipartFilterTest assertTrue(response.getContent().contains("aaaa,bbbbb")); } - + /* * see the testParameterMap test * @@ -758,13 +763,12 @@ public class MultipartFilterTest @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - String content = (String)req.getParameterMap().get("\"strup\"Content-Type: application/octet-stream"); + String content = (String)req.getParameter("\"strup\"Content-Type: application/octet-stream"); assertThat(content, containsString("How now brown cow.")); super.doPost(req, resp); - } - + } } /** @@ -809,6 +813,66 @@ public class MultipartFilterTest assertTrue(response.getContent().indexOf("brown cow")>=0); } + + public static class TestServletCharSet extends HttpServlet + { + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + //test that the multipart content bytes were converted correctly from their charset to unicode + String content = (String)req.getParameter("ttt"); + assertNotNull(content); + assertEquals("ttt\u01FCzzz",content); + assertEquals("application/octet-stream; charset=UTF-8",req.getParameter("ttt"+MultiPartFilter.CONTENT_TYPE_SUFFIX)); + + + //test that the parameter map retrieves values as String[] + Map map = req.getParameterMap(); + Object o = map.get("ttt"); + assertTrue(o.getClass().isArray()); + super.doPost(req, resp); + } + } + + + @Test + public void testWithCharSet() + throws Exception + { + // generated and parsed test + HttpTester request = new HttpTester() { + + }; + HttpTester response = new HttpTester(); + + tester.addServlet(TestServletCharSet.class,"/test2"); + + // test GET + request.setMethod("POST"); + request.setVersion("HTTP/1.0"); + request.setHeader("Host","tester"); + request.setURI("/context/test2"); + + String boundary="XyXyXy"; + request.setHeader("Content-Type","multipart/form-data; boundary="+boundary); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + baos.write(("--" + boundary + "\r\n"+ + "Content-Disposition: form-data; name=\"ttt\"\r\n"+ + "Content-Type: application/octet-stream; charset=UTF-8\r\n\r\n").getBytes()); + baos.write("ttt\u01FCzzz".getBytes(StringUtil.__UTF8)); + baos.write(("\r\n--" + boundary + "--\r\n\r\n").getBytes()); + + request.setContentBytes(baos.toByteArray()); + + response.parse(tester.getResponses(new ByteArrayBuffer(request.generate().getBytes(StringUtil.__UTF8))).toString()); + } + + + + public static class DumpServlet extends HttpServlet { private static final long serialVersionUID = 201012011130L; diff --git a/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java b/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java index 67ed36b4d11..422334b11e2 100644 --- a/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java +++ b/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java @@ -531,6 +531,15 @@ public class HttpTester _genContent=null; } } + + /* ------------------------------------------------------------ */ + public void setContentBytes(byte[] bytes) + { + _parsedContent = null; + _genContent = bytes; + setLongHeader(HttpHeaders.CONTENT_LENGTH, bytes.length); + + } /* ------------------------------------------------------------ */ private class PH extends HttpParser.EventHandler From 162cbc1416afcf92e9f70a22bd84ea9187dd1287 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Fri, 28 Jun 2013 10:20:20 -0700 Subject: [PATCH 21/32] 411909 - GzipFilter flushbuffer() results in erroneous finish() call + Bad finish() call changed to more appropriate flush() call --- .../org/eclipse/jetty/http/gzip/CompressedResponseWrapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index f23799c9d8b..1d804f31249 100644 --- 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 @@ -245,7 +245,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp if (_writer!=null) _writer.flush(); if (_compressedStream!=null) - _compressedStream.finish(); + _compressedStream.flush(); else getResponse().flushBuffer(); } From c089335f51961164edbb70795419cc066ecf7347 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Fri, 28 Jun 2013 14:58:55 -0500 Subject: [PATCH 22/32] add test for gzip streaming and flushing write --- .../servlets/GzipFilterContentLengthTest.java | 4 ++ ...ServletStreamLengthTypeWriteWithFlush.java | 70 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWriteWithFlush.java 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 8834aa688c1..a84349eca8e 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 @@ -21,6 +21,7 @@ package org.eclipse.jetty.servlets; import java.io.File; import java.util.Arrays; import java.util.List; + import javax.servlet.Servlet; import org.eclipse.jetty.http.HttpStatus; @@ -30,6 +31,7 @@ import org.eclipse.jetty.servlets.gzip.GzipTester; import org.eclipse.jetty.servlets.gzip.TestServletLengthStreamTypeWrite; import org.eclipse.jetty.servlets.gzip.TestServletLengthTypeStreamWrite; import org.eclipse.jetty.servlets.gzip.TestServletStreamLengthTypeWrite; +import org.eclipse.jetty.servlets.gzip.TestServletStreamLengthTypeWriteWithFlush; import org.eclipse.jetty.servlets.gzip.TestServletStreamTypeLengthWrite; import org.eclipse.jetty.servlets.gzip.TestServletTypeLengthStreamWrite; import org.eclipse.jetty.servlets.gzip.TestServletTypeStreamLengthWrite; @@ -72,12 +74,14 @@ public class GzipFilterContentLengthTest { TestServletLengthStreamTypeWrite.class, GzipFilter.GZIP }, { TestServletLengthTypeStreamWrite.class, GzipFilter.GZIP }, { TestServletStreamLengthTypeWrite.class, GzipFilter.GZIP }, + { TestServletStreamLengthTypeWriteWithFlush.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 }, + { TestServletStreamLengthTypeWriteWithFlush.class, GzipFilter.DEFLATE }, { TestServletStreamTypeLengthWrite.class, GzipFilter.DEFLATE }, { TestServletTypeLengthStreamWrite.class, GzipFilter.DEFLATE }, { TestServletTypeStreamLengthWrite.class, GzipFilter.DEFLATE } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWriteWithFlush.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWriteWithFlush.java new file mode 100644 index 00000000000..9d8e3fb7287 --- /dev/null +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWriteWithFlush.java @@ -0,0 +1,70 @@ +// +// ======================================================================== +// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.servlets.gzip; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.servlets.GzipFilter; + +/** + * A sample servlet to serve static content, using a order of construction that has caused problems for + * {@link GzipFilter} in the past. + * + * Using a real-world pattern of: + * + *
+ *  1) get stream
+ *  2) set content length
+ *  3) set content type
+ *  4) write and flush
+ * 
+ * + * @see http://bugs.eclipse.org/354014 + */ +@SuppressWarnings("serial") +public class TestServletStreamLengthTypeWriteWithFlush extends TestDirContentServlet +{ + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + String fileName = request.getServletPath(); + byte[] dataBytes = loadContentFileBytes(fileName); + + ServletOutputStream out = response.getOutputStream(); + + response.setContentLength(dataBytes.length); + + if (fileName.endsWith("txt")) + response.setContentType("text/plain"); + else if (fileName.endsWith("mp3")) + response.setContentType("audio/mpeg"); + response.setHeader("ETag","W/etag-"+fileName); + + for ( int i = 0 ; i < dataBytes.length ; i++) + { + out.write(dataBytes[i]); + response.flushBuffer(); + } + } +} \ No newline at end of file From f262dce23b21a9af3e67254181bed29cb2909d6e Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Fri, 28 Jun 2013 15:39:12 -0500 Subject: [PATCH 23/32] add test for gzip streaming and flushing write --- .../java/org/eclipse/jetty/servlets/gzip/GzipTester.java | 6 +++++- .../gzip/TestServletStreamLengthTypeWriteWithFlush.java | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) 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 9a16f333af4..c5a104a6856 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 @@ -117,7 +117,11 @@ public class GzipTester // Assert the response headers 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()); + if ( response.getHeader("X-Testing-Skip-Content-Length") == null ) + { + Assert.assertThat("Response.header[Content-Length]",response.getHeader("Content-Length"),notNullValue()); + } + int qindex = compressionType.indexOf(";"); if (qindex < 0) Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),containsString(compressionType)); diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWriteWithFlush.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWriteWithFlush.java index 9d8e3fb7287..d1cd1b1067c 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWriteWithFlush.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWriteWithFlush.java @@ -54,7 +54,8 @@ public class TestServletStreamLengthTypeWriteWithFlush extends TestDirContentSer ServletOutputStream out = response.getOutputStream(); response.setContentLength(dataBytes.length); - + response.setHeader("X-Testing-Skip-Content-Length","true"); + if (fileName.endsWith("txt")) response.setContentType("text/plain"); else if (fileName.endsWith("mp3")) From aa1aae182af1034edd4e895a5e1fcb8e2f47abb1 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Sun, 30 Jun 2013 16:37:08 -0700 Subject: [PATCH 24/32] Instituting Content-Length OR Transfer-Encoding check in GzipFilter tests + Tests currently fail, will let greg look deeply into jetty's eyes to determine why it defiantly doesn't want to cooperate with greg. --- .../jetty/servlets/gzip/GzipTester.java | 23 +++++++++---------- ...ServletStreamLengthTypeWriteWithFlush.java | 3 ++- 2 files changed, 13 insertions(+), 13 deletions(-) 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 c5a104a6856..ad3ea63a5e2 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 @@ -18,13 +18,8 @@ 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 static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -56,7 +51,6 @@ import org.eclipse.jetty.testing.ServletTester; import org.eclipse.jetty.toolchain.test.IO; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.TestingDir; -import org.eclipse.jetty.util.DateCache; import org.hamcrest.Matchers; import org.junit.Assert; @@ -116,10 +110,15 @@ public class GzipTester // Assert the response headers Assert.assertThat("Response.method",response.getMethod(),nullValue()); - // Assert.assertThat("Response.status",response.getStatus(),is(HttpServletResponse.SC_OK)); - if ( response.getHeader("X-Testing-Skip-Content-Length") == null ) - { - Assert.assertThat("Response.header[Content-Length]",response.getHeader("Content-Length"),notNullValue()); + + // Response headers should have either a Transfer-Encoding indicating chunked OR a Content-Length + String contentLength = response.getHeader("Content-Length"); + String transferEncoding = response.getHeader("Transfer-Encoding"); + boolean chunked = (transferEncoding != null) && (transferEncoding.indexOf("chunk") >= 0); + if(!chunked) { + Assert.assertThat("Response.header[Content-Length]",contentLength,notNullValue()); + } else { + Assert.assertThat("Response.header[Transfer-Encoding]",transferEncoding,notNullValue()); } int qindex = compressionType.indexOf(";"); diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWriteWithFlush.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWriteWithFlush.java index d1cd1b1067c..ff8841c1634 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWriteWithFlush.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWriteWithFlush.java @@ -53,8 +53,8 @@ public class TestServletStreamLengthTypeWriteWithFlush extends TestDirContentSer ServletOutputStream out = response.getOutputStream(); + // set content-length of uncompressed content (GzipFilter should handle this) response.setContentLength(dataBytes.length); - response.setHeader("X-Testing-Skip-Content-Length","true"); if (fileName.endsWith("txt")) response.setContentType("text/plain"); @@ -65,6 +65,7 @@ public class TestServletStreamLengthTypeWriteWithFlush extends TestDirContentSer for ( int i = 0 ; i < dataBytes.length ; i++) { out.write(dataBytes[i]); + // flush using response object (not the stream itself) response.flushBuffer(); } } From 091a4195686ad6b429d7170990e97a290d3a24bf Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Thu, 4 Jul 2013 11:10:46 +1000 Subject: [PATCH 25/32] 411755 MultiPartInputStreamParser fails on base64 encoded content --- .../jetty/servlets/MultiPartFilter.java | 24 +++++++++------ .../java/org/eclipse/jetty/util/B64Code.java | 29 +++++++++++++++++-- 2 files changed, 41 insertions(+), 12 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 f8d2d3e8b1d..eb826d11422 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 @@ -177,13 +177,12 @@ public class MultiPartFilter implements Filter // Read each part boolean lastPart=false; - String content_disposition=null; - String content_transfer_encoding=null; - - + outer:while(!lastPart && params.size()<_maxFormKeys) { String type_content=null; + String content_disposition=null; + String content_transfer_encoding=null; while(true) { @@ -286,7 +285,7 @@ public class MultiPartFilter implements Filter if ("base64".equalsIgnoreCase(content_transfer_encoding)) { - in = new Base64InputStream(in); + in = new Base64InputStream((ReadLineInputStream)in); } else if ("quoted-printable".equalsIgnoreCase(content_transfer_encoding)) { @@ -618,14 +617,14 @@ public class MultiPartFilter implements Filter private static class Base64InputStream extends InputStream { - BufferedReader _in; + ReadLineInputStream _in; String _line; byte[] _buffer; int _pos; - public Base64InputStream (InputStream in) + public Base64InputStream (ReadLineInputStream in) { - _in = new BufferedReader(new InputStreamReader(in)); + _in = in; } @Override @@ -634,6 +633,7 @@ public class MultiPartFilter implements Filter if (_buffer==null || _pos>= _buffer.length) { _line = _in.readLine(); + System.err.println("LINE: "+_line); if (_line==null) return -1; if (_line.startsWith("--")) @@ -641,7 +641,13 @@ public class MultiPartFilter implements Filter else if (_line.length()==0) _buffer="\r\n".getBytes(); else - _buffer=B64Code.decode(_line); + { + ByteArrayOutputStream bout = new ByteArrayOutputStream(4*_line.length()/3); + B64Code.decode(_line, bout); + bout.write(13); + bout.write(10); + _buffer = bout.toByteArray(); + } _pos=0; } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/B64Code.java b/jetty-util/src/main/java/org/eclipse/jetty/util/B64Code.java index 78dd63c709b..b8da7597b54 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/B64Code.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/B64Code.java @@ -350,12 +350,34 @@ public class B64Code { if (encoded==null) return null; + + ByteArrayOutputStream bout = new ByteArrayOutputStream(4*encoded.length()/3); + decode(encoded, bout); + return bout.toByteArray(); + } + + /* ------------------------------------------------------------ */ + /** + * Base 64 decode as described in RFC 2045. + *

Unlike {@link #decode(char[])}, extra whitespace is ignored. + * @param encoded String to decode. + * @param output stream for decoded bytes + * @return byte array containing the decoded form of the input. + * @throws IllegalArgumentException if the input is not a valid + * B64 encoding. + */ + static public void decode (String encoded, ByteArrayOutputStream bout) + { + if (encoded==null) + return; + + if (bout == null) + throw new IllegalArgumentException("No outputstream for decoded bytes"); int ci=0; byte nibbles[] = new byte[4]; int s=0; - ByteArrayOutputStream bout = new ByteArrayOutputStream(4*encoded.length()/3); - + while (ci Date: Thu, 4 Jul 2013 14:32:34 +1000 Subject: [PATCH 26/32] 411216 RequestLogHandler handles async completion --- .../server/handler/RequestLogHandler.java | 34 +++++++++++++------ .../jetty/continuation/ContinuationTest.java | 32 +++++++++++++++-- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java index 669ac992b73..db13f565641 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java @@ -24,6 +24,8 @@ 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.AsyncContinuation; import org.eclipse.jetty.server.DispatcherType; import org.eclipse.jetty.server.Request; @@ -34,12 +36,10 @@ import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; - /** * RequestLogHandler. * This handler can be used to wrap an individual context for context logging. * - * * @org.apache.xbean.XBean */ public class RequestLogHandler extends HandlerWrapper @@ -53,7 +53,7 @@ public class RequestLogHandler extends HandlerWrapper * @see org.eclipse.jetty.server.server.Handler#handle(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int) */ @Override - public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) + public void handle(String target, final Request baseRequest, HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException { AsyncContinuation continuation = baseRequest.getAsyncContinuation(); @@ -68,11 +68,25 @@ public class RequestLogHandler extends HandlerWrapper } finally { - if (_requestLog != null && DispatcherType.REQUEST.equals(baseRequest.getDispatcherType())) + if (continuation.isAsync()) { - _requestLog.log(baseRequest, (Response)response); + if (continuation.isInitial()) + continuation.addContinuationListener(new ContinuationListener() + { + + public void onTimeout(Continuation continuation) + { + + } + + public void onComplete(Continuation continuation) + { + _requestLog.log(baseRequest, (Response)response); + } + }); } - + else + _requestLog.log(baseRequest, (Response)response); } } @@ -139,9 +153,10 @@ public class RequestLogHandler extends HandlerWrapper @Override protected void doStart() throws Exception { + if (_requestLog==null) + throw new IllegalStateException("!RequestLog"); super.doStart(); - if (_requestLog!=null) - _requestLog.start(); + _requestLog.start(); } /* ------------------------------------------------------------ */ @@ -152,8 +167,7 @@ public class RequestLogHandler extends HandlerWrapper protected void doStop() throws Exception { super.doStop(); - if (_requestLog!=null) - _requestLog.stop(); + _requestLog.stop(); } } diff --git a/test-continuation/src/test/java/org/eclipse/jetty/continuation/ContinuationTest.java b/test-continuation/src/test/java/org/eclipse/jetty/continuation/ContinuationTest.java index 208c1a24a7e..7b6de7737f5 100644 --- a/test-continuation/src/test/java/org/eclipse/jetty/continuation/ContinuationTest.java +++ b/test-continuation/src/test/java/org/eclipse/jetty/continuation/ContinuationTest.java @@ -20,16 +20,25 @@ package org.eclipse.jetty.continuation; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import junit.framework.Assert; import org.eclipse.jetty.continuation.test.ContinuationBase; import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.RequestLog; +import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.RequestLogHandler; import org.eclipse.jetty.server.nio.SelectChannelConnector; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.component.AbstractLifeCycle; @@ -39,18 +48,26 @@ public class ContinuationTest extends ContinuationBase protected ServletHandler _servletHandler; protected SelectChannelConnector _connector; FilterHolder _filter; + protected List _log = new ArrayList(); @Override protected void setUp() throws Exception { _connector = new SelectChannelConnector(); _server.setConnectors(new Connector[]{ _connector }); + + _log.clear(); + RequestLogHandler requestLogHandler = new RequestLogHandler(); + requestLogHandler.setRequestLog(new Log()); + _server.setHandler(requestLogHandler); + ServletContextHandler servletContext = new ServletContextHandler(ServletContextHandler.NO_SECURITY|ServletContextHandler.NO_SESSIONS); - _server.setHandler(servletContext); + requestLogHandler.setHandler(servletContext); + _servletHandler=servletContext.getServletHandler(); ServletHolder holder=new ServletHolder(_servlet); _servletHandler.addServletWithMapping(holder,"/"); - + _server.start(); _port=_connector.getLocalPort(); @@ -59,6 +76,9 @@ public class ContinuationTest extends ContinuationBase @Override protected void tearDown() throws Exception { + Assert.assertEquals(1,_log.size()); + Assert.assertTrue(_log.get(0).startsWith("200 ")); + Assert.assertTrue(_log.get(0).endsWith(" /")); _server.stop(); } @@ -153,4 +173,12 @@ public class ContinuationTest extends ContinuationBase return IO.toString(in); } + class Log extends AbstractLifeCycle implements RequestLog + { + public void log(Request request, Response response) + { + _log.add(response.getStatus()+" "+response.getContentCount()+" "+request.getRequestURI()); + } + + } } From 49f865c45a6cb809a6e15388c93322c1ffae3d4f Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 4 Jul 2013 14:59:22 +1000 Subject: [PATCH 27/32] commented out incomplete test for EOF content --- .../test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java | 3 +++ 1 file changed, 3 insertions(+) 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 ad3ea63a5e2..c69d33ff04c 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 @@ -114,12 +114,15 @@ public class GzipTester // Response headers should have either a Transfer-Encoding indicating chunked OR a Content-Length String contentLength = response.getHeader("Content-Length"); String transferEncoding = response.getHeader("Transfer-Encoding"); + + /* TODO need to check for the 3rd option of EOF content. To do this properly you might need to look at both HTTP/1.1 and HTTP/1.0 requests boolean chunked = (transferEncoding != null) && (transferEncoding.indexOf("chunk") >= 0); if(!chunked) { Assert.assertThat("Response.header[Content-Length]",contentLength,notNullValue()); } else { Assert.assertThat("Response.header[Transfer-Encoding]",transferEncoding,notNullValue()); } + */ int qindex = compressionType.indexOf(";"); if (qindex < 0) From cb0084260fcda4f910a7e474886b299cc5c16661 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 4 Jul 2013 15:22:56 +1000 Subject: [PATCH 28/32] 411216 RequestLogHandler handles async completion --- .../server/handler/RequestLogHandler.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java index db13f565641..426aaded707 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java @@ -32,6 +32,7 @@ import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.RequestLog; import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -154,7 +155,10 @@ public class RequestLogHandler extends HandlerWrapper protected void doStart() throws Exception { if (_requestLog==null) - throw new IllegalStateException("!RequestLog"); + { + LOG.warn("!RequestLog"); + _requestLog=new NullRequestLog(); + } super.doStart(); _requestLog.start(); } @@ -168,6 +172,18 @@ public class RequestLogHandler extends HandlerWrapper { super.doStop(); _requestLog.stop(); + if (_requestLog instanceof NullRequestLog) + _requestLog=null; + } + + /* ------------------------------------------------------------ */ + /* ------------------------------------------------------------ */ + /* ------------------------------------------------------------ */ + private static class NullRequestLog extends AbstractLifeCycle implements RequestLog + { + public void log(Request request, Response response) + { + } } } From 8eb664970994f3ec7e4b7a39e88db8dac651c3f3 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 10 Jul 2013 22:57:23 +0200 Subject: [PATCH 29/32] 412712 - HttpClient does not send the terminal chunk after partial writes. HttpGenerator._header and HttpGenerator._buffer may be null when the content is written after a partial write. In this case, the terminal chunk was not prepared, and therefore never written. The fix simply creates a HttpGenerator._header to prepare the terminal chunk, so that it will be written. --- .../main/java/org/eclipse/jetty/http/HttpGenerator.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java index cd3edea4cba..85d70df09ab 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java @@ -1015,14 +1015,17 @@ public class HttpGenerator extends AbstractGenerator // If we need EOC and everything written if (_needEOC && (_content == null || _content.length() == 0)) { + if (_header == null && _buffer == null) + _header = _buffers.getHeader(); + if (_needCRLF) { - if (_buffer == null && _header != null && _header.space() >= 2) + if (_buffer == null && _header != null && _header.space() >= HttpTokens.CRLF.length) { _header.put(HttpTokens.CRLF); _needCRLF = false; } - else if (_buffer!=null && _buffer.space() >= 2) + else if (_buffer!=null && _buffer.space() >= HttpTokens.CRLF.length) { _buffer.put(HttpTokens.CRLF); _needCRLF = false; From af02334ff7a8beebbc700a63d1116cb3bbc7b68a Mon Sep 17 00:00:00 2001 From: Thomas Becker Date: Thu, 11 Jul 2013 15:13:01 +0200 Subject: [PATCH 30/32] 412750 HttpClient close expired connections fix --- .../eclipse/jetty/client/HttpExchange.java | 2 +- .../eclipse/jetty/client/IdleTimeoutTest.java | 67 +++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java index 6fe61048eb0..0877dd803e5 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java @@ -125,10 +125,10 @@ public class HttpExchange protected void expire(HttpDestination destination) { + AbstractHttpConnection connection = _connection; if (getStatus() < HttpExchange.STATUS_COMPLETED) setStatus(HttpExchange.STATUS_EXPIRED); destination.exchangeExpired(this); - AbstractHttpConnection connection = _connection; if (connection != null) connection.exchangeExpired(this); } diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/IdleTimeoutTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/IdleTimeoutTest.java index 930a378d284..ed2b29425ce 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/IdleTimeoutTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/IdleTimeoutTest.java @@ -18,13 +18,28 @@ package org.eclipse.jetty.client; +import java.io.IOException; +import java.net.URI; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.http.HttpMethods; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.AbstractHandler; +import org.eclipse.jetty.server.nio.SelectChannelConnector; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + /** * IdleTimeoutTest * @@ -77,4 +92,56 @@ public class IdleTimeoutTest Assert.fail("Test did not complete in time"); } + + @Test + public void testConnectionsAreReleasedWhenExpired() throws Exception + { + // we need a server that times out and a client with shorter timeout settings, so we need to create new ones + Server server = new Server(); + Connector connector = new SelectChannelConnector(); + server.addConnector(connector); + server.setHandler(new AbstractHandler() + { + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + if (request.getParameter("timeout") != null) + { + try + { + Thread.sleep(1000); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + baseRequest.setHandled(true); + response.getWriter().write("Hello world"); + } + }); + server.start(); + + HttpClient httpClient = new HttpClient(); + httpClient.setMaxConnectionsPerAddress(1); + httpClient.setConnectTimeout(200); + httpClient.setTimeout(200); + httpClient.setIdleTimeout(200); + httpClient.start(); + + String uriString = "http://localhost:" + connector.getLocalPort() + "/"; + + HttpExchange httpExchange = new HttpExchange(); + httpExchange.setURI(URI.create(uriString).resolve("?timeout=true")); + httpExchange.setMethod(HttpMethods.GET); + httpClient.send(httpExchange); + int status = httpExchange.waitForDone(); + assertThat("First request expired", status, is(8)); + + httpExchange = new HttpExchange(); + httpExchange.setURI(URI.create(uriString)); + httpExchange.setMethod(HttpMethods.GET); + httpClient.send(httpExchange); + status = httpExchange.waitForDone(); + assertThat("Second request was successful as timeout is not set", status, is(7)); + } } From ab7268e5163ff0788804e6d4eb809ce275dd51b9 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 24 Jul 2013 16:43:02 -0700 Subject: [PATCH 31/32] 413684 - Trailing slash shows JSP source + Adding testcase to replicate issue. --- .../org/eclipse/jetty/test/jsp/JspAndDefaultWithAliasesTest.java | 1 + .../eclipse/jetty/test/jsp/JspAndDefaultWithoutAliasesTest.java | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithAliasesTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithAliasesTest.java index 82ffc331813..3ba4f2c5e1c 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithAliasesTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithAliasesTest.java @@ -67,6 +67,7 @@ public class JspAndDefaultWithAliasesTest // @formatter:off data.add(new String[] { "false","/dump.jsp" }); + data.add(new String[] { "false","/dump.jsp/" }); data.add(new String[] { "true", "/dump.jsp%00" }); data.add(new String[] { "false","/dump.jsp%00/" }); data.add(new String[] { "false","/dump.jsp%00x/dump.jsp" }); diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithoutAliasesTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithoutAliasesTest.java index ab9f48473fc..5d119f86a02 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithoutAliasesTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithoutAliasesTest.java @@ -68,6 +68,7 @@ public class JspAndDefaultWithoutAliasesTest // @formatter:off data.add(new Object[] { "/dump.jsp" }); + data.add(new Object[] { "/dump.jsp/" }); data.add(new Object[] { "/dump.jsp%00" }); data.add(new Object[] { "/dump.jsp%00x" }); data.add(new Object[] { "/dump.jsp%00x/dump.jsp" }); From 2f08ba29487aff6624dbf947b1fbd845cdd33464 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 25 Jul 2013 11:01:23 +1000 Subject: [PATCH 32/32] 413684 - Trailing slash shows JSP source Fixed alias checkers. Non existent directory does check for none existence. Prefix and Suffix check look for none empty/trivial prefix/suffixes --- .../org/eclipse/jetty/server/handler/ContextHandler.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java index e22ebb8a4e6..c6c98f1e503 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java @@ -2191,7 +2191,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server. if (dot<0) return false; String suffix=path.substring(dot); - return resource.getAlias().toString().endsWith(suffix); + return resource.toString().endsWith(suffix); } } @@ -2206,10 +2206,10 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server. public boolean check(String path, Resource resource) { int slash = path.lastIndexOf('/'); - if (slash<0) + if (slash<0 || slash==path.length()-1) return false; String suffix=path.substring(slash); - return resource.getAlias().toString().endsWith(suffix); + return resource.toString().endsWith(suffix); } } /* ------------------------------------------------------------ */ @@ -2222,7 +2222,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server. public boolean check(String path, Resource resource) { int slash = path.lastIndexOf('/'); - if (slash<0) + if (slash<0 || resource.exists()) return false; String suffix=path.substring(slash); return resource.getAlias().toString().endsWith(suffix);