Merge branch 'jetty-9.4.x' of github.com:eclipse/jetty.project into jetty-9.4.x

This commit is contained in:
Joakim Erdfelt 2019-10-24 06:35:04 -05:00
commit 9b3b174862
No known key found for this signature in database
GPG Key ID: 2D0E1FB8FE4B68B4
158 changed files with 922 additions and 424 deletions

View File

@ -1,4 +1,49 @@
jetty-9.4.22-SNAPSHOT
jetty-9.4.23-SNAPSHOT
jetty-9.4.22.v20191022 - 22 October 2019
+ 2429 HttpClient backpressure improved
+ 3558 Error notifications can be received after a successful websocket
+ 3787 Jetty client sometimes returns EOFException instead of
SSLHandshakeException on certificate errors.
+ 3913 Clustered HttpSession IllegalStateException: Invalid for read
+ 3989 Inform custom ManagedSelector of dead selector via optional
onFailedSelect()
+ 4096 Thread in ReservedThreadExecutor does not exit when stopped
+ 4104 Frames are sent through ExtensionStack even if WebSocket Session is
closed
+ 4105 QueuedThreadPool increased thread usage and no idle thread decay
+ 4115 Drop HTTP/2 pseudo headers
+ 4121 QueuedThreadPool should support ThreadFactory behaviors
+ 4122 QueuedThreadPool should reset thread interrupted on failed run
+ 4128 OpenIdCredetials can't decode JWT ID token
+ 4132 Should be possible to use OIDC without metadata
+ 4141 ClassCastException with non-async Servlet + async Filter +
HttpServletRequestWrapper
+ 4142 Configurable HTTP/2 RateControl
+ 4144 Naked cast to Request should be avoided
+ 4156 IllegalStateException when forwarding to jsp with new session
+ 4158 Behaviour change in session handling in 9.4.21.v20190926
+ 4170 Client-side alias selection based on SSLEngine
+ 4174 ConcurrentModificationException when stopping jetty:run-war
+ 4176 Should not set header if sendError has been called
+ 4177 Configure HTTP proxy with SslContextFactory
+ 4179 Improve HttpChannel$SendCallback references for GC
+ 4183 Jetty considers bootstrap injected class to be a "server class"
+ 4188 Spin in HttpOutput.close
+ 4190 Jetty hangs after thread blocked in SharedBlockingCallback.block()
called by HttpOutput.close
+ 4191 Increase GzipHandler minGzipSize default size
+ 4193 InetAccessHandler - new includeConnectors/excludeConnectors not quite
correct anymore
+ 4201 Throw SSLHandshakeException in case of TLS handshake failures
+ 4203 Some Transfer-Encoding and Content-Length combinations do not result in
expected 400 Bad Request
+ 4204 Transfer-Encoding behavior does not follow RFC7230
+ 4208 Regression in Jetty 9.4.21: 304 response with Content-Length fails
+ 4209 Unused TLS connection is not closed in Java 11
+ 4217 SslConnection.DecryptedEnpoint.flush eternal busy loop
+ 4227 First authorization request produced by OIDC module fails due to
inclusion of sessionid
jetty-9.4.21.v20190926 - 26 September 2019
+ 97 Permanent UnavailableException thrown during servlet request handling
@ -9,7 +54,7 @@ jetty-9.4.21.v20190926 - 26 September 2019
+ 1036 Allow easy configuration of Scheduler-Threads and name them more
appropriate
+ 2815 HPack fields are opaque octets
+ 3040 Allow RFC6265 Cookies to include optional SameSite attribute.
+ 3040 Allow RFC6265 Cookies to include optional SameSite attribute
+ 3106 WebSocket connection stats and request stats
+ 3734 WebSocket suspend when input closed
+ 3747 Make Jetty Demo work with JPMS

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>apache-jsp</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>apache-jstl</artifactId>

View File

@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>build-resources</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Jetty :: Build Resources</name>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>example-async-rest</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>example-async-rest</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.examples</groupId>
<artifactId>examples-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.examples</groupId>
<artifactId>examples-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-alpn-client</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-alpn-server</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-alpn-parent</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-annotations</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-ant</artifactId>

View File

@ -9,7 +9,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<build>
@ -53,336 +53,336 @@
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>apache-jsp</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>apache-jstl</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-client</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-java-client</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-java-server</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-openjdk8-client</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-openjdk8-server</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-conscrypt-client</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-conscrypt-server</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-server</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-annotations</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-ant</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-continuation</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-deploy</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-distribution</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
<type>zip</type>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-distribution</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
<type>tar.gz</type>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.fcgi</groupId>
<artifactId>fcgi-client</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.fcgi</groupId>
<artifactId>fcgi-server</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.gcloud</groupId>
<artifactId>jetty-gcloud-session-manager</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-home</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
<type>zip</type>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-home</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
<type>tar.gz</type>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-http</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-client</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-common</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-hpack</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-http-client-transport</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-server</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-http-spi</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>infinispan-common</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>infinispan-remote-query</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>infinispan-embedded-query</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-hazelcast</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-io</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jaas</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jaspi</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jmx</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jndi</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.memcached</groupId>
<artifactId>jetty-memcached-sessions</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-nosql</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-boot</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-boot-jsp</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-boot-warurl</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-httpservice</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-plus</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-proxy</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-quickstart</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-rewrite</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-security</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-openid</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlets</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-spring</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-unixsocket</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util-ajax</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>javax-websocket-client-impl</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>javax-websocket-server-impl</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-api</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-client</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-common</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-server</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-servlet</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-xml</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.eclipse.jetty</groupId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -807,4 +807,120 @@ public class HttpClientTLSTest
Throwable cause = failure.getCause();
assertThat(cause, Matchers.instanceOf(SSLHandshakeException.class));
}
@Test
public void testTLSLargeFragments() throws Exception
{
CountDownLatch serverLatch = new CountDownLatch(1);
SslContextFactory serverTLSFactory = createServerSslContextFactory();
QueuedThreadPool serverThreads = new QueuedThreadPool();
serverThreads.setName("server");
server = new Server(serverThreads);
HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.addCustomizer(new SecureRequestCustomizer());
HttpConnectionFactory http = new HttpConnectionFactory(httpConfig);
SslConnectionFactory ssl = new SslConnectionFactory(serverTLSFactory, http.getProtocol())
{
@Override
protected SslConnection newSslConnection(Connector connector, EndPoint endPoint, SSLEngine engine)
{
return new SslConnection(connector.getByteBufferPool(), connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
{
@Override
protected SSLEngineResult unwrap(SSLEngine sslEngine, ByteBuffer input, ByteBuffer output) throws SSLException
{
int inputBytes = input.remaining();
SSLEngineResult result = super.unwrap(sslEngine, input, output);
if (inputBytes == 5)
serverLatch.countDown();
return result;
}
};
}
};
connector = new ServerConnector(server, 1, 1, ssl, http);
server.addConnector(connector);
server.setHandler(new EmptyServerHandler());
server.start();
long idleTimeout = 2000;
CountDownLatch clientLatch = new CountDownLatch(1);
SslContextFactory clientTLSFactory = createClientSslContextFactory();
QueuedThreadPool clientThreads = new QueuedThreadPool();
clientThreads.setName("client");
client = new HttpClient(clientTLSFactory)
{
@Override
protected ClientConnectionFactory newSslClientConnectionFactory(SslContextFactory sslContextFactory, ClientConnectionFactory connectionFactory)
{
if (sslContextFactory == null)
sslContextFactory = getSslContextFactory();
return new SslClientConnectionFactory(sslContextFactory, getByteBufferPool(), getExecutor(), connectionFactory)
{
@Override
protected SslConnection newSslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine engine)
{
return new SslConnection(byteBufferPool, executor, endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
{
@Override
protected SSLEngineResult wrap(SSLEngine sslEngine, ByteBuffer[] input, ByteBuffer output) throws SSLException
{
try
{
clientLatch.countDown();
assertTrue(serverLatch.await(5, TimeUnit.SECONDS));
return super.wrap(sslEngine, input, output);
}
catch (InterruptedException x)
{
throw new SSLException(x);
}
}
};
}
};
}
};
client.setIdleTimeout(idleTimeout);
client.setExecutor(clientThreads);
client.start();
String host = "localhost";
int port = connector.getLocalPort();
CountDownLatch responseLatch = new CountDownLatch(1);
client.newRequest(host, port)
.scheme(HttpScheme.HTTPS.asString())
.send(result ->
{
assertTrue(result.isSucceeded());
assertEquals(HttpStatus.OK_200, result.getResponse().getStatus());
responseLatch.countDown();
});
// Wait for the TLS buffers to be acquired by the client, then the
// HTTP request will be paused waiting for the TLS buffer to be expanded.
assertTrue(clientLatch.await(5, TimeUnit.SECONDS));
// Send the large frame bytes that will enlarge the TLS buffers.
try (Socket socket = new Socket(host, port))
{
OutputStream output = socket.getOutputStream();
byte[] largeFrameBytes = new byte[5];
largeFrameBytes[0] = 22; // Type = handshake
largeFrameBytes[1] = 3; // Major TLS version
largeFrameBytes[2] = 3; // Minor TLS version
// Frame length is 0x7FFF == 32767, i.e. a "large fragment".
// Maximum allowed by RFC 8446 is 16384, but SSLEngine supports up to 33093.
largeFrameBytes[3] = 0x7F; // Length hi byte
largeFrameBytes[4] = (byte)0xFF; // Length lo byte
output.write(largeFrameBytes);
output.flush();
// Just close the connection now, the large frame
// length was enough to trigger the buffer expansion.
}
// The HTTP request will resume and be forced to handle the TLS buffer expansion.
assertTrue(responseLatch.await(5, TimeUnit.SECONDS));
}
}

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-continuation</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-deploy</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-distribution</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<artifactId>jetty-documentation</artifactId>
<name>Jetty :: Documentation</name>

View File

@ -19,8 +19,8 @@
[[serving-aliased-files]]
=== Aliased Files and Symbolic links
Web applications will often server static content from the file system provided by the operating system running underneath the JVM.
However because file systems often implement multiple aliased names for the same file, then security constraints and other servlet URI space mappings my inadvertently be bypassed by aliases.
Web applications will often serve static content from the file system provided by the operating system running underneath the JVM.
However, because file systems often implement multiple aliased names for the same file, then security constraints and other servlet URI space mappings may inadvertently be bypassed by aliases.
A key example of this is case insensitivity and 8.3 filenames implemented by the Windows file system.
If a file within a web application called `/mysecretfile.txt` is protected by a security constraint on the URI `/mysecretfile.txt`, then a request to `/MySecretFile.TXT` will not match the URI constraint because URIs are case sensitive, but the Windows file system will report that a file does exist at that name and it will be served despite the security constraint.

View File

@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.fcgi</groupId>
<artifactId>fcgi-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.fcgi</groupId>
<artifactId>fcgi-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.gcloud</groupId>
<artifactId>gcloud-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<artifactId>jetty-project</artifactId>
<groupId>org.eclipse.jetty</groupId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<artifactId>jetty-project</artifactId>
<groupId>org.eclipse.jetty</groupId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-home</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-http-spi</artifactId>

View File

@ -3,7 +3,7 @@
<parent>
<artifactId>jetty-project</artifactId>
<groupId>org.eclipse.jetty</groupId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-http</artifactId>

View File

@ -704,17 +704,24 @@ public class HttpGenerator
_endOfContent = EndOfContent.NO_CONTENT;
// But it is an error if there actually is content
if (_contentPrepared > 0 || contentLength > 0)
if (_contentPrepared > 0)
throw new BadMessageException(INTERNAL_SERVER_ERROR_500, "Content for no content response");
if (contentLengthField)
{
if (_contentPrepared == 0 && last)
if (response != null && response.getStatus() == HttpStatus.NOT_MODIFIED_304)
putContentLength(header, contentLength);
else if (contentLength > 0)
{
// TODO discard content for backward compatibility with 9.3 releases
// TODO review if it is still needed in 9.4 or can we just throw.
content.clear();
contentLength = 0;
if (_contentPrepared == 0 && last)
{
// TODO discard content for backward compatibility with 9.3 releases
// TODO review if it is still needed in 9.4 or can we just throw.
content.clear();
}
else
throw new BadMessageException(INTERNAL_SERVER_ERROR_500, "Content for no content response");
}
else
throw new BadMessageException(INTERNAL_SERVER_ERROR_500, "Content for no content response");
}
}
// Else if we are HTTP/1.1 and the content length is unknown and we are either persistent

View File

@ -169,6 +169,7 @@ public class HttpParser
private Utf8StringBuilder _uri = new Utf8StringBuilder(INITIAL_URI_LENGTH); // Tune?
private EndOfContent _endOfContent;
private boolean _hasContentLength;
private boolean _hasTransferEncoding;
private long _contentLength = -1;
private long _contentPosition;
private int _chunkLength;
@ -955,6 +956,9 @@ public class HttpParser
switch (_header)
{
case CONTENT_LENGTH:
if (_hasTransferEncoding && complianceViolation(TRANSFER_ENCODING_WITH_CONTENT_LENGTH))
throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Transfer-Encoding and Content-Length");
if (_hasContentLength)
{
if (complianceViolation(MULTIPLE_CONTENT_LENGTHS))
@ -964,9 +968,6 @@ public class HttpParser
}
_hasContentLength = true;
if (_endOfContent == EndOfContent.CHUNKED_CONTENT && complianceViolation(TRANSFER_ENCODING_WITH_CONTENT_LENGTH))
throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Bad Content-Length");
if (_endOfContent != EndOfContent.CHUNKED_CONTENT)
{
_contentLength = convertContentLength(_valueString);
@ -978,9 +979,15 @@ public class HttpParser
break;
case TRANSFER_ENCODING:
_hasTransferEncoding = true;
if (_hasContentLength && complianceViolation(TRANSFER_ENCODING_WITH_CONTENT_LENGTH))
throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Transfer-Encoding and Content-Length");
// we encountered another Transfer-Encoding header, but chunked was already set
if (_endOfContent == EndOfContent.CHUNKED_CONTENT)
throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Bad Transfer-Encoding, chunked not last");
if (HttpHeaderValue.CHUNKED.is(_valueString))
{
_endOfContent = EndOfContent.CHUNKED_CONTENT;
@ -989,15 +996,26 @@ public class HttpParser
else
{
List<String> values = new QuotedCSV(_valueString).getValues();
if (!values.isEmpty() && HttpHeaderValue.CHUNKED.is(values.get(values.size() - 1)))
int chunked = -1;
int len = values.size();
for (int i = 0; i < len; i++)
{
_endOfContent = EndOfContent.CHUNKED_CONTENT;
_contentLength = -1;
if (HttpHeaderValue.CHUNKED.is(values.get(i)))
{
if (chunked != -1)
throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Bad Transfer-Encoding, multiple chunked tokens");
chunked = i;
// declared chunked
_endOfContent = EndOfContent.CHUNKED_CONTENT;
_contentLength = -1;
}
// we have a non-chunked token after a declared chunked token
else if (_endOfContent == EndOfContent.CHUNKED_CONTENT)
{
throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Bad Transfer-Encoding, chunked not last");
}
}
else if (values.stream().anyMatch(HttpHeaderValue.CHUNKED::is))
throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Bad chunking");
}
break;
case HOST:
@ -1139,6 +1157,17 @@ public class HttpParser
return _handler.messageComplete();
}
// We found Transfer-Encoding headers, but none declared the 'chunked' token
if (_hasTransferEncoding && _endOfContent != EndOfContent.CHUNKED_CONTENT)
{
if (_responseHandler == null || _endOfContent != EndOfContent.EOF_CONTENT)
{
// Transfer-Encoding chunked not specified
// https://tools.ietf.org/html/rfc7230#section-3.3.1
throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Bad Transfer-Encoding, chunked not last");
}
}
// Was there a required host header?
if (!_host && _version == HttpVersion.HTTP_1_1 && _requestHandler != null)
{
@ -1818,6 +1847,7 @@ public class HttpParser
_endOfContent = EndOfContent.UNKNOWN_CONTENT;
_contentLength = -1;
_hasContentLength = false;
_hasTransferEncoding = false;
_contentPosition = 0;
_responseStatus = 0;
_contentChunk = null;

View File

@ -1050,7 +1050,7 @@ public class HttpParserTest
assertEquals("GET", _methodOrVersion);
assertEquals("/chunk", _uriOrStatus);
assertEquals("HTTP/1.0", _versionOrReason);
assertThat(_bad, containsString("Bad chunking"));
assertThat(_bad, containsString("Bad Transfer-Encoding"));
}
@Test

View File

@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<artifactId>jetty-project</artifactId>
<groupId>org.eclipse.jetty</groupId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>infinispan-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>infinispan-common</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>infinispan-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>infinispan-embedded-query</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>infinispan-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>infinispan-embedded</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>infinispan-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>infinispan-remote-query</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>infinispan-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>infinispan-remote</artifactId>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<artifactId>jetty-project</artifactId>
<groupId>org.eclipse.jetty</groupId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-io</artifactId>

View File

@ -25,12 +25,14 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.ToIntFunction;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
import javax.net.ssl.SSLEngineResult.Status;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSession;
import org.eclipse.jetty.io.AbstractConnection;
import org.eclipse.jetty.io.AbstractEndPoint;
@ -308,10 +310,37 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
return state == HandshakeState.SUCCEEDED || state == HandshakeState.FAILED;
}
private int getApplicationBufferSize()
{
return getBufferSize(SSLSession::getApplicationBufferSize);
}
private int getPacketBufferSize()
{
return getBufferSize(SSLSession::getPacketBufferSize);
}
private int getBufferSize(ToIntFunction<SSLSession> bufferSizeFn)
{
SSLSession hsSession = _sslEngine.getHandshakeSession();
SSLSession session = _sslEngine.getSession();
int size = bufferSizeFn.applyAsInt(session);
if (hsSession == null || hsSession == session)
return size;
int hsSize = bufferSizeFn.applyAsInt(hsSession);
return Math.max(hsSize, size);
}
private void acquireEncryptedInput()
{
if (_encryptedInput == null)
_encryptedInput = _bufferPool.acquire(_sslEngine.getSession().getPacketBufferSize(), _encryptedDirectBuffers);
_encryptedInput = _bufferPool.acquire(getPacketBufferSize(), _encryptedDirectBuffers);
}
private void acquireEncryptedOutput()
{
if (_encryptedOutput == null)
_encryptedOutput = _bufferPool.acquire(getPacketBufferSize(), _encryptedDirectBuffers);
}
@Override
@ -409,6 +438,24 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
connection instanceof AbstractConnection ? ((AbstractConnection)connection).toConnectionString() : connection);
}
private void releaseEncryptedInputBuffer()
{
if (_encryptedInput != null && !_encryptedInput.hasRemaining())
{
_bufferPool.release(_encryptedInput);
_encryptedInput = null;
}
}
protected void releaseDecryptedInputBuffer()
{
if (_decryptedInput != null && !_decryptedInput.hasRemaining())
{
_bufferPool.release(_decryptedInput);
_decryptedInput = null;
}
}
private void releaseEncryptedOutputBuffer()
{
if (!Thread.holdsLock(_decryptedEndPoint))
@ -544,9 +591,12 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
{
if (connection instanceof AbstractConnection)
{
AbstractConnection a = (AbstractConnection)connection;
if (a.getInputBufferSize() < _sslEngine.getSession().getApplicationBufferSize())
a.setInputBufferSize(_sslEngine.getSession().getApplicationBufferSize());
// This is an optimization to avoid that upper layer connections use small
// buffers and we need to copy decrypted data rather than decrypting in place.
AbstractConnection c = (AbstractConnection)connection;
int appBufferSize = getApplicationBufferSize();
if (c.getInputBufferSize() < appBufferSize)
c.setInputBufferSize(appBufferSize);
}
super.setConnection(connection);
}
@ -613,12 +663,13 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
// can we use the passed buffer if it is big enough
ByteBuffer appIn;
int appBufferSize = getApplicationBufferSize();
if (_decryptedInput == null)
{
if (BufferUtil.space(buffer) > _sslEngine.getSession().getApplicationBufferSize())
if (BufferUtil.space(buffer) > appBufferSize)
appIn = buffer;
else
appIn = _decryptedInput = _bufferPool.acquire(_sslEngine.getSession().getApplicationBufferSize(), _decryptedDirectBuffers);
appIn = _decryptedInput = _bufferPool.acquire(appBufferSize, _decryptedDirectBuffers);
}
else
{
@ -698,8 +749,21 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
}
return filled = netFilled;
case BUFFER_OVERFLOW:
// It's possible that SSLSession.applicationBufferSize has been expanded
// by the SSLEngine implementation. Unwrapping a large encrypted buffer
// causes BUFFER_OVERFLOW because the (old) applicationBufferSize is
// too small. Release the decrypted input buffer so it will be re-acquired
// with the larger capacity.
// See also system property "jsse.SSLEngine.acceptLargeFragments".
if (BufferUtil.isEmpty(_decryptedInput) && appBufferSize < getApplicationBufferSize())
{
releaseDecryptedInputBuffer();
continue;
}
throw new IllegalStateException("Unexpected unwrap result " + unwrap);
case OK:
{
if (unwrapResult.getHandshakeStatus() == HandshakeStatus.FINISHED)
handshakeSucceeded();
@ -717,7 +781,6 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
}
break;
}
default:
throw new IllegalStateException("Unexpected unwrap result " + unwrap);
@ -737,17 +800,8 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
}
finally
{
if (_encryptedInput != null && !_encryptedInput.hasRemaining())
{
_bufferPool.release(_encryptedInput);
_encryptedInput = null;
}
if (_decryptedInput != null && !_decryptedInput.hasRemaining())
{
_bufferPool.release(_decryptedInput);
_decryptedInput = null;
}
releaseEncryptedInputBuffer();
releaseDecryptedInputBuffer();
if (_flushState == FlushState.WAIT_FOR_FILL)
{
@ -974,8 +1028,8 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
throw new IllegalStateException("Unexpected HandshakeStatus " + status);
}
if (_encryptedOutput == null)
_encryptedOutput = _bufferPool.acquire(_sslEngine.getSession().getPacketBufferSize(), _encryptedDirectBuffers);
int packetBufferSize = getPacketBufferSize();
acquireEncryptedOutput();
if (_handshake.compareAndSet(HandshakeState.INITIAL, HandshakeState.HANDSHAKE))
{
@ -983,7 +1037,8 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
LOG.debug("flush starting handshake {}", SslConnection.this);
}
// We call sslEngine.wrap to try to take bytes from appOut buffers and encrypt them into the _netOut buffer
// We call sslEngine.wrap to try to take bytes from appOuts
// buffers and encrypt them into the _encryptedOutput buffer.
BufferUtil.compact(_encryptedOutput);
int pos = BufferUtil.flipToFill(_encryptedOutput);
SSLEngineResult wrapResult;
@ -1032,7 +1087,18 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
case BUFFER_OVERFLOW:
if (!flushed)
return result = false;
continue;
// It's possible that SSLSession.packetBufferSize has been expanded
// by the SSLEngine implementation. Wrapping a large application buffer
// causes BUFFER_OVERFLOW because the (old) packetBufferSize is
// too small. Release the encrypted output buffer so that it will
// be re-acquired with the larger capacity.
// See also system property "jsse.SSLEngine.acceptLargeFragments".
if (packetBufferSize < getPacketBufferSize())
{
releaseEncryptedOutputBuffer();
continue;
}
throw new IllegalStateException("Unexpected wrap result " + wrap);
case OK:
if (wrapResult.getHandshakeStatus() == HandshakeStatus.FINISHED)

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-jaas</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-jmx</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-jndi</artifactId>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-jspc-maven-plugin</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-maven-plugin</artifactId>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty.memcached</groupId>
<artifactId>memcached-parent</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<artifactId>jetty-project</artifactId>
<groupId>org.eclipse.jetty</groupId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-nosql</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -246,6 +246,16 @@ public class OpenIdAuthenticator extends LoginAuthenticator
try
{
if (request.isRequestedSessionIdFromURL())
{
if (LOG.isDebugEnabled())
LOG.debug("Session ID should be cookie for OpenID authentication to work");
int redirectCode = (baseRequest.getHttpVersion().getVersion() < HttpVersion.HTTP_1_1.getVersion() ? HttpServletResponse.SC_MOVED_TEMPORARILY : HttpServletResponse.SC_SEE_OTHER);
baseResponse.sendRedirect(redirectCode, URIUtil.addPaths(request.getContextPath(), _errorPage));
return Authentication.SEND_FAILURE;
}
// Handle a request for authentication.
if (isJSecurityCheck(uri))
{
@ -288,7 +298,7 @@ public class OpenIdAuthenticator extends LoginAuthenticator
response.setContentLength(0);
int redirectCode = (baseRequest.getHttpVersion().getVersion() < HttpVersion.HTTP_1_1.getVersion() ? HttpServletResponse.SC_MOVED_TEMPORARILY : HttpServletResponse.SC_SEE_OTHER);
baseResponse.sendRedirect(redirectCode, response.encodeRedirectURL(nuri));
baseResponse.sendRedirect(redirectCode, nuri);
return openIdAuth;
}
}
@ -308,7 +318,7 @@ public class OpenIdAuthenticator extends LoginAuthenticator
if (LOG.isDebugEnabled())
LOG.debug("auth failed {}", _errorPage);
int redirectCode = (baseRequest.getHttpVersion().getVersion() < HttpVersion.HTTP_1_1.getVersion() ? HttpServletResponse.SC_MOVED_TEMPORARILY : HttpServletResponse.SC_SEE_OTHER);
baseResponse.sendRedirect(redirectCode, response.encodeRedirectURL(URIUtil.addPaths(request.getContextPath(), _errorPage)));
baseResponse.sendRedirect(redirectCode, URIUtil.addPaths(request.getContextPath(), _errorPage));
}
return Authentication.SEND_FAILURE;
@ -399,7 +409,7 @@ public class OpenIdAuthenticator extends LoginAuthenticator
if (LOG.isDebugEnabled())
LOG.debug("challenge {}->{}", session.getId(), challengeUri);
int redirectCode = (baseRequest.getHttpVersion().getVersion() < HttpVersion.HTTP_1_1.getVersion() ? HttpServletResponse.SC_MOVED_TEMPORARILY : HttpServletResponse.SC_SEE_OTHER);
baseResponse.sendRedirect(redirectCode, response.encodeRedirectURL(challengeUri));
baseResponse.sendRedirect(redirectCode, challengeUri);
return Authentication.SEND_CONTINUE;
}

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-osgi-alpn</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-osgi-boot-jsp</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-osgi-boot</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-httpservice</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>test-jetty-osgi-context</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>test-jetty-osgi-server</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>jetty-osgi-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-plus</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-proxy</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.eclipse.jetty</groupId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-rewrite</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-runner</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-security</artifactId>

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-server</artifactId>

View File

@ -507,7 +507,9 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
}
// RFC 7230, section 3.3.
if (!_request.isHead() && !_response.isContentComplete(_response.getHttpOutput().getWritten()))
if (!_request.isHead() &&
_response.getStatus() != HttpStatus.NOT_MODIFIED_304 &&
!_response.isContentComplete(_response.getHttpOutput().getWritten()))
{
if (isCommitted())
abort(new IOException("insufficient content written"));

View File

@ -188,13 +188,16 @@ public class InetAccessHandler extends HandlerWrapper
protected boolean isAllowed(InetAddress addr, Request baseRequest, HttpServletRequest request)
{
String name = baseRequest.getHttpChannel().getConnector().getName();
boolean filterAppliesToConnector = _names.test(name);
boolean allowedByAddr = _addrs.test(addr);
if (LOG.isDebugEnabled())
{
Boolean allowedByName = _names.isIncludedAndNotExcluded(name);
Boolean allowedByAddr = _addrs.isIncludedAndNotExcluded(addr);
LOG.debug("{} allowedByName={} allowedByAddr={} for {}/{}", this, allowedByName, allowedByAddr, addr, request);
LOG.debug("name = {}/{} addr={}/{} appliesToConnector={} allowedByAddr={}",
name, _names, addr, _addrs, filterAppliesToConnector, allowedByAddr);
}
return _names.test(name) && _addrs.test(addr);
if (!filterAppliesToConnector)
return true;
return allowedByAddr;
}
@Override

View File

@ -113,7 +113,7 @@ public class DumpHandler extends AbstractHandler.ErrorDispatchHandler
writer.write("<pre>\nlocal=" + request.getLocalAddr() + ":" + request.getLocalPort() + "\n</pre>\n");
writer.write("<pre>\nremote=" + request.getRemoteAddr() + ":" + request.getRemotePort() + "\n</pre>\n");
writer.write("<h3>Header:</h3><pre>");
writer.write(request.getMethod() + " " + request.getRequestURI() + " " + request.getProtocol() + "\n");
writer.write(String.format("%4s %s %s\n", request.getMethod(), request.getRequestURI(), request.getProtocol()));
Enumeration<String> headers = request.getHeaderNames();
while (headers.hasMoreElements())
{

View File

@ -30,10 +30,13 @@ import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -54,6 +57,9 @@ import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
@ -263,43 +269,172 @@ public class HttpConnectionTest
}
}
static final int CHUNKED = -1;
static final int DQUOTED_CHUNKED = -2;
static final int BAD_CHUNKED = -3;
static final int UNKNOWN_TE = -4;
public static Stream<Arguments> http11ContentLengthAndChunkedData()
{
return Stream.of(
Arguments.of(new int[]{CHUNKED, 8}),
Arguments.of(new int[]{8, CHUNKED}),
Arguments.of(new int[]{8, CHUNKED, 8}),
Arguments.of(new int[]{DQUOTED_CHUNKED, 8}),
Arguments.of(new int[]{8, DQUOTED_CHUNKED}),
Arguments.of(new int[]{8, DQUOTED_CHUNKED, 8}),
Arguments.of(new int[]{BAD_CHUNKED, 8}),
Arguments.of(new int[]{8, BAD_CHUNKED}),
Arguments.of(new int[]{8, BAD_CHUNKED, 8}),
Arguments.of(new int[]{UNKNOWN_TE, 8}),
Arguments.of(new int[]{8, UNKNOWN_TE}),
Arguments.of(new int[]{8, UNKNOWN_TE, 8}),
Arguments.of(new int[]{8, UNKNOWN_TE, CHUNKED, DQUOTED_CHUNKED, BAD_CHUNKED, 8})
);
}
/**
* More then 1 Content-Length is a bad requests per HTTP rfcs.
*/
@Test
public void testHttp11ContentLengthAndChunk() throws Exception
@ParameterizedTest
@MethodSource("http11ContentLengthAndChunkedData")
public void testHttp11ContentLengthAndChunk(int[] contentLengths) throws Exception
{
HttpParser.LOG.info("badMessage: 400 Bad messages EXPECTED...");
int[][] contentLengths = {
{-1, 8},
{8, -1},
{8, -1, 8},
};
for (int x = 0; x < contentLengths.length; x++)
StringBuilder request = new StringBuilder();
request.append("POST / HTTP/1.1\r\n");
request.append("Host: local\r\n");
for (int n = 0; n < contentLengths.length; n++)
{
StringBuilder request = new StringBuilder();
request.append("POST /?id=").append(Integer.toString(x)).append(" HTTP/1.1\r\n");
request.append("Host: local\r\n");
int[] clen = contentLengths[x];
for (int n = 0; n < clen.length; n++)
switch (contentLengths[n])
{
if (clen[n] == -1)
case CHUNKED:
request.append("Transfer-Encoding: chunked\r\n");
else
request.append("Content-Length: ").append(Integer.toString(clen[n])).append("\r\n");
break;
case DQUOTED_CHUNKED:
request.append("Transfer-Encoding: \"chunked\"\r\n");
break;
case BAD_CHUNKED:
request.append("Transfer-Encoding: 'chunked'\r\n");
break;
case UNKNOWN_TE:
request.append("Transfer-Encoding: bogus\r\n");
break;
default:
request.append("Content-Length: ").append(contentLengths[n]).append("\r\n");
break;
}
request.append("Content-Type: text/plain\r\n");
request.append("Connection: close\r\n");
request.append("\r\n");
request.append("8;\r\n"); // chunk header
request.append("abcdefgh"); // actual content of 8 bytes
request.append("\r\n0;\r\n"); // last chunk
String rawResponse = connector.getResponse(request.toString());
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
assertThat("Response.status", response.getStatus(), is(HttpServletResponse.SC_BAD_REQUEST));
}
request.append("Content-Type: text/plain\r\n");
request.append("\r\n");
request.append("8;\r\n"); // chunk header
request.append("abcdefgh"); // actual content of 8 bytes
request.append("\r\n0;\r\n\r\n"); // last chunk
String rawResponse = connector.getResponse(request.toString());
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
assertThat("Response.status", response.getStatus(), is(HttpServletResponse.SC_BAD_REQUEST));
}
/**
* Examples of valid Chunked behaviors.
*/
public static Stream<Arguments> http11TransferEncodingChunked()
{
return Stream.of(
Arguments.of(Arrays.asList("chunked, ")), // results in 1 entry
Arguments.of(Arrays.asList(", chunked")),
// invalid tokens with chunked as last
// no conflicts, chunked token is specified and is last, will result in chunked
Arguments.of(Arrays.asList("bogus, chunked")),
Arguments.of(Arrays.asList("'chunked', chunked")), // apostrophe characters with and without
Arguments.of(Arrays.asList("identity, chunked")), // identity was removed in RFC2616 errata and has been dropped in RFC7230
// multiple headers
Arguments.of(Arrays.asList("identity", "chunked")), // 2 separate headers
Arguments.of(Arrays.asList("", "chunked")) // 2 separate headers
);
}
/**
* Test Chunked Transfer-Encoding behavior indicated by
* https://tools.ietf.org/html/rfc7230#section-3.3.1
*/
@ParameterizedTest
@MethodSource("http11TransferEncodingChunked")
public void testHttp11TransferEncodingChunked(List<String> tokens) throws Exception
{
StringBuilder request = new StringBuilder();
request.append("POST / HTTP/1.1\r\n");
request.append("Host: local\r\n");
tokens.forEach((token) -> request.append("Transfer-Encoding: ").append(token).append("\r\n"));
request.append("Content-Type: text/plain\r\n");
request.append("\r\n");
request.append("8;\r\n"); // chunk header
request.append("abcdefgh"); // actual content of 8 bytes
request.append("\r\n0;\r\n\r\n"); // last chunk
System.out.println(request.toString());
String rawResponse = connector.getResponse(request.toString());
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
assertThat("Response.status (" + response.getReason() + ")", response.getStatus(), is(HttpServletResponse.SC_OK));
}
public static Stream<Arguments> http11TransferEncodingInvalidChunked()
{
return Stream.of(
// == Results in 400 Bad Request
Arguments.of(Arrays.asList("bogus", "identity")), // 2 separate headers
Arguments.of(Arrays.asList("bad")),
Arguments.of(Arrays.asList("identity")), // identity was removed in RFC2616 errata and has been dropped in RFC7230
Arguments.of(Arrays.asList("'chunked'")), // apostrophe characters
Arguments.of(Arrays.asList("`chunked`")), // backtick "quote" characters
Arguments.of(Arrays.asList("[chunked]")), // bracketed (seen as mistake in several REST libraries)
Arguments.of(Arrays.asList("{chunked}")), // json'd (seen as mistake in several REST libraries)
Arguments.of(Arrays.asList("\u201Cchunked\u201D")), // opening and closing (fancy) double quotes characters
// invalid tokens with chunked not as last
Arguments.of(Arrays.asList("chunked, bogus")),
Arguments.of(Arrays.asList("chunked, 'chunked'")),
Arguments.of(Arrays.asList("chunked, identity")),
Arguments.of(Arrays.asList("chunked, identity, chunked")), // duplicate chunked
Arguments.of(Arrays.asList("chunked", "identity")), // 2 separate header lines
// multiple chunked tokens present
Arguments.of(Arrays.asList("chunked", "identity", "chunked")), // 3 separate header lines
Arguments.of(Arrays.asList("chunked", "chunked")), // 2 separate header lines
Arguments.of(Arrays.asList("chunked, chunked")) // on same line
);
}
/**
* Test bad Transfer-Encoding behavior as indicated by
* https://tools.ietf.org/html/rfc7230#section-3.3.1
*/
@ParameterizedTest
@MethodSource("http11TransferEncodingInvalidChunked")
public void testHttp11TransferEncodingInvalidChunked(List<String> tokens) throws Exception
{
HttpParser.LOG.info("badMessage: 400 Bad messages EXPECTED...");
StringBuilder request = new StringBuilder();
request.append("POST / HTTP/1.1\r\n");
request.append("Host: local\r\n");
tokens.forEach((token) -> request.append("Transfer-Encoding: ").append(token).append("\r\n"));
request.append("Content-Type: text/plain\r\n");
request.append("\r\n");
request.append("8;\r\n"); // chunk header
request.append("abcdefgh"); // actual content of 8 bytes
request.append("\r\n0;\r\n\r\n"); // last chunk
System.out.println(request.toString());
String rawResponse = connector.getResponse(request.toString());
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
assertThat("Response.status", response.getStatus(), is(HttpServletResponse.SC_BAD_REQUEST));
}
@Test
@ -541,11 +676,10 @@ public class HttpConnectionTest
"Host: localhost\r\n" +
"Transfer-Encoding: chunked\r\n" +
"Content-Type: text/plain\r\n" +
"Connection: close\r\n" +
"\r\n" +
"A\r\n" +
"0123456789\r\n" +
"0\r\n");
"0\r\n\r\n");
int offset = 0;
offset = checkContains(response, offset, "HTTP/1.1 200");

View File

@ -24,6 +24,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.server.handler.AbstractHandler;
@ -432,6 +433,21 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest
}
}
@ParameterizedTest
@MethodSource("httpVersions")
public void testSetContentLengthAnd304Status(HttpVersion httpVersion) throws Exception
{
server.setHandler(new SetContentLength304Handler());
server.start();
HttpTester.Response response = executeRequest(httpVersion);
assertThat("response code", response.getStatus(), is(304));
assertThat(response, containsHeaderValue("content-length", "32768"));
byte[] content = response.getContentBytes();
assertThat(content.length, is(0));
assertFalse(response.isEarlyEOF());
}
@ParameterizedTest
@MethodSource("httpVersions")
public void testSetContentLengthFlushAndWriteInsufficientBytes(HttpVersion httpVersion) throws Exception
@ -519,6 +535,21 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest
}
}
private class SetContentLength304Handler extends AbstractHandler
{
private SetContentLength304Handler()
{
}
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
response.setContentLength(32768);
response.setStatus(HttpStatus.NOT_MODIFIED_304);
}
}
private class SetContentLengthAndWriteThatAmountOfBytesHandler extends ThrowExceptionOnDemandHandler
{
private SetContentLengthAndWriteThatAmountOfBytesHandler(boolean throwException)

View File

@ -35,6 +35,7 @@ import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ -107,6 +108,33 @@ public class PartialRFC2616Test
}
}
@Test
public void test3_3_2()
{
try
{
String get = connector.getResponse("GET /R1 HTTP/1.0\n" + "Host: localhost\n" + "\n");
checkContains(get, 0, "HTTP/1.1 200", "GET");
checkContains(get, 0, "Content-Type: text/html", "GET _content");
checkContains(get, 0, "<html>", "GET body");
int cli = get.indexOf("Content-Length");
String contentLength = get.substring(cli,get.indexOf("\r",cli));
String head = connector.getResponse("HEAD /R1 HTTP/1.0\n" + "Host: localhost\n" + "\n");
checkContains(head, 0, "HTTP/1.1 200", "HEAD");
checkContains(head, 0, "Content-Type: text/html", "HEAD _content");
assertEquals(-1, head.indexOf("<html>"), "HEAD no body");
checkContains(head, 0, contentLength, "3.3.2 HEAD");
}
catch (Exception e)
{
e.printStackTrace();
assertTrue(false);
}
}
@Test
public void test3_6_a() throws Exception
{
@ -321,12 +349,10 @@ public class PartialRFC2616Test
"\n");
offset = 0;
response = endp.getResponse();
offset = checkContains(response, offset, "HTTP/1.1 200 OK", "2. identity") + 10;
offset = checkContains(response, offset, "/R1", "2. identity") + 3;
offset = checkContains(response, offset, "HTTP/1.1 400 ", "2. identity") + 10;
offset = 0;
response = endp.getResponse();
offset = checkContains(response, offset, "HTTP/1.1 200 OK", "2. identity") + 10;
offset = checkContains(response, offset, "/R2", "2. identity") + 3;
assertThat("There should be no next response as first one closed connection", response, is(nullValue()));
}
@Test
@ -358,7 +384,7 @@ public class PartialRFC2616Test
"\n" +
"abcdef");
response = endp.getResponse();
offset = checkContains(response, offset, "HTTP/1.1 400 Bad", "3. ignore c-l") + 1;
offset = checkContains(response, offset, "HTTP/1.1 400 ", "3. ignore c-l") + 1;
checkNotContained(response, offset, "/R2", "3. _content-length");
}

View File

@ -21,7 +21,9 @@ package org.eclipse.jetty.server.handler;
import java.io.IOException;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@ -45,17 +47,20 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
public class InetAccessHandlerTest
{
private static Server _server;
private static ServerConnector _connector;
private static ServerConnector _connector1;
private static ServerConnector _connector2;
private static InetAccessHandler _handler;
@BeforeAll
public static void setUp() throws Exception
{
_server = new Server();
_connector = new ServerConnector(_server);
_connector.setName("http");
_connector1 = new ServerConnector(_server);
_connector1.setName("http_connector1");
_connector2 = new ServerConnector(_server);
_connector2.setName("http_connector2");
_server.setConnectors(new Connector[]
{_connector});
{_connector1, _connector2});
_handler = new InetAccessHandler();
_handler.setHandler(new AbstractHandler()
@ -113,7 +118,21 @@ public class InetAccessHandlerTest
}
}
try (Socket socket = new Socket("127.0.0.1", _connector.getLocalPort());)
List<String> codePerConnector = new ArrayList<>();
for (String nextCode : code.split(";", -1))
{
if (nextCode.length() > 0)
{
codePerConnector.add(nextCode);
}
}
testConnector(_connector1.getLocalPort(), include, exclude, includeConnectors, excludeConnectors, codePerConnector.get(0));
testConnector(_connector2.getLocalPort(), include, exclude, includeConnectors, excludeConnectors, codePerConnector.get(1));
}
private void testConnector(int port, String include, String exclude, String includeConnectors, String excludeConnectors, String code) throws IOException {
try (Socket socket = new Socket("127.0.0.1", port);)
{
socket.setSoTimeout(5000);
@ -136,39 +155,68 @@ public class InetAccessHandlerTest
}
}
/**
* Data for this test.
* @return Format of data: include;exclude;includeConnectors;excludeConnectors;assertionStatusCodePerConnector
*/
public static Stream<Arguments> data()
{
Object[][] data = new Object[][]
{
// Empty lists
{"", "", "", "", "200"},
// Empty lists 1
{"", "", "", "", "200;200"},
// test simple filters
{"127.0.0.1", "", "", "", "200"},
{"127.0.0.1-127.0.0.254", "", "", "", "200"},
{"192.0.0.1", "", "", "", "403"},
{"192.0.0.1-192.0.0.254", "", "", "", "403"},
{"127.0.0.1", "", "", "", "200;200"},
{"127.0.0.1-127.0.0.254", "", "", "", "200;200"},
{"192.0.0.1", "", "", "", "403;403"},
{"192.0.0.1-192.0.0.254", "", "", "", "403;403"},
// test connector name filters
{"127.0.0.1", "", "http", "", "200"},
{"127.0.0.1-127.0.0.254", "", "http", "", "200"},
{"192.0.0.1", "", "http", "", "403"},
{"192.0.0.1-192.0.0.254", "", "http", "", "403"},
// test includeConnector
{"127.0.0.1", "", "http_connector1", "", "200;200"},
{"127.0.0.1-127.0.0.254", "", "http_connector1", "", "200;200"},
{"192.0.0.1", "", "http_connector1", "", "403;200"},
{"192.0.0.1-192.0.0.254", "", "http_connector1", "", "403;200"},
{"192.0.0.1", "", "http_connector2", "", "200;403"},
{"192.0.0.1-192.0.0.254", "", "http_connector2", "", "200;403"},
{"127.0.0.1", "", "nothttp", "", "403"},
{"127.0.0.1-127.0.0.254", "", "nothttp", "", "403"},
{"192.0.0.1", "", "nothttp", "", "403"},
{"192.0.0.1-192.0.0.254", "", "nothttp", "", "403"},
// test includeConnector names where none of them match
{"127.0.0.1", "", "nothttp", "", "200;200"},
{"127.0.0.1-127.0.0.254", "", "nothttp", "", "200;200"},
{"192.0.0.1", "", "nothttp", "", "200;200"},
{"192.0.0.1-192.0.0.254", "", "nothttp", "", "200;200"},
{"127.0.0.1", "", "", "http", "403"},
{"127.0.0.1-127.0.0.254", "", "", "http", "403"},
{"192.0.0.1", "", "", "http", "403"},
{"192.0.0.1-192.0.0.254", "", "", "http", "403"},
// text excludeConnector
{"127.0.0.1", "", "", "http_connector1", "200;200"},
{"127.0.0.1-127.0.0.254", "", "", "http_connector1", "200;200"},
{"192.0.0.1", "", "", "http_connector1", "200;403"},
{"192.0.0.1-192.0.0.254", "", "", "http_connector1", "200;403"},
{"192.0.0.1", "", "", "http_connector2", "403;200"},
{"192.0.0.1-192.0.0.254", "", "", "http_connector2", "403;200"},
{"127.0.0.1", "", "", "nothttp", "200"},
{"127.0.0.1-127.0.0.254", "", "", "nothttp", "200"},
{"192.0.0.1", "", "", "nothttp", "403"},
{"192.0.0.1-192.0.0.254", "", "", "nothttp", "403"},
// test excludeConnector where none of them match.
{"127.0.0.1", "", "", "nothttp", "200;200"},
{"127.0.0.1-127.0.0.254", "", "", "nothttp", "200;200"},
{"192.0.0.1", "", "", "nothttp", "403;403"},
{"192.0.0.1-192.0.0.254", "", "", "nothttp", "403;403"},
// both connectors are excluded
{"127.0.0.1", "", "", "http_connector1;http_connector2", "200;200"},
{"127.0.0.1-127.0.0.254", "", "", "http_connector1;http_connector2", "200;200"},
{"192.0.0.1", "", "", "http_connector1;http_connector2", "200;200"},
{"192.0.0.1-192.0.0.254", "", "", "http_connector1;http_connector2", "200;200"},
// both connectors are included
{"127.0.0.1", "", "http_connector1;http_connector2", "", "200;200"},
{"127.0.0.1-127.0.0.254", "", "http_connector1;http_connector2", "", "200;200"},
{"192.0.0.1", "", "http_connector1;http_connector2", "", "403;403"},
{"192.0.0.1-192.0.0.254", "", "http_connector1;http_connector2", "", "403;403"},
// exclude takes precedence over include
{"127.0.0.1", "", "http_connector1;http_connector2", "http_connector1;http_connector2", "200;200"},
{"127.0.0.1-127.0.0.254", "", "http_connector1;http_connector2", "http_connector1;http_connector2", "200;200"},
{"192.0.0.1", "", "http_connector1;http_connector2", "http_connector1;http_connector2", "200;200"},
{"192.0.0.1-192.0.0.254", "", "http_connector1;http_connector2", "http_connector1;http_connector2", "200;200"},
};
return Arrays.asList(data).stream().map(Arguments::of);
}

View File

@ -3,7 +3,7 @@
<parent>
<artifactId>jetty-project</artifactId>
<groupId>org.eclipse.jetty</groupId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-servlet</artifactId>

View File

@ -3,7 +3,7 @@
<parent>
<artifactId>jetty-project</artifactId>
<groupId>org.eclipse.jetty</groupId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-servlets</artifactId>

View File

@ -25,6 +25,7 @@ import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
@ -251,7 +252,11 @@ public class CGI extends HttpServlet
String parameterName = names.nextElement();
parameterMap.addValues(parameterName, req.getParameterValues(parameterName));
}
bodyFormEncoded = UrlEncoded.encode(parameterMap, Charset.forName(req.getCharacterEncoding()), true);
String characterEncoding = req.getCharacterEncoding();
Charset charset = characterEncoding != null
? Charset.forName(characterEncoding) : StandardCharsets.UTF_8;
bodyFormEncoded = UrlEncoded.encode(parameterMap, charset, true);
}
EnvList env = new EnvList(_env);

View File

@ -121,7 +121,7 @@ import org.eclipse.jetty.util.thread.Scheduler;
* </dl>
* <p>
* This filter should be configured for {@link DispatcherType#REQUEST} and {@link DispatcherType#ASYNC} and with
* <code>&lt;async-supported&gt;true&lt;/async-supported&gt;</code>.
* {@code <async-supported>true</async-supported>}.
* </p>
*/
@ManagedObject("limits exposure to abuse from request flooding, whether malicious, or as a result of a misconfigured client")
@ -146,7 +146,6 @@ public class DoSFilter implements Filter
private static final long __DEFAULT_MAX_REQUEST_MS_INIT_PARAM = 30000L;
private static final long __DEFAULT_MAX_IDLE_TRACKER_MS_INIT_PARAM = 30000L;
static final String NAME = "name";
static final String MANAGED_ATTR_INIT_PARAM = "managedAttr";
static final String MAX_REQUESTS_PER_S_INIT_PARAM = "maxRequestsPerSec";
static final String DELAY_MS_INIT_PARAM = "delayMs";
@ -390,8 +389,7 @@ public class DoSFilter implements Filter
response.addHeader("DoSFilter", "throttled");
AsyncContext asyncContext = request.startAsync();
request.setAttribute(_suspended, Boolean.TRUE);
if (throttleMs > 0)
asyncContext.setTimeout(throttleMs);
asyncContext.setTimeout(throttleMs);
asyncContext.addListener(_listeners[priority]);
_queues[priority].add(asyncContext);
if (LOG.isDebugEnabled())
@ -467,14 +465,7 @@ public class DoSFilter implements Filter
protected void doFilterChain(FilterChain chain, final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException
{
final Thread thread = Thread.currentThread();
Runnable requestTimeout = new Runnable()
{
@Override
public void run()
{
closeConnection(request, response, thread);
}
};
Runnable requestTimeout = () -> closeConnection(request, response, thread);
Scheduler.Task task = _scheduler.schedule(requestTimeout, getMaxRequestMs(), TimeUnit.MILLISECONDS);
try
{
@ -539,7 +530,7 @@ public class DoSFilter implements Filter
* @param tracker the rate tracker for this request
* @return the priority for this request
*/
protected int getPriority(HttpServletRequest request, RateTracker tracker)
private int getPriority(HttpServletRequest request, RateTracker tracker)
{
if (extractUserId(request) != null)
return USER_AUTH;
@ -556,7 +547,7 @@ public class DoSFilter implements Filter
return USER_AUTH;
}
public void schedule(RateTracker tracker)
private void schedule(RateTracker tracker)
{
_scheduler.schedule(tracker, getMaxIdleTrackerMs(), TimeUnit.MILLISECONDS);
}
@ -577,7 +568,7 @@ public class DoSFilter implements Filter
* @param request the current request
* @return the request rate tracker for the current connection
*/
public RateTracker getRateTracker(ServletRequest request)
RateTracker getRateTracker(ServletRequest request)
{
HttpSession session = ((HttpServletRequest)request).getSession(false);
@ -629,7 +620,7 @@ public class DoSFilter implements Filter
return tracker;
}
public void addToRateTracker(RateTracker tracker)
private void addToRateTracker(RateTracker tracker)
{
_rateTrackers.put(tracker.getId(), tracker);
}
@ -1268,7 +1259,7 @@ public class DoSFilter implements Filter
LOG.debug("Tracker removed: {}", getId());
}
protected void addToRateTrackers(DoSFilter filter, RateTracker tracker)
private void addToRateTrackers(DoSFilter filter, RateTracker tracker)
{
if (filter == null)
return;
@ -1308,7 +1299,7 @@ public class DoSFilter implements Filter
}
}
class FixedRateTracker extends RateTracker
private static class FixedRateTracker extends RateTracker
{
public FixedRateTracker(ServletContext context, String filterName, String id, int type, int numRecentRequestsTracked)
{
@ -1337,15 +1328,15 @@ public class DoSFilter implements Filter
}
}
private class DoSTimeoutAsyncListener implements AsyncListener
private static class DoSTimeoutAsyncListener implements AsyncListener
{
@Override
public void onStartAsync(AsyncEvent event) throws IOException
public void onStartAsync(AsyncEvent event)
{
}
@Override
public void onComplete(AsyncEvent event) throws IOException
public void onComplete(AsyncEvent event)
{
}
@ -1356,7 +1347,7 @@ public class DoSFilter implements Filter
}
@Override
public void onError(AsyncEvent event) throws IOException
public void onError(AsyncEvent event)
{
}
}

View File

@ -2,7 +2,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.22-SNAPSHOT</version>
<version>9.4.23-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-spring</artifactId>

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