Version in base suite: 9.4.50-4+deb12u3 Base version: jetty9_9.4.50-4+deb12u3 Target version: jetty9_9.4.57-0+deb12u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/j/jetty9/jetty9_9.4.50-4+deb12u3.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/j/jetty9/jetty9_9.4.57-0+deb12u1.dsc CODE_OF_CONDUCT.md | 93 CONTRIBUTING.md | 8 Jenkinsfile | 5 KEYS.txt | 2 NOTICE.txt | 2 README.md | 2 VERSION.txt | 1502 +- aggregates/jetty-all-compact3/pom.xml | 4 aggregates/jetty-all/pom.xml | 2 aggregates/jetty-all/src/main/resources/META-INF/MANIFEST.MF | 2 aggregates/jetty-websocket-all/pom.xml | 2 apache-jsp/pom.xml | 2 apache-jsp/src/main/config/modules/apache-jsp.mod | 2 apache-jstl/pom.xml | 2 apache-jstl/src/main/config/modules/apache-jstl.mod | 2 build-resources/pom.xml | 2 debian/changelog | 155 debian/control | 7 debian/copyright | 2 debian/jetty9.install | 1 debian/jetty9.timer | 9 debian/patches/01-maven-bundle-plugin-version.patch | 2 debian/patches/02-import-alpn-api.patch | 8 debian/patches/04-weksocket-1.1-compatibility.patch | 10 debian/patches/06-ignore-jetty-documentation.patch | 2 debian/patches/07-assembly-plugin-configuration.patch | 4 debian/patches/08-ignore-jetty-test-policy.patch | 2 debian/patches/09-tweak-distribution.patch | 18 debian/patches/CVE-2023-26048.patch | 433 debian/patches/CVE-2023-26049.patch | 367 debian/patches/CVE-2023-36478.patch | 7110 ---------- debian/patches/CVE-2023-36479.patch | 47 debian/patches/CVE-2023-40167.patch | 268 debian/patches/CVE-2023-41900.patch | 781 - debian/patches/CVE-2023-44487.patch | 622 debian/patches/CVE-2024-22201.patch | 138 debian/patches/series | 8 debian/patches/servlet-api.patch | 2 debian/source/lintian-overrides | 2 examples/async-rest/async-rest-jar/pom.xml | 2 examples/async-rest/async-rest-webapp/pom.xml | 2 examples/async-rest/async-rest-webapp/src/main/webapp/WEB-INF/jetty-web.xml | 2 examples/async-rest/pom.xml | 2 examples/embedded/pom.xml | 2 examples/embedded/src/main/resources/exampleserver.xml | 2 examples/embedded/src/main/resources/fileserver.xml | 2 examples/embedded/src/main/resources/jetty-otherserver.xml | 2 examples/pom.xml | 2 jetty-alpn/jetty-alpn-client/pom.xml | 2 jetty-alpn/jetty-alpn-conscrypt-client/pom.xml | 2 jetty-alpn/jetty-alpn-conscrypt-server/pom.xml | 2 jetty-alpn/jetty-alpn-java-client/pom.xml | 2 jetty-alpn/jetty-alpn-java-server/pom.xml | 2 jetty-alpn/jetty-alpn-openjdk8-client/pom.xml | 2 jetty-alpn/jetty-alpn-openjdk8-server/pom.xml | 2 jetty-alpn/jetty-alpn-server/pom.xml | 2 jetty-alpn/jetty-alpn-server/src/main/config/etc/jetty-alpn.xml | 2 jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-available-false.mod | 2 jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-available-true.mod | 2 jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn.mod | 2 jetty-alpn/pom.xml | 2 jetty-annotations/pom.xml | 2 jetty-annotations/src/main/config/etc/jetty-annotations.xml | 2 jetty-annotations/src/main/config/modules/annotations.mod | 2 jetty-ant/pom.xml | 2 jetty-bom/pom.xml | 138 jetty-cdi/pom.xml | 12 jetty-cdi/src/main/config/etc/cdi/jetty-cdi.xml | 2 jetty-cdi/src/main/config/etc/cdi/jetty-cdi2.xml | 2 jetty-cdi/src/main/config/etc/cdi/jetty-web-cdi2.xml | 2 jetty-cdi/src/main/config/modules/cdi-decorate.mod | 2 jetty-cdi/src/main/config/modules/cdi-spi.mod | 2 jetty-cdi/src/main/config/modules/cdi.mod | 2 jetty-cdi/src/main/config/modules/cdi2.mod | 2 jetty-client/pom.xml | 12 jetty-client/src/main/config/modules/client.mod | 2 jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java | 5 jetty-continuation/pom.xml | 2 jetty-deploy/pom.xml | 2 jetty-deploy/src/main/config/etc/jetty-decorate.xml | 2 jetty-deploy/src/main/config/etc/jetty-deploy.xml | 2 jetty-deploy/src/main/config/etc/jetty-web-decorate.xml | 2 jetty-deploy/src/main/config/modules/decorate.mod | 2 jetty-deploy/src/main/config/modules/deploy.mod | 2 jetty-deploy/src/main/config/modules/global-webapp-common.d/global-webapp-common.xml | 2 jetty-deploy/src/main/config/modules/global-webapp-common.d/webapp-common.xml | 2 jetty-deploy/src/main/config/modules/global-webapp-common.mod | 2 jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentTempDirTest.java | 10 jetty-deploy/src/test/resources/binding-test-contexts-1.xml | 2 jetty-deploy/src/test/resources/context-binding-test-1.xml | 2 jetty-deploy/src/test/resources/jetty-deploy-wars.xml | 2 jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml | 2 jetty-deploy/src/test/resources/jetty-http.xml | 2 jetty-deploy/src/test/resources/jetty.xml | 5 jetty-deploy/src/test/resources/webapps/badapp/badapp.xml | 2 jetty-deploy/src/test/resources/webapps/foo.xml | 2 jetty-distribution/pom.xml | 2 jetty-distribution/src/main/resources/README.TXT | 2 jetty-distribution/src/main/resources/demo-base/webapps/ROOT/index.html | 12 jetty-distribution/src/main/resources/demo-base/webapps/example-moved.xml | 2 jetty-distribution/src/main/resources/start.ini | 2 jetty-fcgi/fcgi-client/pom.xml | 2 jetty-fcgi/fcgi-server/pom.xml | 2 jetty-fcgi/fcgi-server/src/main/config/modules/fcgi.mod | 4 jetty-fcgi/pom.xml | 2 jetty-gcloud/jetty-gcloud-session-manager/pom.xml | 2 jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/etc/sessions/gcloud/session-store.xml | 2 jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud-datastore.mod | 2 jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud.mod | 2 jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/session-store-gcloud.mod | 2 jetty-gcloud/pom.xml | 4 jetty-hazelcast/pom.xml | 2 jetty-hazelcast/src/main/config/etc/sessions/hazelcast/default.xml | 2 jetty-hazelcast/src/main/config/etc/sessions/hazelcast/remote.xml | 2 jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod | 2 jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod | 2 jetty-home/pom.xml | 2 jetty-home/src/main/resources/etc/jetty-setuid.xml | 2 jetty-home/src/main/resources/etc/jetty-started.xml | 2 jetty-home/src/main/resources/etc/jetty-stop.xml | 2 jetty-home/src/main/resources/modules/conscrypt.mod | 2 jetty-home/src/main/resources/modules/conscrypt/conscrypt.xml | 2 jetty-home/src/main/resources/modules/hawtio.mod | 2 jetty-home/src/main/resources/modules/hawtio/hawtio.xml | 2 jetty-home/src/main/resources/modules/jamon.mod | 2 jetty-home/src/main/resources/modules/jamon/jamon.xml | 2 jetty-home/src/main/resources/modules/jminix.mod | 2 jetty-home/src/main/resources/modules/jminix/jminix.xml | 2 jetty-home/src/main/resources/modules/jolokia.mod | 2 jetty-home/src/main/resources/modules/jolokia/jolokia.xml | 2 jetty-home/src/main/resources/modules/jsp.mod | 2 jetty-home/src/main/resources/modules/jstl.mod | 2 jetty-home/src/main/resources/modules/setuid.mod | 2 jetty-home/src/main/resources/modules/stop.mod | 2 jetty-http-spi/pom.xml | 18 jetty-http/pom.xml | 2 jetty-http/src/main/java/org/eclipse/jetty/http/CookieCompliance.java | 1 jetty-http/src/main/java/org/eclipse/jetty/http/HttpCompliance.java | 5 jetty-http/src/main/java/org/eclipse/jetty/http/HttpComplianceSection.java | 1 jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java | 48 jetty-http/src/main/java/org/eclipse/jetty/http/HttpTokens.java | 44 jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java | 127 jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormInputStream.java | 24 jetty-http/src/main/java/org/eclipse/jetty/http/compression/EncodingException.java | 27 jetty-http/src/main/java/org/eclipse/jetty/http/compression/Huffman.java | 357 jetty-http/src/main/java/org/eclipse/jetty/http/compression/HuffmanDecoder.java | 143 jetty-http/src/main/java/org/eclipse/jetty/http/compression/HuffmanEncoder.java | 142 jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitIntegerDecoder.java | 113 jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitIntegerEncoder.java | 96 jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitStringDecoder.java | 138 jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitStringEncoder.java | 82 jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java | 83 jetty-http/src/test/java/org/eclipse/jetty/http/HttpURITest.java | 37 jetty-http/src/test/java/org/eclipse/jetty/http/HuffmanTest.java | 168 jetty-http/src/test/java/org/eclipse/jetty/http/NBitIntegerTest.java | 207 jetty-http2/http2-alpn-tests/pom.xml | 2 jetty-http2/http2-client/pom.xml | 7 jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java | 81 jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java | 83 jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientSession.java | 15 jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/DynamicTableTest.java | 190 jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/HTTP2Test.java | 179 jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/IdleTimeoutTest.java | 56 jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PrefaceTest.java | 13 jetty-http2/http2-common/pom.xml | 2 jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Connection.java | 22 jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java | 179 jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java | 6 jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/HeadersFrame.java | 3 jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/Generator.java | 26 jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ContinuationBodyParser.java | 36 jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockFragments.java | 33 jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockParser.java | 5 jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeadersBodyParser.java | 41 jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java | 60 jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PushPromiseBodyParser.java | 17 jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ResetBodyParser.java | 8 jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ServerParser.java | 39 jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/SettingsBodyParser.java | 29 jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/UnknownBodyParser.java | 1 jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java | 61 jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/DataGenerateParseTest.java | 13 jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java | 38 jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/GoAwayGenerateParseTest.java | 13 jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersGenerateParseTest.java | 13 jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/MaxFrameSizeParseTest.java | 9 jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PingGenerateParseTest.java | 19 jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PriorityGenerateParseTest.java | 13 jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PushPromiseGenerateParseTest.java | 13 jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ResetGenerateParseTest.java | 13 jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java | 61 jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/UnknownParseTest.java | 13 jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/WindowUpdateGenerateParseTest.java | 13 jetty-http2/http2-hpack/pom.xml | 2 jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java | 61 jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java | 174 jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackEncoder.java | 178 jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackException.java | 5 jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackFieldPreEncoder.java | 14 jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/Huffman.java | 551 jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java | 42 jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/NBitInteger.java | 151 jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackContextTest.java | 33 jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java | 50 jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackEncoderTest.java | 30 jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackPerfTest.java | 29 jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackTest.java | 49 jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java | 87 jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/NBitIntegerTest.java | 204 jetty-http2/http2-http-client-transport/pom.xml | 2 jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2.java | 21 jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java | 5 jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/GoAwayTest.java | 151 jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java | 8 jetty-http2/http2-server/pom.xml | 2 jetty-http2/http2-server/src/main/config/etc/jetty-http2.xml | 2 jetty-http2/http2-server/src/main/config/etc/jetty-http2c.xml | 2 jetty-http2/http2-server/src/main/config/modules/http2.mod | 2 jetty-http2/http2-server/src/main/config/modules/http2c.mod | 2 jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java | 87 jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java | 8 jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerSession.java | 20 jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/CloseTest.java | 19 jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2CServerTest.java | 13 jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2ServerTest.java | 45 jetty-http2/pom.xml | 2 jetty-infinispan/infinispan-common/pom.xml | 26 jetty-infinispan/infinispan-common/src/main/config/etc/sessions/infinispan/infinispan-common.xml | 2 jetty-infinispan/infinispan-embedded-query/pom.xml | 13 jetty-infinispan/infinispan-embedded-query/src/main/config-template/etc/sessions/infinispan/infinispan-embedded-query.xml | 2 jetty-infinispan/infinispan-embedded/pom.xml | 12 jetty-infinispan/infinispan-embedded/src/main/config-template/etc/sessions/infinispan/infinispan-embedded.xml | 2 jetty-infinispan/infinispan-remote-query/pom.xml | 23 jetty-infinispan/infinispan-remote-query/src/main/config-template/etc/sessions/infinispan/infinispan-remote-query.xml | 2 jetty-infinispan/infinispan-remote/pom.xml | 12 jetty-infinispan/infinispan-remote/src/main/config-template/etc/sessions/infinispan/infinispan-remote.xml | 2 jetty-infinispan/pom.xml | 2 jetty-io/pom.xml | 2 jetty-jaas/pom.xml | 4 jetty-jaas/src/main/config/etc/jetty-jaas.xml | 2 jetty-jaas/src/main/config/modules/jaas.mod | 2 jetty-jaspi/pom.xml | 5 jetty-jaspi/src/main/config/modules/jaspi.mod | 2 jetty-jmh/pom.xml | 20 jetty-jmx/pom.xml | 2 jetty-jmx/src/main/config/etc/jetty-jmx-remote.xml | 2 jetty-jmx/src/main/config/etc/jetty-jmx.xml | 2 jetty-jmx/src/main/config/modules/jmx-remote.mod | 2 jetty-jmx/src/main/config/modules/jmx.mod | 2 jetty-jndi/pom.xml | 2 jetty-jndi/src/main/jndi-config/modules/jndi.mod | 2 jetty-jndi/src/main/jndi-config/modules/mail.mod | 2 jetty-jspc-maven-plugin/pom.xml | 2 jetty-jspc-maven-plugin/src/main/java/org/eclipse/jetty/jspc/plugin/JspcMojo.java | 2 jetty-jspc-maven-plugin/src/site/site.xml | 4 jetty-maven-plugin/pom.xml | 11 jetty-maven-plugin/src/it/jetty-cdi-run-forked/src/main/jetty/jetty-context.xml | 2 jetty-maven-plugin/src/it/jetty-cdi-run-forked/src/main/jetty/jetty.xml | 2 jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/src/config/jetty.xml | 2 jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/src/config/jetty.xml | 2 jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml | 2 jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/modules/testmod.mod | 2 jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/src/config/jetty.xml | 2 jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/context.xml | 2 jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/jetty.xml | 2 jetty-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyWebApp/src/config/context.xml | 2 jetty-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyWebApp/src/config/jetty.xml | 2 jetty-maven-plugin/src/it/jetty-run-mojo-jsp/src/config/jetty.xml | 2 jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/webapp-war/src/config/jetty.xml | 2 jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/src/config/jetty.xml | 2 jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/src/config/jetty.xml | 2 jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/config/jetty.xml | 2 jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/config/jetty.xml | 3 jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/jettyconf/context.xml | 3 jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEffectiveWebXml.java | 2 jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunDistro.java | 2 jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunForkedMojo.java | 2 jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunMojo.java | 2 jetty-maven-plugin/src/main/resources/jetty-maven.xml | 2 jetty-maven-plugin/src/main/resources/maven.mod | 2 jetty-maven-plugin/src/main/resources/maven.xml | 2 jetty-maven-plugin/src/site/site.xml | 4 jetty-memcached/jetty-memcached-sessions/pom.xml | 2 jetty-memcached/jetty-memcached-sessions/src/main/config/etc/sessions/session-data-cache/xmemcached.xml | 2 jetty-memcached/jetty-memcached-sessions/src/main/config/modules/sessions/session-data-cache/xmemcached.mod | 2 jetty-memcached/pom.xml | 2 jetty-nosql/pom.xml | 2 jetty-nosql/src/main/config/etc/sessions/mongo/session-store-by-address.xml | 2 jetty-nosql/src/main/config/etc/sessions/mongo/session-store-by-uri.xml | 2 jetty-nosql/src/main/config/modules/session-store-mongo.mod | 2 jetty-nosql/src/main/config/modules/sessions/mongo/address.mod | 2 jetty-nosql/src/main/config/modules/sessions/mongo/uri.mod | 2 jetty-openid/pom.xml | 2 jetty-openid/src/main/config/etc/jetty-openid.xml | 2 jetty-openid/src/main/config/modules/openid.mod | 2 jetty-openid/src/main/config/modules/openid/openid-baseloginservice.xml | 2 jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java | 12 jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java | 19 jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdAuthenticationTest.java | 187 jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdProvider.java | 250 jetty-osgi/jetty-osgi-alpn/pom.xml | 2 jetty-osgi/jetty-osgi-boot-jsp/pom.xml | 2 jetty-osgi/jetty-osgi-boot-warurl/pom.xml | 2 jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-deploy.xml | 2 jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-http.xml | 2 jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml | 4 jetty-osgi/jetty-osgi-boot/pom.xml | 2 jetty-osgi/jetty-osgi-httpservice/contexts/httpservice.xml | 2 jetty-osgi/jetty-osgi-httpservice/pom.xml | 2 jetty-osgi/pom.xml | 23 jetty-osgi/test-jetty-osgi-context/pom.xml | 2 jetty-osgi/test-jetty-osgi-context/src/main/context/acme.xml | 2 jetty-osgi/test-jetty-osgi-fragment/pom.xml | 2 jetty-osgi/test-jetty-osgi-server/pom.xml | 2 jetty-osgi/test-jetty-osgi-webapp-resources/pom.xml | 2 jetty-osgi/test-jetty-osgi-webapp/pom.xml | 2 jetty-osgi/test-jetty-osgi/pom.xml | 10 jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-alpn.xml | 2 jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-deploy.xml | 2 jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-context-as-service.xml | 2 jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-webapp-as-service.xml | 2 jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-annotations.xml | 2 jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-javax-websocket.xml | 2 jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-jsp.xml | 2 jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-resources.xml | 2 jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-websocket.xml | 2 jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http.xml | 2 jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http2-jdk9.xml | 2 jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http2.xml | 2 jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-https.xml | 2 jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-ssl.xml | 2 jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-testrealm.xml | 2 jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty.xml | 4 jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestOSGiUtil.java | 8 jetty-plus/pom.xml | 2 jetty-plus/src/main/plus-config/etc/jetty-plus.xml | 2 jetty-plus/src/main/plus-config/modules/plus.mod | 2 jetty-plus/src/main/plus-config/modules/transactions.mod | 2 jetty-proxy/pom.xml | 2 jetty-proxy/src/main/config/etc/jetty-proxy.xml | 2 jetty-proxy/src/main/config/modules/proxy.mod | 2 jetty-quickstart/pom.xml | 2 jetty-quickstart/src/main/config/etc/example-quickstart.xml | 2 jetty-quickstart/src/main/config/modules/quickstart.mod | 2 jetty-rewrite/pom.xml | 2 jetty-rewrite/src/main/config/etc/jetty-rewrite-customizer.xml | 2 jetty-rewrite/src/main/config/etc/jetty-rewrite.xml | 2 jetty-rewrite/src/main/config/etc/rewrite-compactpath.xml | 2 jetty-rewrite/src/main/config/modules/rewrite-compactpath.mod | 2 jetty-rewrite/src/main/config/modules/rewrite-customizer.mod | 2 jetty-rewrite/src/main/config/modules/rewrite.mod | 2 jetty-rewrite/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml | 2 jetty-runner/pom.xml | 4 jetty-runner/src/main/java/org/eclipse/jetty/runner/Runner.java | 2 jetty-security/pom.xml | 2 jetty-security/src/main/config/modules/security.mod | 2 jetty-server/pom.xml | 7 jetty-server/src/main/config/etc/home-base-warning.xml | 2 jetty-server/src/main/config/etc/jetty-acceptratelimit.xml | 2 jetty-server/src/main/config/etc/jetty-bytebufferpool-logarithmic.xml | 2 jetty-server/src/main/config/etc/jetty-bytebufferpool.xml | 2 jetty-server/src/main/config/etc/jetty-connectionlimit.xml | 2 jetty-server/src/main/config/etc/jetty-customrequestlog.xml | 2 jetty-server/src/main/config/etc/jetty-debug.xml | 2 jetty-server/src/main/config/etc/jetty-debuglog.xml | 2 jetty-server/src/main/config/etc/jetty-gzip.xml | 2 jetty-server/src/main/config/etc/jetty-http-forwarded.xml | 2 jetty-server/src/main/config/etc/jetty-http.xml | 2 jetty-server/src/main/config/etc/jetty-https.xml | 2 jetty-server/src/main/config/etc/jetty-ipaccess.xml | 2 jetty-server/src/main/config/etc/jetty-lowresources.xml | 2 jetty-server/src/main/config/etc/jetty-proxy-protocol-ssl.xml | 2 jetty-server/src/main/config/etc/jetty-proxy-protocol.xml | 2 jetty-server/src/main/config/etc/jetty-requestlog.xml | 2 jetty-server/src/main/config/etc/jetty-ssl-context-reload.xml | 2 jetty-server/src/main/config/etc/jetty-ssl-context.xml | 4 jetty-server/src/main/config/etc/jetty-ssl.xml | 2 jetty-server/src/main/config/etc/jetty-stats.xml | 2 jetty-server/src/main/config/etc/jetty-threadlimit.xml | 2 jetty-server/src/main/config/etc/jetty-threadpool.xml | 2 jetty-server/src/main/config/etc/jetty.xml | 4 jetty-server/src/main/config/etc/sessions/file/session-store.xml | 2 jetty-server/src/main/config/etc/sessions/id-manager.xml | 2 jetty-server/src/main/config/etc/sessions/jdbc/datasource.xml | 2 jetty-server/src/main/config/etc/sessions/jdbc/driver.xml | 2 jetty-server/src/main/config/etc/sessions/jdbc/session-store.xml | 2 jetty-server/src/main/config/etc/sessions/session-cache-hash.xml | 2 jetty-server/src/main/config/etc/sessions/session-cache-null.xml | 2 jetty-server/src/main/config/etc/sessions/session-data-cache/session-caching-store.xml | 2 jetty-server/src/main/config/modules/acceptratelimit.mod | 2 jetty-server/src/main/config/modules/bytebufferpool-logarithmic.mod | 2 jetty-server/src/main/config/modules/bytebufferpool.mod | 2 jetty-server/src/main/config/modules/connectionlimit.mod | 2 jetty-server/src/main/config/modules/continuation.mod | 2 jetty-server/src/main/config/modules/customrequestlog.mod | 2 jetty-server/src/main/config/modules/debug.mod | 2 jetty-server/src/main/config/modules/debuglog.mod | 2 jetty-server/src/main/config/modules/ext.mod | 2 jetty-server/src/main/config/modules/gzip.mod | 2 jetty-server/src/main/config/modules/home-base-warning.mod | 2 jetty-server/src/main/config/modules/http-forwarded.mod | 2 jetty-server/src/main/config/modules/http.mod | 2 jetty-server/src/main/config/modules/https.mod | 2 jetty-server/src/main/config/modules/inetaccess.mod | 2 jetty-server/src/main/config/modules/inetaccess/jetty-inetaccess.xml | 2 jetty-server/src/main/config/modules/ipaccess.mod | 2 jetty-server/src/main/config/modules/jdbc.mod | 2 jetty-server/src/main/config/modules/jvm.mod | 2 jetty-server/src/main/config/modules/logback-access.mod | 2 jetty-server/src/main/config/modules/logback-access/jetty-logback-access.xml | 2 jetty-server/src/main/config/modules/lowresources.mod | 2 jetty-server/src/main/config/modules/proxy-protocol-ssl.mod | 2 jetty-server/src/main/config/modules/proxy-protocol.mod | 2 jetty-server/src/main/config/modules/requestlog.mod | 2 jetty-server/src/main/config/modules/resources.mod | 2 jetty-server/src/main/config/modules/server.mod | 2 jetty-server/src/main/config/modules/session-cache-hash.mod | 2 jetty-server/src/main/config/modules/session-cache-null.mod | 2 jetty-server/src/main/config/modules/session-store-cache.mod | 2 jetty-server/src/main/config/modules/session-store-file.mod | 2 jetty-server/src/main/config/modules/session-store-jdbc.mod | 2 jetty-server/src/main/config/modules/sessions.mod | 2 jetty-server/src/main/config/modules/sessions/jdbc/datasource.mod | 2 jetty-server/src/main/config/modules/sessions/jdbc/driver.mod | 2 jetty-server/src/main/config/modules/ssl-reload.mod | 2 jetty-server/src/main/config/modules/ssl.mod | 4 jetty-server/src/main/config/modules/stats.mod | 2 jetty-server/src/main/config/modules/threadpool.mod | 2 jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java | 102 jetty-server/src/main/java/org/eclipse/jetty/server/HomeBaseWarning.java | 2 jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java | 28 jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java | 14 jetty-server/src/main/java/org/eclipse/jetty/server/Request.java | 27 jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java | 4 jetty-server/src/main/java/org/eclipse/jetty/server/handler/SizeLimitHandler.java | 22 jetty-server/src/main/java/org/eclipse/jetty/server/handler/ThreadLimitHandler.java | 72 jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java | 45 jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterLenientTest.java | 3 jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterTest.java | 90 jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java | 2 jetty-server/src/test/java/org/eclipse/jetty/server/handler/SizeLimitHandlerTest.java | 8 jetty-server/src/test/java/org/eclipse/jetty/server/handler/ThreadLimitHandlerTest.java | 25 jetty-servlet/pom.xml | 2 jetty-servlet/src/main/config/modules/servlet.mod | 2 jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java | 30 jetty-servlet/src/test/java/org/eclipse/jetty/servlet/MultiPartServletTest.java | 208 jetty-servlets/pom.xml | 2 jetty-servlets/src/main/config/modules/servlets.mod | 2 jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CGI.java | 3 jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java | 246 jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PushCacheFilter.java | 7 jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PushSessionCacheFilter.java | 9 jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AbstractDoSFilterTest.java | 56 jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterTest.java | 2 jetty-spring/pom.xml | 4 jetty-spring/src/main/config/modules/spring.mod | 2 jetty-start/pom.xml | 2 jetty-start/src/main/java/org/eclipse/jetty/start/ModuleGraphWriter.java | 2 jetty-start/src/main/resources/org/eclipse/jetty/start/usage.txt | 4 jetty-start/src/test/java/org/eclipse/jetty/start/fileinits/MavenLocalRepoFileInitializerTest.java | 2 jetty-start/src/test/resources/bogus.xml | 1 jetty-start/src/test/resources/dist-home/modules/main.mod | 2 jetty-unixsocket/pom.xml | 2 jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-forwarded.xml | 2 jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-http.xml | 2 jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-http2c.xml | 2 jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-proxy-protocol.xml | 2 jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-secure.xml | 2 jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket.xml | 2 jetty-unixsocket/src/main/config-template/modules/unixsocket-forwarded.mod | 2 jetty-unixsocket/src/main/config-template/modules/unixsocket-http.mod | 2 jetty-unixsocket/src/main/config-template/modules/unixsocket-http2c.mod | 2 jetty-unixsocket/src/main/config-template/modules/unixsocket-prefix.mod | 2 jetty-unixsocket/src/main/config-template/modules/unixsocket-proxy-protocol.mod | 2 jetty-unixsocket/src/main/config-template/modules/unixsocket-secure.mod | 2 jetty-util-ajax/pom.xml | 2 jetty-util/pom.xml | 2 jetty-util/src/main/config/etc/console-capture.xml | 2 jetty-util/src/main/config/modules/console-capture.mod | 2 jetty-util/src/main/config/modules/jcl-slf4j.mod | 2 jetty-util/src/main/config/modules/jul-impl.mod | 2 jetty-util/src/main/config/modules/jul-slf4j.mod | 2 jetty-util/src/main/config/modules/log4j-impl.mod | 2 jetty-util/src/main/config/modules/log4j2-api.mod | 2 jetty-util/src/main/config/modules/log4j2-impl.mod | 2 jetty-util/src/main/config/modules/log4j2-slf4j.mod | 2 jetty-util/src/main/config/modules/logback-impl.mod | 2 jetty-util/src/main/config/modules/logging-jetty.mod | 2 jetty-util/src/main/config/modules/logging-jul.mod | 2 jetty-util/src/main/config/modules/logging-log4j.mod | 2 jetty-util/src/main/config/modules/logging-log4j2.mod | 2 jetty-util/src/main/config/modules/logging-logback.mod | 2 jetty-util/src/main/config/modules/logging-slf4j.mod | 2 jetty-util/src/main/config/modules/slf4j-api.mod | 2 jetty-util/src/main/config/modules/slf4j-jul.mod | 2 jetty-util/src/main/config/modules/slf4j-log4j.mod | 2 jetty-util/src/main/config/modules/slf4j-log4j2.mod | 2 jetty-util/src/main/config/modules/slf4j-logback.mod | 2 jetty-util/src/main/config/modules/slf4j-simple-impl.mod | 2 jetty-util/src/main/java/org/eclipse/jetty/util/CharsetStringBuilder.java | 312 jetty-util/src/main/java/org/eclipse/jetty/util/IteratingCallback.java | 311 jetty-util/src/main/java/org/eclipse/jetty/util/Jetty.java | 2 jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java | 23 jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java | 73 jetty-util/src/main/java/org/eclipse/jetty/util/URIUtil.java | 4 jetty-util/src/test/java/org/eclipse/jetty/util/IteratingCallbackTest.java | 84 jetty-util/src/test/java/org/eclipse/jetty/util/LazyListTest.java | 4 jetty-util/src/test/java/org/eclipse/jetty/util/RolloverFileOutputStreamTest.java | 2 jetty-util/src/test/java/org/eclipse/jetty/util/URIUtilTest.java | 39 jetty-util/src/test/java/org/eclipse/jetty/util/Utf8LineParserTest.java | 2 jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java | 2 jetty-webapp/pom.xml | 2 jetty-webapp/src/main/config/etc/jetty-webapp.xml | 2 jetty-webapp/src/main/config/modules/webapp.mod | 2 jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java | 4 jetty-websocket/javax-websocket-client-impl/pom.xml | 2 jetty-websocket/javax-websocket-client-impl/src/test/resources/examples/jetty-websocket-httpclient.xml | 2 jetty-websocket/javax-websocket-server-impl/pom.xml | 2 jetty-websocket/javax-websocket-server-impl/src/main/config/modules/websocket.mod | 2 jetty-websocket/jetty-websocket-tests/pom.xml | 2 jetty-websocket/pom.xml | 2 jetty-websocket/websocket-api/pom.xml | 2 jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionFactory.java | 7 jetty-websocket/websocket-client/pom.xml | 2 jetty-websocket/websocket-client/src/test/resources/httpclient/simple/jetty-websocket-httpclient.xml | 2 jetty-websocket/websocket-common/pom.xml | 2 jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/WebSocketRemoteEndpointTest.java | 2 jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/FragmentExtensionTest.java | 2 jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/FrameFlusherTest.java | 2 jetty-websocket/websocket-server/pom.xml | 2 jetty-websocket/websocket-servlet/pom.xml | 2 jetty-xml/pom.xml | 2 jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java | 55 jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlParser.java | 35 jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java | 57 jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlParserTest.java | 37 jetty-xml/src/test/resources/org/eclipse/jetty/xml/configureWithAttr.xml | 2 jetty-xml/src/test/resources/org/eclipse/jetty/xml/configureWithElements.xml | 2 jetty-xml/src/test/resources/org/eclipse/jetty/xml/mortbay.xml | 3 pom.xml | 226 scripts/release-jetty.sh | 11 tests/pom.xml | 2 tests/test-continuation/pom.xml | 2 tests/test-distribution/pom.xml | 18 tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java | 5 tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java | 7 tests/test-distribution/src/test/resources/badapp/badapp_throwonunavailable_false.xml | 2 tests/test-distribution/src/test/resources/badapp/badapp_throwonunavailable_true.xml | 2 tests/test-distribution/src/test/resources/test-realm.xml | 2 tests/test-http-client-transport/pom.xml | 2 tests/test-integration/pom.xml | 2 tests/test-integration/src/test/java/org/eclipse/jetty/test/AllowedResourceAliasCheckerTest.java | 88 tests/test-integration/src/test/java/org/eclipse/jetty/test/DeploymentErrorInitializer.java | 2 tests/test-integration/src/test/java/org/eclipse/jetty/test/HttpInputInterceptorTest.java | 14 tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithAliasesTest.java | 30 tests/test-integration/src/test/resources/DefaultHandler.xml | 2 tests/test-integration/src/test/resources/NIOHttp.xml | 2 tests/test-integration/src/test/resources/NIOHttps.xml | 2 tests/test-integration/src/test/resources/RFC2616Base.xml | 6 tests/test-integration/src/test/resources/RFC2616_Filters.xml | 2 tests/test-integration/src/test/resources/RFC2616_Redirects.xml | 2 tests/test-integration/src/test/resources/docroots/deployerror/badapp-unavailable-false.xml | 2 tests/test-integration/src/test/resources/docroots/deployerror/badapp.xml | 2 tests/test-integration/src/test/resources/ssl.xml | 2 tests/test-integration/src/test/resources/webapp-contexts/RFC2616/rfc2616-webapp.xml | 2 tests/test-jmx/jmx-webapp-it/pom.xml | 2 tests/test-jmx/jmx-webapp/pom.xml | 2 tests/test-jmx/pom.xml | 2 tests/test-loginservice/pom.xml | 7 tests/test-quickstart/pom.xml | 2 tests/test-quickstart/src/test/resources/test-jndi.xml | 2 tests/test-quickstart/src/test/resources/test-spec.xml | 2 tests/test-quickstart/src/test/resources/test.xml | 2 tests/test-sessions/pom.xml | 2 tests/test-sessions/test-file-sessions/pom.xml | 2 tests/test-sessions/test-gcloud-sessions/pom.xml | 7 tests/test-sessions/test-hazelcast-sessions/pom.xml | 2 tests/test-sessions/test-infinispan-sessions/pom.xml | 7 tests/test-sessions/test-jdbc-sessions/pom.xml | 7 tests/test-sessions/test-memcached-sessions/pom.xml | 7 tests/test-sessions/test-mongodb-sessions/pom.xml | 7 tests/test-sessions/test-sessions-common/pom.xml | 2 tests/test-webapps/pom.xml | 2 tests/test-webapps/test-cdi-common-webapp/pom.xml | 2 tests/test-webapps/test-felix-webapp/pom.xml | 2 tests/test-webapps/test-http2-webapp/pom.xml | 2 tests/test-webapps/test-jaas-webapp/pom.xml | 2 tests/test-webapps/test-jaas-webapp/src/main/config/demo-base/webapps/test-jaas.xml | 2 tests/test-webapps/test-jaas-webapp/src/main/webapp/WEB-INF/jetty-web.xml | 2 tests/test-webapps/test-jaas-webapp/src/main/webapp/index.html | 6 tests/test-webapps/test-jetty-webapp/pom.xml | 3 tests/test-webapps/test-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml | 2 tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/etc/demo-rewrite-rules.xml | 2 tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/etc/test-realm.xml | 2 tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/webapps/test.xml | 2 tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/jetty-web.xml | 2 tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml | 12 tests/test-webapps/test-jetty-webapp/src/main/webapp/index.html | 6 tests/test-webapps/test-jetty-webapp/src/main/webapp/remote.html | 6 tests/test-webapps/test-jndi-webapp/pom.xml | 2 tests/test-webapps/test-jndi-webapp/src/main/templates/jetty-test-jndi-header.xml | 2 tests/test-webapps/test-jndi-webapp/src/main/templates/plugin-context-header.xml | 2 tests/test-webapps/test-jndi-webapp/src/main/webapp/WEB-INF/jetty-env.xml | 2 tests/test-webapps/test-jndi-webapp/src/main/webapp/WEB-INF/jetty-web.xml | 2 tests/test-webapps/test-jndi-webapp/src/main/webapp/index.html | 4 tests/test-webapps/test-mock-resources/pom.xml | 2 tests/test-webapps/test-owb-cdi-webapp/pom.xml | 2 tests/test-webapps/test-owb-cdi-webapp/src/main/webapp/WEB-INF/jetty-env.xml | 2 tests/test-webapps/test-owb-cdi-webapp/src/main/webapp/WEB-INF/jetty-web-owb.xml | 4 tests/test-webapps/test-proxy-webapp/pom.xml | 2 tests/test-webapps/test-proxy-webapp/src/main/webapp/WEB-INF/jetty-web.xml | 2 tests/test-webapps/test-proxy-webapp/src/main/webapp/WEB-INF/web.xml | 6 tests/test-webapps/test-proxy-webapp/src/test/java/org/eclipse/jetty/ProxyWebAppTest.java | 5 tests/test-webapps/test-servlet-spec/pom.xml | 2 tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml | 2 tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml | 2 tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/templates/annotations-context-header.xml | 2 tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/templates/plugin-context-header.xml | 2 tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/WEB-INF/jetty-env.xml | 2 tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/WEB-INF/jetty-web.xml | 2 tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/index.html | 6 tests/test-webapps/test-servlet-spec/test-spec-webapp/src/test/jetty-plugin-env.xml | 2 tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml | 2 tests/test-webapps/test-simple-session-webapp/pom.xml | 2 tests/test-webapps/test-simple-webapp/pom.xml | 2 tests/test-webapps/test-webapp-rfc2616/pom.xml | 2 tests/test-webapps/test-websocket-client-provided-webapp/pom.xml | 2 tests/test-webapps/test-websocket-client-provided-webapp/src/main/resources/jetty-websocket-httpclient.xml | 2 tests/test-webapps/test-websocket-client-webapp/pom.xml | 2 tests/test-webapps/test-weld-cdi-webapp/pom.xml | 2 tests/test-webapps/test-weld-cdi-webapp/src/main/webapp/WEB-INF/jetty-env.xml | 2 631 files changed, 7458 insertions(+), 13760 deletions(-) diff -Nru jetty9-9.4.50/CODE_OF_CONDUCT.md jetty9-9.4.57/CODE_OF_CONDUCT.md --- jetty9-9.4.50/CODE_OF_CONDUCT.md 1970-01-01 00:00:00.000000000 +0000 +++ jetty9-9.4.57/CODE_OF_CONDUCT.md 2024-12-19 21:51:26.000000000 +0000 @@ -0,0 +1,93 @@ +# Community Code of Conduct + +**Version 2.0 +January 1, 2023** + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as community members, contributors, Committers[^1], and Project Leads (collectively "Contributors") pledge to make participation in our projects and our community a harassment-free and inclusive experience for everyone. + +This Community Code of Conduct ("Code") outlines our behavior expectations as members of our community in all Eclipse Foundation activities, both offline and online. It is not intended to govern scenarios or behaviors outside of the scope of Eclipse Foundation activities. Nor is it intended to replace or supersede the protections offered to all our community members under the law. Please follow both the spirit and letter of this Code and encourage other Contributors to follow these principles into our work. Failure to read or acknowledge this Code does not excuse a Contributor from compliance with the Code. + +## Our Standards + +Examples of behavior that contribute to creating a positive and professional environment include: + +- Using welcoming and inclusive language; +- Actively encouraging all voices; +- Helping others bring their perspectives and listening actively. If you find yourself dominating a discussion, it is especially important to encourage other voices to join in; +- Being respectful of differing viewpoints and experiences; +- Gracefully accepting constructive criticism; +- Focusing on what is best for the community; +- Showing empathy towards other community members; +- Being direct but professional; and +- Leading by example by holding yourself and others accountable + +Examples of unacceptable behavior by Contributors include: + +- The use of sexualized language or imagery; +- Unwelcome sexual attention or advances; +- Trolling, insulting/derogatory comments, and personal or political attacks; +- Public or private harassment, repeated harassment; +- Publishing others' private information, such as a physical or electronic address, without explicit permission; +- Violent threats or language directed against another person; +- Sexist, racist, or otherwise discriminatory jokes and language; +- Posting sexually explicit or violent material; +- Sharing private content, such as emails sent privately or non-publicly, or unlogged forums such as IRC channel history; +- Personal insults, especially those using racist or sexist terms; +- Excessive or unnecessary profanity; +- Advocating for, or encouraging, any of the above behavior; and +- Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +With the support of the Eclipse Foundation employees, consultants, officers, and directors (collectively, the "Staff"), Committers, and Project Leads, the Eclipse Foundation Conduct Committee (the "Conduct Committee") is responsible for clarifying the standards of acceptable behavior. The Conduct Committee takes appropriate and fair corrective action in response to any instances of unacceptable behavior. + +## Scope + +This Code applies within all Project, Working Group, and Interest Group spaces and communication channels of the Eclipse Foundation (collectively, "Eclipse spaces"), within any Eclipse-organized event or meeting, and in public spaces when an individual is representing an Eclipse Foundation Project, Working Group, Interest Group, or their communities. Examples of representing a Project or community include posting via an official social media account, personal accounts, or acting as an appointed representative at an online or offline event. Representation of Projects, Working Groups, and Interest Groups may be further defined and clarified by Committers, Project Leads, or the Staff. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the Conduct Committee via conduct@eclipse-foundation.org. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. Without the explicit consent of the reporter, the Conduct Committee is obligated to maintain confidentiality with regard to the reporter of an incident. The Conduct Committee is further obligated to ensure that the respondent is provided with sufficient information about the complaint to reply. If such details cannot be provided while maintaining confidentiality, the Conduct Committee will take the respondent‘s inability to provide a defense into account in its deliberations and decisions. Further details of enforcement guidelines may be posted separately. + +Staff, Committers and Project Leads have the right to report, remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code, or to block temporarily or permanently any Contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. Any such actions will be reported to the Conduct Committee for transparency and record keeping. + +Any Staff (including officers and directors of the Eclipse Foundation), Committers, Project Leads, or Conduct Committee members who are the subject of a complaint to the Conduct Committee will be recused from the process of resolving any such complaint. + +## Responsibility + +The responsibility for administering this Code rests with the Conduct Committee, with oversight by the Executive Director and the Board of Directors. For additional information on the Conduct Committee and its process, please write to . + +## Investigation of Potential Code Violations + +All conflict is not bad as a healthy debate may sometimes be necessary to push us to do our best. It is, however, unacceptable to be disrespectful or offensive, or violate this Code. If you see someone engaging in objectionable behavior violating this Code, we encourage you to address the behavior directly with those involved. If for some reason, you are unable to resolve the matter or feel uncomfortable doing so, or if the behavior is threatening or harassing, please report it following the procedure laid out below. + +Reports should be directed to . It is the Conduct Committee’s role to receive and address reported violations of this Code and to ensure a fair and speedy resolution. + +The Eclipse Foundation takes all reports of potential Code violations seriously and is committed to confidentiality and a full investigation of all allegations. The identity of the reporter will be omitted from the details of the report supplied to the accused. Contributors who are being investigated for a potential Code violation will have an opportunity to be heard prior to any final determination. Those found to have violated the Code can seek reconsideration of the violation and disciplinary action decisions. Every effort will be made to have all matters disposed of within 60 days of the receipt of the complaint. + +## Actions +Contributors who do not follow this Code in good faith may face temporary or permanent repercussions as determined by the Conduct Committee. + +This Code does not address all conduct. It works in conjunction with our [Communication Channel Guidelines](https://www.eclipse.org/org/documents/communication-channel-guidelines/), [Social Media Guidelines](https://www.eclipse.org/org/documents/social_media_guidelines.php), [Bylaws](https://www.eclipse.org/org/documents/eclipse-foundation-be-bylaws-en.pdf), and [Internal Rules](https://www.eclipse.org/org/documents/ef-be-internal-rules.pdf) which set out additional protections for, and obligations of, all contributors. The Foundation has additional policies that provide further guidance on other matters. + +It’s impossible to spell out every possible scenario that might be deemed a violation of this Code. Instead, we rely on one another’s good judgment to uphold a high standard of integrity within all Eclipse Spaces. Sometimes, identifying the right thing to do isn’t an easy call. In such a scenario, raise the issue as early as possible. + +## No Retaliation + +The Eclipse community relies upon and values the help of Contributors who identify potential problems that may need to be addressed within an Eclipse Space. Any retaliation against a Contributor who raises an issue honestly is a violation of this Code. That a Contributor has raised a concern honestly or participated in an investigation, cannot be the basis for any adverse action, including threats, harassment, or discrimination. If you work with someone who has raised a concern or provided information in an investigation, you should continue to treat the person with courtesy and respect. If you believe someone has retaliated against you, report the matter as described by this Code. Honest reporting does not mean that you have to be right when you raise a concern; you just have to believe that the information you are providing is accurate. + +False reporting, especially when intended to retaliate or exclude, is itself a violation of this Code and will not be accepted or tolerated. + +Everyone is encouraged to ask questions about this Code. Your feedback is welcome, and you will get a response within three business days. Write to . + +## Amendments + +The Eclipse Foundation Board of Directors may amend this Code from time to time and may vary the procedures it sets out where appropriate in a particular case. + +### Attribution + +This Code was inspired by the [Contributor Covenant](https://www.contributor-covenant.org/), version 1.4, available [here](https://www.contributor-covenant.org/version/1/4/code-of-conduct/). + +[^1]: Capitalized terms used herein without definition shall have the meanings assigned to them in the Bylaws. \ No newline at end of file diff -Nru jetty9-9.4.50/CONTRIBUTING.md jetty9-9.4.57/CONTRIBUTING.md --- jetty9-9.4.50/CONTRIBUTING.md 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/CONTRIBUTING.md 2024-12-19 21:51:26.000000000 +0000 @@ -14,9 +14,9 @@ -------------------- Information regarding source code management, builds, coding standards, and more. -- [https://www.eclipse.org/jetty/documentation/current/advanced-contributing.html](https://www.eclipse.org/jetty/documentation/current/advanced-contributing.html) +- [https://jetty.org/docs/contribution-guide/index.html](https://jetty.org/docs/contribution-guide/index.html) -The canonical Jetty git repository is located at [GitHub.](https://github.com/eclipse/jetty.project) Providing you have +The canonical Jetty git repository is located at [GitHub.](https://github.com/jetty/jetty.project) Providing you have completed the contributors agreement mentioned below we will endeavor to pull your commit into Jetty proper. Eclipse Contributor Agreement @@ -43,13 +43,13 @@ ---------------- This project uses GitHub Issues to track ongoing development and issues. -- [https://github.com/eclipse/jetty.project/issues](https://github.com/eclipse/jetty.project/issues) +- [https://github.com/jetty/jetty.project/issues](https://github.com/jetty/jetty.project/issues) Create a new bug ----------------- Be sure to search for existing bugs before you create another one. Remember that contributions are always welcome! -- [https://github.com/eclipse/jetty.project/issues](https://github.com/eclipse/jetty.project/issues) +- [https://github.com/jetty/jetty.project/issues](https://github.com/jetty/jetty.project/issues) Reporting Security Issues ----------------- diff -Nru jetty9-9.4.50/Jenkinsfile jetty9-9.4.57/Jenkinsfile --- jetty9-9.4.50/Jenkinsfile 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/Jenkinsfile 2024-12-19 21:51:26.000000000 +0000 @@ -1,7 +1,7 @@ #!groovy pipeline { - agent any + agent none // save some io during the build options { skipDefaultCheckout() @@ -110,13 +110,14 @@ "MAVEN_OPTS=-Xms2g -Xmx4g -Djava.awt.headless=true"]) { configFileProvider( [configFile(fileId: 'oss-settings.xml', variable: 'GLOBAL_MVN_SETTINGS')]) { - sh "mvn --no-transfer-progress -s $GLOBAL_MVN_SETTINGS -Dmaven.repo.local=.repository -Pci -DexcludedGroups=\"external, large-disk-resource, stress, slow\" -V -B -e -Djetty.testtracker.log=true $cmdline -Dunix.socket.tmp=/tmp/unixsocket" + sh "mvn --no-transfer-progress -s $GLOBAL_MVN_SETTINGS -Dmaven.repo.local=.repository -Pci -V -B -e $cmdline -Dunix.socket.tmp=/tmp/unixsocket" } } } finally { junit testResults: '**/target/surefire-reports/*.xml,**/target/invoker-reports/TEST*.xml', allowEmptyResults: true + archiveArtifacts artifacts: ".repository/org/eclipse/jetty/jetty-home/**/jetty-home-*", allowEmptyArchive: true, onlyIfSuccessful: false } } } diff -Nru jetty9-9.4.50/KEYS.txt jetty9-9.4.57/KEYS.txt --- jetty9-9.4.50/KEYS.txt 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/KEYS.txt 2024-12-19 21:51:26.000000000 +0000 @@ -6,4 +6,4 @@ Joakim Erdfelt BFBB 21C2 46D7 7768 3628 7A48 A04E 0C74 ABB3 5FEA Simone Bordet 8B09 6546 B1A8 F026 56B1 5D3B 1677 D141 BCF3 584D Olivier Lamy F254 B356 17DC 255D 9344 BCFA 873A 8E86 B437 2146 -Ludovic Orban E224 88CC 94F6 3E3F C928 536C 4241 C082 70D9 99C3 +Ludovic Orban CD38 A1DA DA34 13BE 96DF 547F 3D14 6A4A 1C58 367E diff -Nru jetty9-9.4.50/NOTICE.txt jetty9-9.4.57/NOTICE.txt --- jetty9-9.4.50/NOTICE.txt 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/NOTICE.txt 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ ========================= This content is produced and maintained by the Eclipse Jetty project. -Project home: https://www.eclipse.org/jetty/ +Project home: https://jetty.org/ Trademarks ---------- diff -Nru jetty9-9.4.50/README.md jetty9-9.4.57/README.md --- jetty9-9.4.50/README.md 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/README.md 2024-12-19 21:51:26.000000000 +0000 @@ -23,7 +23,7 @@ Project documentation is available on the Jetty Eclipse website. -- [https://www.eclipse.org/jetty/documentation](https://www.eclipse.org/jetty/documentation) +- [https://jetty.org/docs/](https://jetty.org/docs/) Building ======== diff -Nru jetty9-9.4.50/VERSION.txt jetty9-9.4.57/VERSION.txt --- jetty9-9.4.50/VERSION.txt 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/VERSION.txt 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,49 @@ -jetty-9.4.50.v20221107 - 07 November 2022 +jetty-9.4.57.v20241219 - 19 December 2024 + + 12268 `IteratingCallback` may iterate too much when `process()` returns + Action.IDLE + + 12648 Backport improved handling of bad Gzip content (and Gzip Exceptions) + + 12532 Backport CVE-2024-6763 to deprecate UserInfo on URI (in violation of + RFC2616 spec) + +jetty-9.4.56.v20240826 - 26 August 2024 + + 12200 Backport ThreadLimitHandler improvements from Jetty 12 (CVE-2024-8184) + +jetty-9.4.55.v20240627 - 27 June 2024 + + 10805 Jetty response with an invalid HTTP2 packet if the client set the + hpack table size as 0 + + 11917 Update XML configure.dtd locations to new jetty.org website + +jetty-9.4.54.v20240208 - 08 February 2024 + + 1256 DoSFilter leaks USER_AUTH entries (CVE-2024-9823) + + 11259 HTTP/2 connection not closed after idle timeout when TCP congested + (CVE-2024-22201) + + 11389 Strip default ports on ws/wss scheme uris too + +jetty-9.4.53.v20231009 - 09 October 2023 + + 10546 backport jetty-http Huffman encoders/decoders from Jetty 10.0.x + + 10573 backport hpack improvements from Jetty 10.0.x (CVE-2023-36478) + + 10679 backport HTTP/2 rate control from Jetty 10.0.x (CVE-2023-44487) + +jetty-9.4.52.v20230823 - 23 August 2023 + + 9476 onCompleteFailure called multiple times + + 9660 OpenId Revoked authentication allows one request (CVE-2023-41900) + + 9887 Deprecate CGI Servlet (CVE-2023-36479) + + 10066 Allow `SAXParserFactory` or `SAXParser` to be configured in Jetty's + `XmlParser` class + + 10168 NPE in websocket extension startup + + 10352 Jetty accepts "+" prefixed value in Content-Length (CVE-2023-40167) + + 10337 SizeLimitHandler does not enforce 0 responseLimit + +jetty-9.4.51.v20230217 - 17 February 2023 + + 9059 IteratingCallback not serializing close() and failed() + + 9181 NPE in SessionHandler.checkRequestedSessionId() + + 9345 Backport Fix for CVE-2023-26048 + + 9352 Backport Fix for CVE-2023-26049 + +jetty-9.4.50.v20221201 - 01 December 2022 + 8774 Added SizeLimitHandler + + 8678 Jetty client is not responding to GO_AWAY packet received from (Jetty) + Server and continue to send traffic on same connection jetty-9.4.49.v20220914 - 14 September 2022 + 8414 BlockingArrayQueue drops all contents on drain @@ -503,6 +547,14 @@ + 4325 Deprecate SniX509ExtendedKeyManager constructor without SslContextFactory$Server +jetty-9.3.28.v20191105 - 05 November 2019 + + 3989 Inform custom ManagedSelector of dead selector via optional + onFailedSelect() + + 4217 SslConnection.DecryptedEnpoint.flush eternal busy loop + +jetty-9.2.29.v20191105 - 05 November 2019 + + 4217 SslConnection.DecryptedEnpoint.flush eternal busy loop + jetty-9.4.22.v20191022 - 22 October 2019 + 2429 HttpClient backpressure improved + 3558 Error notifications can be received after a successful websocket @@ -699,6 +751,18 @@ + 3555 DefaultHandler Reveals Base Resource Path of each Context - Resolves CVE-2019-10247 +jetty-9.3.27.v20190418 - 18 April 2019 + + 3549 Directory Listing on Windows reveals Resource Base path - Resolves + CVE-2019-10246 + + 3555 DefaultHandler Reveals Base Resource Path of each Context - Resolves + CVE-2019-10247 + +jetty-9.2.28.v20190418 - 18 April 2019 + + 3549 Directory Listing on Windows reveals Resource Base path - Resolves + CVE-2019-10246 + + 3555 DefaultHandler Reveals Base Resource Path of each Context - Resolves + CVE-2019-10247 + jetty-9.4.16.v20190411 - 11 April 2019 + 1861 Limit total bytes pooled by ByteBufferPools + 3133 Logging of `key.readyOps()` can throw unchecked `CancelledKeyException` @@ -730,6 +794,18 @@ + 3540 Use configured Provider in SslContextFactory consistently + 3545 NullPointerException on ServletOutputStream.print(""); +jetty-9.3.26.v20190403 - 03 April 2019 + + 2954 Improve cause reporting for HttpClient failures + + 3274 OSGi versions of java.base classes in + org.apache.felix:org.osgi.foundation:jar conflicts with new rules on Java 9+ + + 3302 Support host:port in X-Forwarded-For header in + ForwardedRequestCustomizer + + 3319 Allow reverse sort for directory listed files - Resolves CVE-2019-10241 + +jetty-9.2.27.v20190403 - 03 April 2019 + + 3319 Refactored Directory Listing to modernize and avoid XSS - Resolves + CVE-2019-10241 + jetty-9.4.15.v20190215 - 15 February 2019 + 113 Add support for NCSA Extended Log File Format + 150 extraClasspath() method on WebAppContext dont support dir path @@ -773,38 +849,6 @@ + 3350 Do not expect to be able to connect to https URLs with the HttpClient created from a parameterless constructor -jetty-9.3.28.v20191105 - 05 November 2019 - + 3989 Inform custom ManagedSelector of dead selector via optional - onFailedSelect() - + 4217 SslConnection.DecryptedEnpoint.flush eternal busy loop - -jetty-9.3.27.v20190418 - 18 April 2019 - + 3549 Directory Listing on Windows reveals Resource Base path - Resolves - CVE-2019-10246 - + 3555 DefaultHandler Reveals Base Resource Path of each Context - Resolves - CVE-2019-10247 - -jetty-9.3.26.v20190403 - 03 April 2019 - + 2954 Improve cause reporting for HttpClient failures - + 3274 OSGi versions of java.base classes in - org.apache.felix:org.osgi.foundation:jar conflicts with new rules on Java 9+ - + 3302 Support host:port in X-Forwarded-For header in - ForwardedRequestCustomizer - + 3319 Allow reverse sort for directory listed files - Resolves CVE-2019-10241 - -jetty-9.2.29.v20191105 - 05 November 2019 - + 4217 SslConnection.DecryptedEnpoint.flush eternal busy loop - -jetty-9.2.28.v20190418 - 18 April 2019 - + 3549 Directory Listing on Windows reveals Resource Base path - Resolves - CVE-2019-10246 - + 3555 DefaultHandler Reveals Base Resource Path of each Context - Resolves - CVE-2019-10247 - -jetty-9.2.27.v20190403 - 03 April 2019 - + 3319 Refactored Directory Listing to modernize and avoid XSS - Resolves - CVE-2019-10241 - jetty-9.4.14.v20181114 - 14 November 2018 + 3097 Duplicated programmatic Servlet Listeners causing duplicate calls + 3104 Align jetty-schemas version within apache-jsp module as well @@ -1145,6 +1189,16 @@ jetty-9.2.24.v20180105 - 05 January 2018 + 2065 Backport #347 to Jetty 9.2.x. HttpClient Idle timeout connection reuse +jetty-9.2.23.v20171218 - 18 December 2017 + + 1556 Remove a timing channel in Password matching + + 1685 Update ALPN support for Java 8u141 + + 1702 Update ALPN support for Java 8u144 + + 1914 HttpClient fails to parse Content-Type response header with RFC 2045 + charset="utf-8" syntax + + 2065 Backport #347 to Jetty 9.2.x + + 475546 ClosedChannelException when connecting to HTTPS over HTTP proxy with + CONNECT + jetty-9.4.8.v20171121 - 21 November 2017 + 212 HttpClient should support pluggable AuthenticationStore + 215 Add Conscrypt for native ALPN/TLS/SSL @@ -1220,6 +1274,44 @@ + 1981 Loading resource content failed + 1984 Remove jetty-client dependency in jetty-rewrite +jetty-9.3.22.v20171030 - 30 October 2017 + + 1213 Upgrade to ASM Version 6.0_ALPHA for JDK9 + + 1692 Annotation scanning should ignore `module-info.class` files + + 1705 Rejected executions in QueuedThreadPool can lead to memory leaks + + 1797 JEP 238 - Multi-Release JAR files break bytecode scanning + + 1814 Move JavaVersion to jetty-util for future Java 9 support requirements + + 1901 Reimplement PathWatcher as scanner + + 1912 AbstractConnector EndPoint leak for failed SSL connections + + 1914 jetty client fails to parse response with RFC2045 conformant + Content-Type: charset="utf-8" + + 1928 Backport #1705 to jetty-9.3.x. Fixed leak on Rejected execution + +jetty-9.3.21.v20170918 - 18 September 2017 + + 487 JDK 9 build compatibility + + 1116 Support empty HTTP header values + + 1357 RolloverFileOutputStream: No rollout performed at midnight + + 1469 RolloverFileOutputStream: IllegalStateException Task already scheduled + + 1507 RolloverFileOutputStream: Negative delay Timer.schedule exception + + 1513 RolloverFileOutputStream: can't handle multiple instances + + 1515 Improved RollOverFileOutputStream removeOldFiles() behavior + + 1556 Remove a timing channel in Password matching + + 1590 Improve RolloverFileOutputStream functionality with multiple TimeZones + + 1655 Improve extensibility of ServerConnector + + 1661 AbstractProxyServlet onProxyResponseFailure Error + + 1664 IPAccessHandler CIDR IP range check is incorrect + + 1685 Update ALPN support for Java 8u141 + + 1687 HTTP2: Correcting missing callback notification when channel not found + + 1702 Update ALPN support for Java 8u144 + + 1703 Improve HttpInput failure logging + + 1719 HTTP/2: Improve handling of queued requests + + 1741 Java 9 javadoc failure in build + + 1749 Dump HttpDestination exchange queue + + 1750 PoolingHttpDestination creates ConnectionPool twice + + 1759 HTTP/2: producer can block in onReset + + 1790 HTTP/2: 100% CPU usage seen during close/shutdown of endpoint + + 475546 ClosedChannelException when connection to HTTPS over HTTP proxy with + CONNECT + jetty-9.4.7.v20170914 - 14 September 2017 + 215 Consider native ALPN/SSL provider + 487 JDK 9 build compatibility @@ -1313,27 +1405,18 @@ + 475546 ClosedChannelException when connection to HTTPS over HTTP proxy with CONNECT -jetty-9.2.23.v20171218 - 18 December 2017 - + 1556 Remove a timing channel in Password matching - + 1685 Update ALPN support for Java 8u141 - + 1702 Update ALPN support for Java 8u144 - + 1914 HttpClient fails to parse Content-Type response header with RFC 2045 - charset="utf-8" syntax - + 2065 Backport #347 to Jetty 9.2.x - + 475546 ClosedChannelException when connecting to HTTPS over HTTP proxy with - CONNECT - -jetty-9.3.22.v20171030 - 30 October 2017 - + 1213 Upgrade to ASM Version 6.0_ALPHA for JDK9 - + 1692 Annotation scanning should ignore `module-info.class` files - + 1705 Rejected executions in QueuedThreadPool can lead to memory leaks - + 1797 JEP 238 - Multi-Release JAR files break bytecode scanning - + 1814 Move JavaVersion to jetty-util for future Java 9 support requirements - + 1901 Reimplement PathWatcher as scanner - + 1912 AbstractConnector EndPoint leak for failed SSL connections - + 1914 jetty client fails to parse response with RFC2045 conformant - Content-Type: charset="utf-8" - + 1928 Backport #1705 to jetty-9.3.x. Fixed leak on Rejected execution +jetty-9.2.22.v20170606 - 06 June 2017 + + 920 no main manifest attribute, in jetty-runner-9.2.19.v20160908.jar + + 1108 Please improve logging in SslContextFactory when there are no approved + cipher suites + + 1357 RolloverFileOutputStream: No rollout performed at midnight + + 1469 IllegalStateException in RolloverFileOutputStream + + 1507 Negative delay Timer.schedule exception due to mismatched local and + _logTimeZone values + + 1532 RolloverFileOutputStream can't handle multiple instances + + 1523 Update ALPN support for Java 8u131 + + 1556 A timing channel in Password.java + + 1590 RolloverFileOutputStream not functioning in Jetty 9.2.21+ jetty-9.4.6.v20170531 - 31 May 2017 + 523 TLS close behaviour breaking session resumption @@ -1363,31 +1446,13 @@ + 1569 Allow setting of maxBinaryMessageSize to 0 in WebSocketPolicy + 1579 NPE in Quoted Quality CSV -jetty-9.3.21.v20170918 - 18 September 2017 - + 487 JDK 9 build compatibility - + 1116 Support empty HTTP header values - + 1357 RolloverFileOutputStream: No rollout performed at midnight - + 1469 RolloverFileOutputStream: IllegalStateException Task already scheduled - + 1507 RolloverFileOutputStream: Negative delay Timer.schedule exception - + 1513 RolloverFileOutputStream: can't handle multiple instances - + 1515 Improved RollOverFileOutputStream removeOldFiles() behavior - + 1556 Remove a timing channel in Password matching - + 1590 Improve RolloverFileOutputStream functionality with multiple TimeZones - + 1655 Improve extensibility of ServerConnector - + 1661 AbstractProxyServlet onProxyResponseFailure Error - + 1664 IPAccessHandler CIDR IP range check is incorrect - + 1685 Update ALPN support for Java 8u141 - + 1687 HTTP2: Correcting missing callback notification when channel not found - + 1702 Update ALPN support for Java 8u144 - + 1703 Improve HttpInput failure logging - + 1719 HTTP/2: Improve handling of queued requests - + 1741 Java 9 javadoc failure in build - + 1749 Dump HttpDestination exchange queue - + 1750 PoolingHttpDestination creates ConnectionPool twice - + 1759 HTTP/2: producer can block in onReset - + 1790 HTTP/2: 100% CPU usage seen during close/shutdown of endpoint - + 475546 ClosedChannelException when connection to HTTPS over HTTP proxy with - CONNECT +jetty-9.3.20.v20170531 - 31 May 2017 + + 523 TLS close behaviour breaking session resumption + + 1108 Improve logging in SslContextFactory when there are no approved cipher + suites + + 1527 Jetty BOM should not depend on jetty-parent + + 1556 A timing channel in Password.java + + 1567 XmlConfiguration will start the same object multiple times jetty-9.4.5.v20170502 - 02 May 2017 + 304 Review dead code - StringUtil.sidBytesToString @@ -1421,27 +1486,6 @@ + 1521 Prevent copy of jetty jars to lib/gcloud + 1523 Update ALPN support for Java 8u131 -jetty-9.3.20.v20170531 - 31 May 2017 - + 523 TLS close behaviour breaking session resumption - + 1108 Improve logging in SslContextFactory when there are no approved cipher - suites - + 1527 Jetty BOM should not depend on jetty-parent - + 1556 A timing channel in Password.java - + 1567 XmlConfiguration will start the same object multiple times - -jetty-9.2.22.v20170606 - 06 June 2017 - + 920 no main manifest attribute, in jetty-runner-9.2.19.v20160908.jar - + 1108 Please improve logging in SslContextFactory when there are no approved - cipher suites - + 1357 RolloverFileOutputStream: No rollout performed at midnight - + 1469 IllegalStateException in RolloverFileOutputStream - + 1507 Negative delay Timer.schedule exception due to mismatched local and - _logTimeZone values - + 1532 RolloverFileOutputStream can't handle multiple instances - + 1523 Update ALPN support for Java 8u131 - + 1556 A timing channel in Password.java - + 1590 RolloverFileOutputStream not functioning in Jetty 9.2.21+ - jetty-9.3.19.v20170502 - 02 May 2017 + 877 Programmatic servlet mappings cannot override mappings from webdefault.xml using quickstart @@ -1977,6 +2021,19 @@ + 913 Unprotected debug in WebAppClassLoader + 922 Implements methods Connection.getBytes[In|Out]() +jetty-9.2.19.v20160908 - 08 September 2016 + + 817 NPE in jndi Resource + + 830 Test webapp not properly copied to demo-base + + 832 ServerWithJNDI example uses wrong webapp + + 851 MBeanContainer no longer unregisters MBeans when "stopped" + + 868 ClassLoader leak with Jetty and Karaf - static instances of + java.lang.Throwable + + 880 Refactor jetty-http's HostPortHttpField logic into new jetty-util class + + 882 Add IPv6 support to IPAddressMap in jetty-util + + 894 When adding servless class, preserve Class instead of going through + String + + 899 PathFinderTest fails in jetty-9.2.x + jetty-9.4.0.M1 - 15 August 2016 + 185 Implement RFC 7239 (Forwarded header) + 213 jetty.osgi.boot requires Server services registered before @@ -2133,19 +2190,6 @@ + 755 NPE in HttpChannelOverHTTP2.requestContent() + 756 Filter problematic headers from CGI and FastCGIProxy -jetty-9.2.19.v20160908 - 08 September 2016 - + 817 NPE in jndi Resource - + 830 Test webapp not properly copied to demo-base - + 832 ServerWithJNDI example uses wrong webapp - + 851 MBeanContainer no longer unregisters MBeans when "stopped" - + 868 ClassLoader leak with Jetty and Karaf - static instances of - java.lang.Throwable - + 880 Refactor jetty-http's HostPortHttpField logic into new jetty-util class - + 882 Add IPv6 support to IPAddressMap in jetty-util - + 894 When adding servless class, preserve Class instead of going through - String - + 899 PathFinderTest fails in jetty-9.2.x - jetty-9.2.18.v20160721 - 21 July 2016 + 425 Incorrect @ServerEndpoint Encoder/Decoder lifecycle + 649 LDAPLoginModule should disallow blank username and password @@ -2731,6 +2775,11 @@ + 472422 Custom status codes result in a NumberFormatException while using http2. +jetty-9.2.12.v20150709 - 09 July 2015 + + 469414 Proxied redirects expose upstream server name + + 469936 Remove usages of SpinLock + + 470184 Send the proxy-to-server request more lazily + jetty-9.3.0.v20150612 - 12 June 2015 + 414479 Add WebSocketPingPongListener for those that want PING/PONG payload data @@ -2914,11 +2963,6 @@ --add-to-start + 469991 Fix logging levels in websocket client UpgradeConnection -jetty-9.2.12.v20150709 - 09 July 2015 - + 469414 Proxied redirects expose upstream server name - + 469936 Remove usages of SpinLock - + 470184 Send the proxy-to-server request more lazily - jetty-9.2.11.v20150529 - 29 May 2015 + 461499 ConnectionPool may leak connections + 463579 Add support for 308 status code @@ -3752,6 +3796,30 @@ + 434077 AnnotatedServerEndpointTest emits strange exception + 434247 Redirect loop in FastCGI proxying for HTTPS sites +jetty-9.1.5.v20140505 - 05 May 2014 + + 431459 Jetty WebSocket compression extensions fails to handle big messages + properly + + 431519 Fixed NetworkTrafficListener + + 432145 Pending request is not failed when HttpClient is stopped + + 432270 Slow requests with response content delimited by EOF fail + + 432473 web.xml declaration order of filters not preserved on calls to init() + + 432483 make osgi.serviceloader support for + javax.servlet.ServletContainerInitializer optional (cherry picked from + commit 31043d25708edbea9ef31948093f4eaf2247919b) + + 432528 IllegalStateException when using DeferredContentProvider + + 432777 Async Write Loses Data with HTTPS Server + + 432901 ensure a single onError callback only in pending and unready states + + 432993 Improve handling of ProxyTo and Prefix parameters in + ProxyServlet.Transparent. + + 433365 No such servlet: + __org.eclipse.jetty.servlet.JspPropertyGroupServlet__ (cherry picked from + commit e2ed934978b958d6fccb28a8a5d04768f7c0432d) + + 433370 PATCH method does not work with ProxyServlet + + 433483 sync log initialize + + 433692 improved buffer resizing + + 433916 HttpChannelOverHttp handles HTTP 1.0 connection reuse incorrectly + + 434027 ReadListener.onError() not invoked in case of read failures + jetty-8.1.15.v20140411 - 11 April 2014 + 397167 Remote Access documentation is wrong + 419799 complete after exceptions thrown from async error pages @@ -3798,30 +3866,6 @@ + 432145 Pending request is not failed when HttpClient is stopped + 432270 Slow requests with response content delimited by EOF fail -jetty-9.1.5.v20140505 - 05 May 2014 - + 431459 Jetty WebSocket compression extensions fails to handle big messages - properly - + 431519 Fixed NetworkTrafficListener - + 432145 Pending request is not failed when HttpClient is stopped - + 432270 Slow requests with response content delimited by EOF fail - + 432473 web.xml declaration order of filters not preserved on calls to init() - + 432483 make osgi.serviceloader support for - javax.servlet.ServletContainerInitializer optional (cherry picked from - commit 31043d25708edbea9ef31948093f4eaf2247919b) - + 432528 IllegalStateException when using DeferredContentProvider - + 432777 Async Write Loses Data with HTTPS Server - + 432901 ensure a single onError callback only in pending and unready states - + 432993 Improve handling of ProxyTo and Prefix parameters in - ProxyServlet.Transparent. - + 433365 No such servlet: - __org.eclipse.jetty.servlet.JspPropertyGroupServlet__ (cherry picked from - commit e2ed934978b958d6fccb28a8a5d04768f7c0432d) - + 433370 PATCH method does not work with ProxyServlet - + 433483 sync log initialize - + 433692 improved buffer resizing - + 433916 HttpChannelOverHttp handles HTTP 1.0 connection reuse incorrectly - + 434027 ReadListener.onError() not invoked in case of read failures - jetty-9.1.4.v20140401 - 01 April 2014 + 414206 Rewrite rules re-encode requestURI + 414885 Don't expose JDT classes by default @@ -4534,6 +4578,75 @@ + 414951 QueuedThreadPool fix constructor that missed to pass the idleTimeout + 414972 HttpClient may read bytes with pre-tunnelled connection +jetty-8.1.12.v20130726 - 26 July 2013 + + 396706 CGI support parameters + + 397193 MongoSessionManager refresh updates last access time + + 407342 ReloadedSessionMissingClassTest uses class compiled with jdk7 + + 408529 Etags set in 304 response + + 408600 set correct jetty.url in all pom files + + 408642 setContentType from addHeader + + 408662 In pax-web servlet services requests even if init() has not finished + running + + 408806 getParameter returns null on Multipart request if called before + request.getPart()/getParts() + + 408909 GzipFilter setting of headers when reset and/or not compressed + + 409028 Jetty HttpClient does not work with proxy CONNECT method + + 409133 Empty causes StackOverflowError + + 409436 NPE on context restart using dynamic servlet registration + + 409449 Ensure servlets, filters and listeners added via dynamic + registration, annotations or descriptors are cleaned on context restarts + + 409556 FileInputStream not closed in DirectNIOBuffer + + 410405 Avoid NPE for requestDispatcher(../) + + 410630 MongoSessionManager conflicting session update op + + 410750 NoSQLSessions: implement session context data persistence across + server restarts + + 410893 async support defaults to false for spec created servlets and filters + + 411135 HttpClient may send proxied https requests to the proxy instead of + the target server. + + 411216 RequestLogHandler handles async completion + + 411458 MultiPartFilter getParameterMap doesn't preserve multivalued + parameters 411459 MultiPartFilter.Wrapper getParameter should use charset + encoding of part + + 411755 MultiPartInputStreamParser fails on base64 encoded content + + 411909 GzipFilter flushbuffer() results in erroneous finish() call + + 412712 HttpClient does not send the terminal chunk after partial writes + + 412750 HttpClient close expired connections fix + + 413371 Default JSON.Converters for List and Set + + 413372 JSON Enum uses name rather than toString() + + 413684 Trailing slash shows JSP source + + 413812 Make RateTracker serializable + +jetty-7.6.12.v20130726 - 26 July 2013 + + 396706 CGI support parameters + + 397193 MongoSessionManager refresh updates last access time + + 407342 ReloadedSessionMissingClassTest uses class compiled with jdk7 + + 408529 Etags set in 304 response + + 408600 set correct jetty.url in all pom files + + 408642 setContentType from addHeader + + 408662 In pax-web servlet services requests even if init() has not finished + running + + 408909 GzipFilter setting of headers when reset and/or not compressed + + 409028 Jetty HttpClient does not work with proxy CONNECT method + + 409133 Empty causes StackOverflowError + + 409556 FileInputStream not closed in DirectNIOBuffer + + 410630 MongoSessionManager conflicting session update op + + 410750 NoSQLSessions: implement session context data persistence across + server restarts + + 411135 HttpClient may send proxied https requests to the proxy instead of + the target server. + + 411216 RequestLogHandler handles async completion + + 411458 MultiPartFilter getParameterMap doesn't preserve multivalued + parameters 411459 MultiPartFilter.Wrapper getParameter should use charset + encoding of part + + 411755 MultiPartInputStreamParser fails on base64 encoded content + + 411909 GzipFilter flushbuffer() results in erroneous finish() call + + 412712 HttpClient does not send the terminal chunk after partial writes + + 412750 HttpClient close expired connections fix + + 413371 Default JSON.Converters for List and Set + + 413372 JSON Enum uses name rather than toString() + + 413684 Trailing slash shows JSP source + + 413812 Make RateTracker serializable + jetty-9.0.4.v20130625 - 25 June 2013 + 396706 CGI support parameters + 397051 Make JDBCLoginService data members protected to facilitate @@ -4668,6 +4781,59 @@ + 411545 SslConnection.DecryptedEndpoint.fill() sometimes misses a few network bytes +jetty-8.1.11.v20130520 - 20 May 2013 + + 402844 STOP.PORT & STOP.KEY behaviour has changed + + 403281 jetty.sh waits for started or failure before returning + + 403513 jetty:run goal cannot be executed twice during the maven build + + 403570 Asynchronous Request Logging + + 404010 fix cast exception in mongodb session manager + + 404128 Add Vary headers rather than set them + + 404283 org.eclipse.jetty.util.Scanner.scanFile() dies with an NPE if + listFiles() returns null + + 404325 data constraint redirection does send default port + + 404517 Close connection if request received after half close + + 404789 Support IPv6 addresses in DoSFilter white list + + 404958 Fixed Resource.newSystemResource striped / handling + + 405281 allow filemappedbuffers to not be used + + 405537 NPE in rendering JSP using SPDY and wrapped ServletRequest + + 406437 Digest Auth supports out of order nc + + 406618 Jetty startup in OSGi Equinox fails when using option + jetty.home.bundle=org.eclipse.jetty.osgi.boot + + 406923 CR line termination + + 407136 @PreDestroy called after Servlet.destroy() + + 407173 java.lang.IllegalStateException: null when using JDBCSessionManager + + 407931 Add toggle for failing on servlet availability + + 407976 JDBCSessionIdManager potentially leaves server in bad state after + startup + + 408077 HashSessionManager leaves file handles open after being stopped + + 408446 Multipart parsing issue with boundry and charset in ContentType + header + +jetty-7.6.11.v20130520 - 20 May 2013 + + 402844 STOP.PORT & STOP.KEY behaviour has changed + + 403281 jetty.sh waits for started or failure before returning + + 403513 jetty:run goal cannot be executed twice during the maven build + + 403570 Asynchronous Request Logging + + 404010 fix cast exception in mongodb session manager + + 404128 Add Vary headers rather than set them + + 404283 org.eclipse.jetty.util.Scanner.scanFile() dies with an NPE if + listFiles() returns null + + 404325 data constraint redirection does send default port + + 404517 Close connection if request received after half close + + 404789 Support IPv6 addresses in DoSFilter white list + + 404958 Fixed Resource.newSystemResource striped / handling + + 405281 allow filemappedbuffers to not be used + + 405537 NPE in rendering JSP using SPDY and wrapped ServletRequest + + 406437 Digest Auth supports out of order nc + + 406923 CR line termination + + 407136 @PreDestroy called after Servlet.destroy() + + 407173 java.lang.IllegalStateException: null when using JDBCSessionManager + + 407976 JDBCSessionIdManager potentially leaves server in bad state after + startup + + 408077 HashSessionManager leaves file handles open after being stopped + + 408446 Multipart parsing issue with boundry and charset in ContentType + header + jetty-9.0.3.v20130506 - 06 May 2013 + 404010 fix cast exception in mongodb session manager + 404911 WebSocketCloseTest fails spuriously @@ -4793,144 +4959,6 @@ + 404958 Fixed Resource.newSystemResource striped / handling + 405044 Query parameters lost for non GET or POST -jetty-9.0.0.v20130308 - 08 March 2013 - + 399070 add updated version of npn-boot jar to start.ini - + 399799 do not hold lock while calling invalidation listeners - + 399967 Destroyables destroyed on undeploy and shutdown hook - + 400312 ServletContextListener.contextInitialized() is not called when added - in ServletContainerInitializer.onStartup - + 401495 removed unused getOutputStream - + 401531 StringIndexOutOfBoundsException for "/*" of - fix for multiple mappings to *.jsp - + 401641 Fixed MBean setter for String[] - + 401642 Less verbose INFOs - + 401643 Improved Authentication exception messages and provided quiet servlet - exception - + 401644 Dump does not login user already logged in - + 401651 Abort request if maxRequestsQueuedPerDestination is reached - + 401777 InputStreamResponseListener CJK byte (>=128) cause EOF - + 401904 fixed getRemoteAddr to return IP instead of hostname - + 401908 Enhance DosFilter to allow dynamic configuration of attributes - + 401966 Ensure OSGI WebApp as Service (WebAppContext) can be deployed only - through ServiceWebAppProvider - + 402008 Websocket blocking write hangs when remote client dies (or is killed) - without going thru Close handshake - + 402048 org.eclipse.jetty.server.ShutdownMonitor doesn't stop after the jetty - server is stopped - + 402075 Massive old gen growth when hit by lots of non persistent - connections. - + 402090 httpsender PendingState cause uncertain data send to server - + 402106 fixed URI resize in HttpParser - + 402148 Update Javadoc for WebSocketServlet for new API - + 402154 WebSocket / Session.setIdleTimeout(ms) should support in-place idle - timeout changes - + 402185 updated javascript mime-type - + 402277 spdy proxy: fix race condition in nested push streams initiated by - upstream server. Fix several other small proxy issues - + 402316 HttpReceiver and null pointer exception - + 402341 Host with default port causes redirects loop - + 402726 WebAppContext references old WebSocket packages in system and server - classes - + 402757 WebSocket client module can't be used with WebSocket server module in - the same WAR - -jetty-8.1.12.v20130726 - 26 July 2013 - + 396706 CGI support parameters - + 397193 MongoSessionManager refresh updates last access time - + 407342 ReloadedSessionMissingClassTest uses class compiled with jdk7 - + 408529 Etags set in 304 response - + 408600 set correct jetty.url in all pom files - + 408642 setContentType from addHeader - + 408662 In pax-web servlet services requests even if init() has not finished - running - + 408806 getParameter returns null on Multipart request if called before - request.getPart()/getParts() - + 408909 GzipFilter setting of headers when reset and/or not compressed - + 409028 Jetty HttpClient does not work with proxy CONNECT method - + 409133 Empty causes StackOverflowError - + 409436 NPE on context restart using dynamic servlet registration - + 409449 Ensure servlets, filters and listeners added via dynamic - registration, annotations or descriptors are cleaned on context restarts - + 409556 FileInputStream not closed in DirectNIOBuffer - + 410405 Avoid NPE for requestDispatcher(../) - + 410630 MongoSessionManager conflicting session update op - + 410750 NoSQLSessions: implement session context data persistence across - server restarts - + 410893 async support defaults to false for spec created servlets and filters - + 411135 HttpClient may send proxied https requests to the proxy instead of - the target server. - + 411216 RequestLogHandler handles async completion - + 411458 MultiPartFilter getParameterMap doesn't preserve multivalued - parameters 411459 MultiPartFilter.Wrapper getParameter should use charset - encoding of part - + 411755 MultiPartInputStreamParser fails on base64 encoded content - + 411909 GzipFilter flushbuffer() results in erroneous finish() call - + 412712 HttpClient does not send the terminal chunk after partial writes - + 412750 HttpClient close expired connections fix - + 413371 Default JSON.Converters for List and Set - + 413372 JSON Enum uses name rather than toString() - + 413684 Trailing slash shows JSP source - + 413812 Make RateTracker serializable - -jetty-7.6.12.v20130726 - 26 July 2013 - + 396706 CGI support parameters - + 397193 MongoSessionManager refresh updates last access time - + 407342 ReloadedSessionMissingClassTest uses class compiled with jdk7 - + 408529 Etags set in 304 response - + 408600 set correct jetty.url in all pom files - + 408642 setContentType from addHeader - + 408662 In pax-web servlet services requests even if init() has not finished - running - + 408909 GzipFilter setting of headers when reset and/or not compressed - + 409028 Jetty HttpClient does not work with proxy CONNECT method - + 409133 Empty causes StackOverflowError - + 409556 FileInputStream not closed in DirectNIOBuffer - + 410630 MongoSessionManager conflicting session update op - + 410750 NoSQLSessions: implement session context data persistence across - server restarts - + 411135 HttpClient may send proxied https requests to the proxy instead of - the target server. - + 411216 RequestLogHandler handles async completion - + 411458 MultiPartFilter getParameterMap doesn't preserve multivalued - parameters 411459 MultiPartFilter.Wrapper getParameter should use charset - encoding of part - + 411755 MultiPartInputStreamParser fails on base64 encoded content - + 411909 GzipFilter flushbuffer() results in erroneous finish() call - + 412712 HttpClient does not send the terminal chunk after partial writes - + 412750 HttpClient close expired connections fix - + 413371 Default JSON.Converters for List and Set - + 413372 JSON Enum uses name rather than toString() - + 413684 Trailing slash shows JSP source - + 413812 Make RateTracker serializable - -jetty-8.1.11.v20130520 - 20 May 2013 - + 402844 STOP.PORT & STOP.KEY behaviour has changed - + 403281 jetty.sh waits for started or failure before returning - + 403513 jetty:run goal cannot be executed twice during the maven build - + 403570 Asynchronous Request Logging - + 404010 fix cast exception in mongodb session manager - + 404128 Add Vary headers rather than set them - + 404283 org.eclipse.jetty.util.Scanner.scanFile() dies with an NPE if - listFiles() returns null - + 404325 data constraint redirection does send default port - + 404517 Close connection if request received after half close - + 404789 Support IPv6 addresses in DoSFilter white list - + 404958 Fixed Resource.newSystemResource striped / handling - + 405281 allow filemappedbuffers to not be used - + 405537 NPE in rendering JSP using SPDY and wrapped ServletRequest - + 406437 Digest Auth supports out of order nc - + 406618 Jetty startup in OSGi Equinox fails when using option - jetty.home.bundle=org.eclipse.jetty.osgi.boot - + 406923 CR line termination - + 407136 @PreDestroy called after Servlet.destroy() - + 407173 java.lang.IllegalStateException: null when using JDBCSessionManager - + 407931 Add toggle for failing on servlet availability - + 407976 JDBCSessionIdManager potentially leaves server in bad state after - startup - + 408077 HashSessionManager leaves file handles open after being stopped - + 408446 Multipart parsing issue with boundry and charset in ContentType - header - jetty-8.1.10.v20130312 - 12 March 2013 + 376273 Early EOF because of SSL Protocol Error on https://api-3t.paypal.com/nvp. @@ -4967,31 +4995,6 @@ + 402833 Test harness for global error page and hide exception message from reason string -jetty-7.6.11.v20130520 - 20 May 2013 - + 402844 STOP.PORT & STOP.KEY behaviour has changed - + 403281 jetty.sh waits for started or failure before returning - + 403513 jetty:run goal cannot be executed twice during the maven build - + 403570 Asynchronous Request Logging - + 404010 fix cast exception in mongodb session manager - + 404128 Add Vary headers rather than set them - + 404283 org.eclipse.jetty.util.Scanner.scanFile() dies with an NPE if - listFiles() returns null - + 404325 data constraint redirection does send default port - + 404517 Close connection if request received after half close - + 404789 Support IPv6 addresses in DoSFilter white list - + 404958 Fixed Resource.newSystemResource striped / handling - + 405281 allow filemappedbuffers to not be used - + 405537 NPE in rendering JSP using SPDY and wrapped ServletRequest - + 406437 Digest Auth supports out of order nc - + 406923 CR line termination - + 407136 @PreDestroy called after Servlet.destroy() - + 407173 java.lang.IllegalStateException: null when using JDBCSessionManager - + 407976 JDBCSessionIdManager potentially leaves server in bad state after - startup - + 408077 HashSessionManager leaves file handles open after being stopped - + 408446 Multipart parsing issue with boundry and charset in ContentType - header - jetty-7.6.10.v20130312 - 12 March 2013 + 376273 Early EOF because of SSL Protocol Error on https://api-3t.paypal.com/nvp. @@ -5024,6 +5027,47 @@ + 402833 Test harness for global error page and hide exception message from reason string +jetty-9.0.0.v20130308 - 08 March 2013 + + 399070 add updated version of npn-boot jar to start.ini + + 399799 do not hold lock while calling invalidation listeners + + 399967 Destroyables destroyed on undeploy and shutdown hook + + 400312 ServletContextListener.contextInitialized() is not called when added + in ServletContainerInitializer.onStartup + + 401495 removed unused getOutputStream + + 401531 StringIndexOutOfBoundsException for "/*" of + fix for multiple mappings to *.jsp + + 401641 Fixed MBean setter for String[] + + 401642 Less verbose INFOs + + 401643 Improved Authentication exception messages and provided quiet servlet + exception + + 401644 Dump does not login user already logged in + + 401651 Abort request if maxRequestsQueuedPerDestination is reached + + 401777 InputStreamResponseListener CJK byte (>=128) cause EOF + + 401904 fixed getRemoteAddr to return IP instead of hostname + + 401908 Enhance DosFilter to allow dynamic configuration of attributes + + 401966 Ensure OSGI WebApp as Service (WebAppContext) can be deployed only + through ServiceWebAppProvider + + 402008 Websocket blocking write hangs when remote client dies (or is killed) + without going thru Close handshake + + 402048 org.eclipse.jetty.server.ShutdownMonitor doesn't stop after the jetty + server is stopped + + 402075 Massive old gen growth when hit by lots of non persistent + connections. + + 402090 httpsender PendingState cause uncertain data send to server + + 402106 fixed URI resize in HttpParser + + 402148 Update Javadoc for WebSocketServlet for new API + + 402154 WebSocket / Session.setIdleTimeout(ms) should support in-place idle + timeout changes + + 402185 updated javascript mime-type + + 402277 spdy proxy: fix race condition in nested push streams initiated by + upstream server. Fix several other small proxy issues + + 402316 HttpReceiver and null pointer exception + + 402341 Host with default port causes redirects loop + + 402726 WebAppContext references old WebSocket packages in system and server + classes + + 402757 WebSocket client module can't be used with WebSocket server module in + the same WAR + jetty-9.0.0.RC2 - 24 February 2013 + Fix etc/jetty.xml TimerScheduler typo that is preventing normal startup + Fix etc/jetty-https.xml ExcludeCipherSuites typo that prevents SSL startup @@ -5126,102 +5170,6 @@ + 399703 made encoding error handling consistent + 399721 Change to -jetty-9.0.0.M5 - 19 January 2013 - + 367638 throw exception for excess form keys - + 381521 Only set Vary header when content could be compressed - + 391623 Making --stop with STOP.WAIT perform graceful shutdown - + 393158 java.lang.IllegalStateException when sending an empty InputStream - + 393220 remove dead code from ServletHandler and log ServletExceptions in - warn instead of debug - + 393733 WebSocketClient interface should support multiple connections - + 395885 ResourceCache should honor useFileMappedBuffer if set - + 396253 FilterRegistration wrong order - + 396459 Log specific message for empty request body for multipart mime - requests - + 396500 HttpClient Exchange takes forever to complete when less content sent - than Content-Length - + 396886 MultiPartFilter strips bad escaping on filename="..." - + 397110 Accept %uXXXX encodings in URIs - + 397111 Tolerate empty or excessive whitespace preceeding MultiParts - + 397112 Requests with byte-range throws NPE if requested file has no mimetype - (eg no file extension) - + 397114 run-forked with waitForChild=false can lock up - + 397130 maxFormContentSize set in jetty.xml is ignored - + 397190 improve ValidUrlRule to iterate on codepoints - + 397321 Wrong condition in default start.config for annotations - + 397535 Support pluggable alias checking to support symbolic links - + 397769 TimerScheduler does not relinquish cancelled tasks - + 398105 Clean up WebSocketPolicy - + 398285 ProxyServlet mixes cookies from different clients - + 398337 UTF-16 percent encoding in UTF-16 form content - + 398582 Move lib/jta jar into lib/jndi - + JETTY-1533 handle URL with no path - -jetty-9.0.0.M4 - 21 December 2012 - + 392417 Prevent Cookie parsing interpreting unicode chars - + 393220 remove dead code from ServletHandler and log ServletExceptions in - warn instead of debug - + 393770 Error in ContextHandler.setEventListeners(EventListener[]) - + 394210 spdy api rename stream.syn() to stream.push() - + 394211 spdy: Expose RemoteServerAddress and LocalServerAddress in - StandardSession - + 394294 Start web-bundles started before jetty - + 394370 Add integration test for client resetting SPDY push SYN's - + 394514 Preserve URI parameters in sendRedirect - + 394552 HEAD requests don't work for jetty-client - + 394719 remove regex from classpath matching - + 394829 Session can not be restored after SessionManager.setIdleSavePeriod - has saved the session - + 394839 Allow multipart mime with no boundary - + 394854 optimised promise implementation - + 394870 Make enablement of remote access to test webapp configurable in - override-web.xml - + 395168 fix unavailable attributes when return type has annotation on super - class - + 395215 Multipart mime with just LF and no CRLF: add test for legacy filter - + 395220 New InputStream extension to allow a mix of EOL styles between - headers and content - + 395312 log.warn if a SPDY stream gets committed twice - + 395313 HttpTransportOverSPDY.send() does not rethrow exceptions, but call - Callback.failed() only - + 395314 Add missing flush() call after StandardSession.complete() has been - called. Some test cleanup. - + 395344 Move JSR-356 (Java WebSocket API) work off to Jetty 9.1.x - + 395380 add ValidUrlRule to jetty-rewrite - + 395394 allow logging from boot classloader - + 395574 port jetty-runner and StatisticsServlet to jetty-9 - + 395605 class cast exception in XMLConfiguration fixed - + 395649 add jetty-setuid back into jetty 9 and distribution - + 395794 slightly modified fix for empty file extenstion to mime type mapping - Added a default, so it will also work with unknown file extensions - + 396036 SPDY send controlFrames even if Stream is reset to avoid breaking the - compression context - + 396193 spdy remove timeout parameters from api and move them to the Info* - classes - + 396459 Log specific message for empty request body for multipart mime - requests - + 396460 Make ServerConnector configurable with jetty-maven-plugin - + 396472 org.eclipse.jetty.websocket needs to be removed from serverclasses as - it should only be a systemclass - + 396473 JettyWebXMlConfiguration does not reset serverclasses - + 396474 add websocket server classes to jetty-maven-plugin classpath - + 396475 Remove unneeded websocket-server dependency from test-jetty-webapp - + 396518 Websocket AB Tests should test for which side disconnected and - closed.wasClean - + 396687 missing jetty-io dependency in jetty-servlets - + JETTY-796 jetty ant plugin improvements - -jetty-9.0.0.M3 - 20 November 2012 - + 391623 Add option to --stop to wait for target jetty to stop - + 392237 Port test-integration to jetty-9 - + 392492 expect headers only examined for requests>=HTTP/1.1 - + 392850 ContextLoaderListener not called in 9.0.0.M1 and M2 - + 393075 1xx, 204, 304 responses ignore headers that suggest content - + 393832 start connectors last - + 393947 additional tests - + 394143 add jetty-all aggregate via release profile - + 394144 add jetty-jaspi - jetty-8.1.9.v20130131 - 31 January 2013 + 362226 HttpConnection "wait" call causes thread resource exhaustion + 367638 throw exception for excess form keys @@ -5327,6 +5275,102 @@ + JETTY-846 Support maven-war-plugin configuration for jetty-maven-plugin; fix NPE +jetty-9.0.0.M5 - 19 January 2013 + + 367638 throw exception for excess form keys + + 381521 Only set Vary header when content could be compressed + + 391623 Making --stop with STOP.WAIT perform graceful shutdown + + 393158 java.lang.IllegalStateException when sending an empty InputStream + + 393220 remove dead code from ServletHandler and log ServletExceptions in + warn instead of debug + + 393733 WebSocketClient interface should support multiple connections + + 395885 ResourceCache should honor useFileMappedBuffer if set + + 396253 FilterRegistration wrong order + + 396459 Log specific message for empty request body for multipart mime + requests + + 396500 HttpClient Exchange takes forever to complete when less content sent + than Content-Length + + 396886 MultiPartFilter strips bad escaping on filename="..." + + 397110 Accept %uXXXX encodings in URIs + + 397111 Tolerate empty or excessive whitespace preceeding MultiParts + + 397112 Requests with byte-range throws NPE if requested file has no mimetype + (eg no file extension) + + 397114 run-forked with waitForChild=false can lock up + + 397130 maxFormContentSize set in jetty.xml is ignored + + 397190 improve ValidUrlRule to iterate on codepoints + + 397321 Wrong condition in default start.config for annotations + + 397535 Support pluggable alias checking to support symbolic links + + 397769 TimerScheduler does not relinquish cancelled tasks + + 398105 Clean up WebSocketPolicy + + 398285 ProxyServlet mixes cookies from different clients + + 398337 UTF-16 percent encoding in UTF-16 form content + + 398582 Move lib/jta jar into lib/jndi + + JETTY-1533 handle URL with no path + +jetty-9.0.0.M4 - 21 December 2012 + + 392417 Prevent Cookie parsing interpreting unicode chars + + 393220 remove dead code from ServletHandler and log ServletExceptions in + warn instead of debug + + 393770 Error in ContextHandler.setEventListeners(EventListener[]) + + 394210 spdy api rename stream.syn() to stream.push() + + 394211 spdy: Expose RemoteServerAddress and LocalServerAddress in + StandardSession + + 394294 Start web-bundles started before jetty + + 394370 Add integration test for client resetting SPDY push SYN's + + 394514 Preserve URI parameters in sendRedirect + + 394552 HEAD requests don't work for jetty-client + + 394719 remove regex from classpath matching + + 394829 Session can not be restored after SessionManager.setIdleSavePeriod + has saved the session + + 394839 Allow multipart mime with no boundary + + 394854 optimised promise implementation + + 394870 Make enablement of remote access to test webapp configurable in + override-web.xml + + 395168 fix unavailable attributes when return type has annotation on super + class + + 395215 Multipart mime with just LF and no CRLF: add test for legacy filter + + 395220 New InputStream extension to allow a mix of EOL styles between + headers and content + + 395312 log.warn if a SPDY stream gets committed twice + + 395313 HttpTransportOverSPDY.send() does not rethrow exceptions, but call + Callback.failed() only + + 395314 Add missing flush() call after StandardSession.complete() has been + called. Some test cleanup. + + 395344 Move JSR-356 (Java WebSocket API) work off to Jetty 9.1.x + + 395380 add ValidUrlRule to jetty-rewrite + + 395394 allow logging from boot classloader + + 395574 port jetty-runner and StatisticsServlet to jetty-9 + + 395605 class cast exception in XMLConfiguration fixed + + 395649 add jetty-setuid back into jetty 9 and distribution + + 395794 slightly modified fix for empty file extenstion to mime type mapping + Added a default, so it will also work with unknown file extensions + + 396036 SPDY send controlFrames even if Stream is reset to avoid breaking the + compression context + + 396193 spdy remove timeout parameters from api and move them to the Info* + classes + + 396459 Log specific message for empty request body for multipart mime + requests + + 396460 Make ServerConnector configurable with jetty-maven-plugin + + 396472 org.eclipse.jetty.websocket needs to be removed from serverclasses as + it should only be a systemclass + + 396473 JettyWebXMlConfiguration does not reset serverclasses + + 396474 add websocket server classes to jetty-maven-plugin classpath + + 396475 Remove unneeded websocket-server dependency from test-jetty-webapp + + 396518 Websocket AB Tests should test for which side disconnected and + closed.wasClean + + 396687 missing jetty-io dependency in jetty-servlets + + JETTY-796 jetty ant plugin improvements + +jetty-9.0.0.M3 - 20 November 2012 + + 391623 Add option to --stop to wait for target jetty to stop + + 392237 Port test-integration to jetty-9 + + 392492 expect headers only examined for requests>=HTTP/1.1 + + 392850 ContextLoaderListener not called in 9.0.0.M1 and M2 + + 393075 1xx, 204, 304 responses ignore headers that suggest content + + 393832 start connectors last + + 393947 additional tests + + 394143 add jetty-all aggregate via release profile + + 394144 add jetty-jaspi + jetty-9.0.0.M2 - 06 November 2012 + 371170 MongoSessionManager LastAccessTimeTest fails + 391877 org.eclipse.jetty.webapp.FragmentDescriptor incorrectly reporting @@ -5569,7 +5613,7 @@ + 385925 make SslContextFactory.setProtocols and SslContextFactory.setCipherSuites preserve the order of the given parameters -jetty-8.1.5.v20120716 - 16 June 2012 +jetty-7.6.5.v20120716 - 16 July 2012 + 376717 Balancer Servlet with round robin support, contribution, added missing license + 379250 Server is added to shutdown hook twice @@ -5587,20 +5631,15 @@ + 383251 500 for SocketExceptions + 383881 WebSocketHandler sets request as handled + 384254 revert change to writable when not dispatched - + 384280 Implement preliminary ServletRegistrations + 384847 CrossOriginFilter is not working + 384896 JDBCSessionManager fails to load existing sessions on oracle when contextPath is / + 384980 Jetty client unable to recover from Time outs when connection count per address hits max. - + 385138 add getter for session path and max cookie age that seemed to - disappear in a merge long ago - + JETTY-1523 It is imposible to map servlet to "/" using - WebApplicationInitializer + JETTY-1525 Show handle status in response debug message + JETTY-1530 refine search control on ldap login module -jetty-7.6.5.v20120716 - 16 July 2012 +jetty-8.1.5.v20120716 - 16 June 2012 + 376717 Balancer Servlet with round robin support, contribution, added missing license + 379250 Server is added to shutdown hook twice @@ -5618,11 +5657,16 @@ + 383251 500 for SocketExceptions + 383881 WebSocketHandler sets request as handled + 384254 revert change to writable when not dispatched + + 384280 Implement preliminary ServletRegistrations + 384847 CrossOriginFilter is not working + 384896 JDBCSessionManager fails to load existing sessions on oracle when contextPath is / + 384980 Jetty client unable to recover from Time outs when connection count per address hits max. + + 385138 add getter for session path and max cookie age that seemed to + disappear in a merge long ago + + JETTY-1523 It is imposible to map servlet to "/" using + WebApplicationInitializer + JETTY-1525 Show handle status in response debug message + JETTY-1530 refine search control on ldap login module @@ -5879,6 +5923,22 @@ + JETTY-1475 made output state fields volatile to provide memory barrier for non dispatched thread IO +jetty-7.6.0.RC5 - 20 January 2012 + + 359329 Prevent reinvocation of LoginModule.login with jaspi for already + authed user + + 368632 Remove superfluous removal of org.apache.catalina.jsp_file + + 368633 fixed configure.dtd resource mappings + + 368635 moved lifecycle state reporting from toString to dump + + 368773 process data constraints without realm + + 368787 always set token view to new header buffers in httpparser + + 368821 improved test harness + + 368920 JettyAwareLogger always formats the arguments + + 368948 POM for jetty-jndi references unknown version for javax.activation + + 368992 avoid non-blocking flush when writing to avoid setting !_writable + without _writeblocked + + JETTY-1475 made output state fields volatile to provide memory barrier for + non dispatched thread IO + jetty-8.1.0.RC4 - 13 January 2012 + 365048 jetty Http client does not send proxy authentication when requesting a Https-resource through a web-proxy. @@ -5923,6 +5983,43 @@ + 368291 Change warning to info for NoSuchFieldException on BeanELResolver.properties +jetty-7.6.0.RC4 - 13 January 2012 + + 365048 jetty Http client does not send proxy authentication when requesting + a Https-resource through a web-proxy. + + 366774 removed XSS vulnerbility + + 367099 Upgrade jetty-websocket for RFC 6455 - Addendum + + 367716 simplified idleTimeout logic + + 368035 WebSocketClientFactory does not invoke super.doStop() + + 368060 do not encode sendRedirect URLs + + 368114 Protect against non-Strings in System properties for Log + + 368189 WebSocketClientFactory should not manage external thread pool + + 368215 Remove debug from jaspi + + 368240 Improve AggregateLifeCycle handling of shared lifecycles + + 368291 Change warning to info for NoSuchFieldException on + BeanELResolver.properties + +jetty-7.6.0.RC3 - 05 January 2012 + + 367433 added tests to investigate + + 367435 improved D00 test harness + + 367485 HttpExchange canceled before response do not release connection + + 367502 WebSocket connections should be closed when application context is + stopped. + + 367591 corrected configuration.xml version to 7.6 + + 367635 Added support for start.d directory + + 367638 limit number of form parameters to avoid DOS + + JETTY-1467 close half closed when idle + +jetty-7.6.0.RC3 - 05 January 2012 + + 367433 added tests to investigate + + 367435 improved D00 test harness + + 367485 HttpExchange canceled before response do not release connection + + 367502 WebSocket connections should be closed when application context is + stopped. + + 367591 corrected configuration.xml version to 7.6 + + 367635 Added support for start.d directory + + 367638 limit number of form parameters to avoid DOS + + JETTY-1467 close half closed when idle + jetty-8.1.0.RC2 - 22 December 2011 + 359329 jetty-jaspi must exports its packages. jetty-plus must import javax.security @@ -5947,17 +6044,6 @@ + JETTY-1463 websocket D0 parser should return progress even if no fill done + JETTY-1465 NPE in ContextHandler.toString -jetty-7.6.0.RC3 - 05 January 2012 - + 367433 added tests to investigate - + 367435 improved D00 test harness - + 367485 HttpExchange canceled before response do not release connection - + 367502 WebSocket connections should be closed when application context is - stopped. - + 367591 corrected configuration.xml version to 7.6 - + 367635 Added support for start.d directory - + 367638 limit number of form parameters to avoid DOS - + JETTY-1467 close half closed when idle - jetty-7.6.0.RC2 - 22 December 2011 + 364638 HttpParser closes if data received while seeking EOF. Tests fixed to cope @@ -5978,66 +6064,6 @@ + JETTY-1463 websocket D0 parser should return progress even if no fill done + JETTY-1465 NPE in ContextHandler.toString -jetty-8.1.0.RC1 - 06 December 2011 - + 360245 The version of the javax.servlet packages to import is 2.6 instead of - 3.0 - + 365370 ServletHandler can fall through to nested handler - -jetty-8.1.0.RC0 - 30 November 2011 - + 352565 cookie httponly flag ignored - + 353285 ServletSecurity annotation ignored - + 357163 jetty 8 ought to proxy jetty8 javadocs - + 357209 JSP tag listeners not called - + 360051 SocketConnectionTest.testServerClosedConnection is excluded - + 361135 Allow session cookies to NEVER be marked as secure, even on HTTPS - requests. - + 362249 update shell scripts to jetty8 - + 363878 Add ecj compiler to jetty-8 for jsp - + 364283 can't parse the servlet multipart-config for the web.xml - + 364430 Support web.xml enabled state for servlets - -jetty-7.6.0.RC5 - 20 January 2012 - + 359329 Prevent reinvocation of LoginModule.login with jaspi for already - authed user - + 368632 Remove superfluous removal of org.apache.catalina.jsp_file - + 368633 fixed configure.dtd resource mappings - + 368635 moved lifecycle state reporting from toString to dump - + 368773 process data constraints without realm - + 368787 always set token view to new header buffers in httpparser - + 368821 improved test harness - + 368920 JettyAwareLogger always formats the arguments - + 368948 POM for jetty-jndi references unknown version for javax.activation - + 368992 avoid non-blocking flush when writing to avoid setting !_writable - without _writeblocked - + JETTY-1475 made output state fields volatile to provide memory barrier for - non dispatched thread IO - -jetty-7.6.0.RC4 - 13 January 2012 - + 365048 jetty Http client does not send proxy authentication when requesting - a Https-resource through a web-proxy. - + 366774 removed XSS vulnerbility - + 367099 Upgrade jetty-websocket for RFC 6455 - Addendum - + 367716 simplified idleTimeout logic - + 368035 WebSocketClientFactory does not invoke super.doStop() - + 368060 do not encode sendRedirect URLs - + 368114 Protect against non-Strings in System properties for Log - + 368189 WebSocketClientFactory should not manage external thread pool - + 368215 Remove debug from jaspi - + 368240 Improve AggregateLifeCycle handling of shared lifecycles - + 368291 Change warning to info for NoSuchFieldException on - BeanELResolver.properties - -jetty-7.6.0.RC3 - 05 January 2012 - + 367433 added tests to investigate - + 367435 improved D00 test harness - + 367485 HttpExchange canceled before response do not release connection - + 367502 WebSocket connections should be closed when application context is - stopped. - + 367591 corrected configuration.xml version to 7.6 - + 367635 Added support for start.d directory - + 367638 limit number of form parameters to avoid DOS - + JETTY-1467 close half closed when idle - jetty-7.6.0.RC2 - 22 December 2011 + 364638 HttpParser closes if data received while seeking EOF. Tests fixed to cope @@ -6058,6 +6084,11 @@ + JETTY-1463 websocket D0 parser should return progress even if no fill done + JETTY-1465 NPE in ContextHandler.toString +jetty-8.1.0.RC1 - 06 December 2011 + + 360245 The version of the javax.servlet packages to import is 2.6 instead of + 3.0 + + 365370 ServletHandler can fall through to nested handler + jetty-7.6.0.RC1 - 04 December 2011 + 352565 cookie httponly flag ignored + 353285 ServletSecurity annotation ignored @@ -6072,6 +6103,19 @@ + 364430 Support web.xml enabled state for servlets + 365370 ServletHandler can fall through to nested handler +jetty-8.1.0.RC0 - 30 November 2011 + + 352565 cookie httponly flag ignored + + 353285 ServletSecurity annotation ignored + + 357163 jetty 8 ought to proxy jetty8 javadocs + + 357209 JSP tag listeners not called + + 360051 SocketConnectionTest.testServerClosedConnection is excluded + + 361135 Allow session cookies to NEVER be marked as secure, even on HTTPS + requests. + + 362249 update shell scripts to jetty8 + + 363878 Add ecj compiler to jetty-8 for jsp + + 364283 can't parse the servlet multipart-config for the web.xml + + 364430 Support web.xml enabled state for servlets + jetty-7.6.0.RC0 - 29 November 2011 + 349110 fixed bypass chunk handling + 360546 handle set count exceeding max integer @@ -6137,6 +6181,10 @@ + 348978 migrate jetty-http-spi + 358649 StdErrLog system properties for package/class logging LEVEL +jetty-7.5.3.v20111011 - 11 October 2011 + + 348978 migrate jetty-http-spi + + 358649 StdErrLog system properties for package/class logging LEVEL + jetty-8.0.2.v20111006 - 06 October 2011 + 336443 add missing comma in DigestAuthenticator string + 342161 ScannerTest fails intermittently on Mac OS X @@ -6189,10 +6237,6 @@ + JETTY-1434 Add a jsp that exercises jstl + JETTY-1439 space in directory installation path causes classloader problem -jetty-7.5.3.v20111011 - 11 October 2011 - + 348978 migrate jetty-http-spi - + 358649 StdErrLog system properties for package/class logging LEVEL - jetty-7.5.2.v20111006 - 06 October 2011 + 336443 check nonce count is increasing + 342161 ScannerTest fails intermittently on Mac OS X @@ -6314,13 +6358,6 @@ + Enable annotations by default + Merge from jetty-7.4.3 -jetty-8.0.0.M3 - 27 May 2011 - + 324505 Implement API login - + 335500 request.getParts() throws a NullPointerException - + 343472 isUserInRole does not prevent subsequent login call - + 346180 jsp-2.2 support - + Updated to jetty-7.4.2.v20110526 - jetty-7.5.0.RC0 - 15 August 2011 + 298502 Handle 200 Connect responses with no content-length + 347484 / - > ${/} in some paths in grant codebases @@ -6396,7 +6433,14 @@ HTttpExchange.setRequestContentSource(InputStream) + JETTY-1390 RewriteHandler handles encoded URIs -jetty-7.4.2.v20110526 +jetty-8.0.0.M3 - 27 May 2011 + + 324505 Implement API login + + 335500 request.getParts() throws a NullPointerException + + 343472 isUserInRole does not prevent subsequent login call + + 346180 jsp-2.2 support + + Updated to jetty-7.4.2.v20110526 + +jetty-7.4.2.v20110526 - 26 May 2011 + 334443 Improve the ability to specify extra class paths using the Jetty Maven Plugin + 336220 tmp directory is not set if you reload a webapp with @@ -6421,7 +6465,7 @@ + JETTY-1146 Encode jsessionid in sendRedirect + JETTY-1342 Recreate selector if wakeup throws JVM bug -jetty-7.4.1.v20110513 +jetty-7.4.1.v20110513 - 13 May 2011 + 288563 remove unsupported and deprecated --secure option + 332907 Add context property to ObjectName of JMX MBeans + 336056 Ability to override the computation of the ContextHandler to deploy @@ -6457,13 +6501,13 @@ + JETTY-1343 IllegalArgumentException for bad % encodings + JETTY-1347 Updated ServletHander javadoc -jetty-7.4.0.v20110414 +jetty-7.4.0.v20110414 - 14 April 2011 + 342504 Scanner Listener + 342700 refine websocket API for anticipated changes + JETTY-1362 Set root cause of UnavailableException + Various test harness cleanups to avoid random failures -jetty-7.4.0.RC0 +jetty-7.4.0.RC0 - 07 April 2011 + 324110 Added test harnesses for merging of QueryStrings + 337685 Update websocket API in preparation for draft -07 + 338627 HashSessionManager.getIdleSavePeriod returns milliseconds instead of @@ -6503,26 +6547,6 @@ + Added extra session removal test + Ensure generated fragment names are unique -jetty-8.0.0.M2 - 16 November 2010 - + 320073 Reconsile configuration mechanism - + 321068 JSF2 fails to initialize - + 324493 Registration init parameter handling null check, setInitParameters - additive - + 324505 Request.login method must throw ServletException if it cant login - + 324872 allow disabling listener restriction from using *Registration - interfaces - + 327416 Change meaning of @HandlesTypes in line with latest interpretation by - JSR315 - + 327489 Change meaning of @MultipartConfig to match servlet spec 3.0 - maintenance release 3.0a - + 328008 Handle update to Servlet Spec 3 Section 8.2.3.h.ii - + 330188 Reject web-fragment.xml with same as another already loaded - one - + 330208 Support new wording on servlet-mapping and filter-mapping merging - from servlet3.0a - + 330292 request.getParts() returns only one part when the name is the same - + Update to jetty-7.2.1.v20101111 - jetty-7.3.1.v20110307 - 07 March 2011 + 316382 Support a more strict SSL option with certificates + 333481 Handle UCS-4 codepoints in decode and encode @@ -6624,6 +6648,26 @@ + JETTY-1307 Check that JarFileResource directories end with / + JETTY-1308 327109 (re)fixed AJP handling of empty packets +jetty-8.0.0.M2 - 16 November 2010 + + 320073 Reconsile configuration mechanism + + 321068 JSF2 fails to initialize + + 324493 Registration init parameter handling null check, setInitParameters + additive + + 324505 Request.login method must throw ServletException if it cant login + + 324872 allow disabling listener restriction from using *Registration + interfaces + + 327416 Change meaning of @HandlesTypes in line with latest interpretation by + JSR315 + + 327489 Change meaning of @MultipartConfig to match servlet spec 3.0 + maintenance release 3.0a + + 328008 Handle update to Servlet Spec 3 Section 8.2.3.h.ii + + 330188 Reject web-fragment.xml with same as another already loaded + one + + 330208 Support new wording on servlet-mapping and filter-mapping merging + from servlet3.0a + + 330292 request.getParts() returns only one part when the name is the same + + Update to jetty-7.2.1.v20101111 + jetty-7.2.1.v20101111 - 11 November 2010 + 324679 Fixed dedection of write before static content + 328008 Handle update to Servlet Spec 3 Section 8.2.3.h.ii @@ -6753,7 +6797,20 @@ + Fix jetty-plus.xml for new configuration names + Improved debug dump -jetty-7.1.6.v20100715 +jetty-6.1.25 - 26 July 2010 + + 320264 Removed duplicate mime.property entries + + JETTY-1212 Long content lengths + + JETTY-1214 Avoid ISE when scavenging invalid session + + JETTY-1223 DefaultServlet: NPE when setting relativeResourceBase and + resourceBase is not set + + JETTY-1226 javax.activation needs to be listed in the system classes + + JETTY-1237 Remember local/remote details of endpoint + + JETTY-1251 protected against closed selector + + COMETD-112 if two threads create the same channel, then create events may + occur after subscribe events + + Jetty-6 is now in maintenance mode. + +jetty-7.1.6.v20100715 - 15 July 2010 + 319519 Warn about duplicate configuration files + 319655 Reset HEAD status + JETTY-1247 synchronize recylcing of SSL NIO buffers @@ -6770,7 +6827,7 @@ + Ensure empty implies exclusion of all fragments + Ensure servlet-api jar class inheritance hierarchy is scanned -jetty-7.1.5.v20100705 +jetty-7.1.5.v20100705 - 05 July 2010 + 288194 Add blacklist/whitelist to ProxyServlet and ProxyHandler + 296570 EOFException for HttpExchange when HttpClient.stop called + 311550 The WebAppProvider should allow setTempDirectory @@ -6796,20 +6853,7 @@ + JETTY-1237 Save local/remote address to be available after close + Update ecj to 3.6 Helios release drop -jetty-6.1.25 - 26 July 2010 - + 320264 Removed duplicate mime.property entries - + JETTY-1212 Long content lengths - + JETTY-1214 Avoid ISE when scavenging invalid session - + JETTY-1223 DefaultServlet: NPE when setting relativeResourceBase and - resourceBase is not set - + JETTY-1226 javax.activation needs to be listed in the system classes - + JETTY-1237 Remember local/remote details of endpoint - + JETTY-1251 protected against closed selector - + COMETD-112 if two threads create the same channel, then create events may - occur after subscribe events - + Jetty-6 is now in maintenance mode. - -jetty-7.1.4.v20100610 +jetty-7.1.4.v20100610 - 10 June 2010 + 292326 Stop continuations if server is stopped + 292814 Make QoSFilter and DoSFilter JMX manageable + 293222 Improve request log to handle/show asynchronous latency @@ -6839,7 +6883,7 @@ + JETTY-547 Delay close after shutdown until request read + JETTY-1231 Support context request log handler -jetty-7.1.3.v20100526 +jetty-7.1.3.v20100526 - 26 May 2010 + 296567 HttpClient RedirectListener handles new HttpDestination + 297598 JDBCLoginService uses hardcoded credential class + 305898 Websocket handles query string in URI @@ -6849,7 +6893,7 @@ + 314177 JSTL support is broken + 314459 support maven3 for builds -jetty-7.1.2.v20100523 +jetty-7.1.2.v20100523 - 23 May 2010 + 308866 Update test suite to JUnit4 - Module jetty-util + 312948 Recycle SSL crypto buffers + 313196 randomly allocate ports for session test @@ -6858,7 +6902,7 @@ + 314009 updated README.txt + Update links to jetty website and wiki on test webapp -jetty-7.1.1.v20100517 +jetty-7.1.1.v20100517 - 17 May 2010 + 302344 Make the list of available contexts if root context is not configured optional + 304803 Remove TypeUtil Integer and Long caches @@ -6940,19 +6984,6 @@ + Merged 7.0.2.v20100331 + Temporarily remove jetty-osgi module to clarify jsp version compatibility -jetty-7.0.2.v20100331 - 31 March 2010 - + 297552 Don't call Continuation timeouts from acceptor tick - + 298236 Additional unit tests for jetty-client - + 306782 httpbis interpretation of 100 continues. Body never skipped - + 306783 NPE in StdErrLog when Throwable is null - + 306840 Suppress content-length in requests with no content - + 306880 Support for UPGRADE in HttpClient - + 306884 Suspend with timeout <=0 never expires - + 307589 updated servlet 3.0 continuations for final API - + Allow Configuration array to be set on Server instance for all web apps - + Ensure webapps with no WEB-INF don't scan WEB-INF/lib - + Take excess logging statements out of startup - jetty-6.1.24 - 21 April 2010 + 308925 Protect the test webapp from remote access + JETTY-903 Stop both caches @@ -7021,7 +7052,20 @@ + Remove references to old content in HttpClient client tests for www.sun.com + Updated JSP to 2.1.v20091210 -jetty-7.0.2.RC0 +jetty-7.0.2.v20100331 - 31 March 2010 + + 297552 Don't call Continuation timeouts from acceptor tick + + 298236 Additional unit tests for jetty-client + + 306782 httpbis interpretation of 100 continues. Body never skipped + + 306783 NPE in StdErrLog when Throwable is null + + 306840 Suppress content-length in requests with no content + + 306880 Support for UPGRADE in HttpClient + + 306884 Suspend with timeout <=0 never expires + + 307589 updated servlet 3.0 continuations for final API + + Allow Configuration array to be set on Server instance for all web apps + + Ensure webapps with no WEB-INF don't scan WEB-INF/lib + + Take excess logging statements out of startup + +jetty-7.0.2.RC0 - 09 March 2010 + 290765 Reset input for HttpExchange retry + 292799 WebAppDeployer - start a started context? + 292800 ContextDeployer - recursive setting is undone by FilenameFilter @@ -7265,6 +7309,29 @@ + JETTY-1086 Added UncheckedPrintWriter to avoid ignored EOFs + JETTY-1087 Chunked SSL non blocking input +jetty-7.0.0.RC4 - 18 August 2009 + + 279820 Fixed HotSwapHandler + + 285891 SessionAuthentication is serializable + + 286185 Implement ability for JSON implementation to automatically register + convertors + + 286535 ContentExchange status code + + JETTY-1057 XSS error page + + JETTY-1079 ResourceCollection.toString + + JETTY-1080 Ignore files that would be extracted outside the destination + directory when unpacking WARs + + Added discoverable start options + +jetty-7.0.0.RC3 - 07 August 2009 + + 277403 remove system properties + + 282447 concurrent destinations in HttpClient + + 283172 fix Windows build, broken on directory creation with the + DefaultServlet + + 283375 additional error-checking on SSL connector passwords to prevent NPE + + 283513 Check endp.isOpen when blocking read + + 285697 extract parameters if dispatch has query + + JETTY-1074 JMX thread manipulation + + Improved deferred authentication handling + jetty-6.1.19 - 01 July 2009 + JETTY-799 shell script for jetty on cygwin + JETTY-863 Non blocking stats handler @@ -7294,29 +7361,6 @@ + JETTY-1058 Handle trailing / with aliases on + JETTY-1062 Don't filter cometd message without data -jetty-7.0.0.RC4 - 18 August 2009 - + 279820 Fixed HotSwapHandler - + 285891 SessionAuthentication is serializable - + 286185 Implement ability for JSON implementation to automatically register - convertors - + 286535 ContentExchange status code - + JETTY-1057 XSS error page - + JETTY-1079 ResourceCollection.toString - + JETTY-1080 Ignore files that would be extracted outside the destination - directory when unpacking WARs - + Added discoverable start options - -jetty-7.0.0.RC3 - 07 August 2009 - + 277403 remove system properties - + 282447 concurrent destinations in HttpClient - + 283172 fix Windows build, broken on directory creation with the - DefaultServlet - + 283375 additional error-checking on SSL connector passwords to prevent NPE - + 283513 Check endp.isOpen when blocking read - + 285697 extract parameters if dispatch has query - + JETTY-1074 JMX thread manipulation - + Improved deferred authentication handling - jetty-7.0.0.RC2 - 29 June 2009 + 283375 improved extensibility of SSL connectors + 283818 fixed merge of forward parameters @@ -7331,6 +7375,23 @@ + Disassociate method on IdentityService + Improved handling of overlays and resourceCollections +jetty-7.0.0.M3 - 20 June 2009 + + 274251 Allow dispatch to welcome files that are servlets (configurable) + + 276545 Quoted cookie paths + + 277403 Cleanup system property usage + + 277798 Denial of Service Filter + + 279725 Support 100 and 102 expectations + + 280707 client.HttpConnection does not catch and handle non-IOExceptions + + 281470 Handle the case where request.PathInfo() should be "/*" + + Added ContinuationThrowable + + added WebAppContext.setConfigurationDiscovered for servlet 3.0 features + + fixed race with expired async listeners + + Numerous cleanups from static code analysis + + Portable continuations for jetty6 and servlet3 + + Refactored AbstractBuffers to HttpBuffers for performance + + refactored configuration mechanism + + Refactored continuations to only support response wrapping + jetty-7.0.0.RC1 - 15 June 2009 + 283344 Startup on windows is broken + JETTY-1066 283357 400 response for bad URIs @@ -7357,23 +7418,6 @@ + JETTY-1055 Cookie quoting + JETTY-1057 Error page stack trace XSS -jetty-7.0.0.M3 - 20 June 2009 - + 274251 Allow dispatch to welcome files that are servlets (configurable) - + 276545 Quoted cookie paths - + 277403 Cleanup system property usage - + 277798 Denial of Service Filter - + 279725 Support 100 and 102 expectations - + 280707 client.HttpConnection does not catch and handle non-IOExceptions - + 281470 Handle the case where request.PathInfo() should be "/*" - + Added ContinuationThrowable - + added WebAppContext.setConfigurationDiscovered for servlet 3.0 features - + fixed race with expired async listeners - + Numerous cleanups from static code analysis - + Portable continuations for jetty6 and servlet3 - + Refactored AbstractBuffers to HttpBuffers for performance - + refactored configuration mechanism - + Refactored continuations to only support response wrapping - jetty-7.0.0.M2 - 18 May 2009 + 273767 Update to use geronimo annotations spec 1.1.1 + 275396 Added ScopedHandler to set servlet scope before security handler @@ -7391,6 +7435,11 @@ + JETTY-1020 ZipException in org.mortbay.jetty.webapp.TagLibConfiguration prevents all contexts from being loaded +jetty-5.1.15 - 18 May 2009 + + JETTY-418 synchronized load class + + JETTY-1004 CERT VU402580 Canonical path handling includes ? in path segment + + Fixes for CERT438616-CERT237888-CERT21284 + jetty-6.1.18 - 16 May 2009 + JETTY-937 Improved work around sun JVM selector bugs + JETTY-1004 CERT VU#402580 Canonical path handling includes ? in path segment @@ -7405,11 +7454,6 @@ prevents all contexts from being loaded + JETTY-1022 Removed several 1.5isms -jetty-5.1.15 - 18 May 2009 - + JETTY-418 synchronized load class - + JETTY-1004 CERT VU402580 Canonical path handling includes ? in path segment - + Fixes for CERT438616-CERT237888-CERT21284 - jetty-6.1.17 - 30 April 2009 + JETTY-936 Make optional dispatching to welcome files as servlets + JETTY-937 Work around sun JVM selector bugs @@ -7559,7 +7603,7 @@ + moved to org.eclipse packages + simplified HandlerContainer API -jetty-6.1.15 - 04 March 2009 +jetty-6.1.15 - 02 March 2009 + JETTY-923 BayeuxClient uses message pools to reduce memory footprint + JETTY-924 Improved BayeuxClient disconnect handling + JETTY-925 Lazy bayeux messages @@ -8217,13 +8261,18 @@ + Use terracotta repo for build; make jetty a terracotta module + UTF-8 for bayeux client +jetty-5.1.14 - 09 August 2007 + + JETTY-155 force close with content length + + JETTY-369 failed state in Container + + patched with correct version + jetty-6.1.5 - 19 July 2007 + JETTY-392 updated LikeJettyXml example + Fixed GzipFilter for dispatchers + Fixed reset of reason + Upgrade to Jasper 2.1 tag SJSAS-9_1-B50G-BETA3-27_June_2007 -jetty-6.1.5rc0 - 15 July 0200 +jetty-6.1.5rc0 - 15 July 2007 + JETTY-253 Improved graceful shutdown + JETTY-373 Stop all dependent lifecycles + JETTY-374 HttpTesters handles large requests/responses @@ -8481,7 +8530,7 @@ + start webapps on deployment with jboss, use isDistributed() method from WebAppContext -jetty-6.1.0 - 09 January 2007 +jetty-6.1.0 - 05 January 2007 + Fixed unpacking WAR jetty-6.1.0 - 05 January 2007 @@ -8613,14 +8662,6 @@ + updated glassfish jasper to tag SJSAS-9_1-B25-EA-08_Nov_2006 + Upgraded session ID generation to use SecureRandom -jetty-5.1.14 - 09 August 2007 - + JETTY-155 force close with content length - + JETTY-369 failed state in Container - + patched with correct version - -jetty-5.1.13 - + Sourceforge 1648335: problem setting version for AJP13 - jetty-5.1.12 - 22 November 2006 + JETTY-154 Cookies ignore single quotes + Added support for TLS_DHE_RSA_WITH_AES_256_CBC_SHA @@ -8769,6 +8810,39 @@ + use mvn -Dslf4j=false jetty:run to disable use of slf4j logging with jdk1.4/jsp2.0 +jetty-6.0.0ALPHA2 - 20 August 2006 + + Continuations - way cool way to suspend a request and retry later. + + Dispatchers + + Security + +jetty-6.0.0ALPHA1 - 20 August 2006 + + Filters + + web.xml handling + +jetty-6.0.0ALPHA0 - 20 August 2006 + + file may be sent as sent is a single operation. + + Improved "dependancy injection" and "inversion of control" design of + components + + Improved "interceptor" design of handlers + + Missing Request Dispatchers + + Missing Security + + Missing war support + + Missing web.xml based configuration + + Optional use of NIO Buffering so that efficient direct buffers and memory + mapped files can be used. + + Optional use of NIO gather writes, so that for example a HTTP header and a + memory mapped + + Optional use of NIO non-blocking scheduling so that threads are not + allocated per connection. + + Smart split buffer design allows large buffers to only be allocated to + active connections. The resulting memory savings allow very large buffers to + be used, which increases the chance of efficient asynchronous flushing and + of avoiding chunking. + + Totally rearchitected and rebuilt, so 10 years of cruft could be removed! + +jetty-6.0.0ALPHA3 - 20 August 2006 + + Added demo for Continuations + jetty-6.0.0rc1 - 16 August 2006 + JETTY-85 JETTY-86 (TrustManager and SecureRandom are now configurable; better handling of null/default values) @@ -8840,7 +8914,7 @@ + Updated javax code from http://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk/java/javax@417727 -jetty-6.0.0beta17 - 01 June 2006 +jetty-6.0.0beta17 - 02 June 2006 + Added clover reports and enough tests to get >50% coverage + Added config to disable file memory mapped buffers for windows + Added Request.isHandled() @@ -8856,7 +8930,7 @@ + Recovered repository from Codehaus crash + Refactored Synchronization of SelectChannelConnector -jetty-6.0.0beta16 - 12 May 2006 +jetty-6.0.0beta16 - 15 May 2006 + remove a couple of System.err.printlns + replace backwards compativle API in UrlEncoded @@ -8911,6 +8985,15 @@ + stop JDBCUserRealm coercing all credentials to String + Use start.config to select which JSP impl at runtime based on jdk version +jetty-5.1.11RC0 - 05 April 2006 + + Added provider support to SslListener + + Fixed AJP handling of ;jsessionid. + + force close with shutdownOutput for win32 + + improved contentType param handling + + logging improvements for servlet and runtime exceptions + + NPE protection if desirable client certificates + + stop JDBCUserRealm forcing all credentials to be String + jetty-6.0.0beta12 - 16 March 2006 + Added JSP2.0 demos to test webapp + Added provider support to SslListener @@ -8934,7 +9017,12 @@ + refactored session ID management + refactored writers and improved UTF-8 generation. -jetty-6.0.0beta10 - 25 February 2006 +jetty-6.0.0beta0 - 27 February 2006 + + Dispatcher parameters + + Fixed blocking read + + Maven 2 build + +jetty-6.0.0beta10 - 24 February 2006 + added getLocalPort() to connector + Added support for java:comp/env + Added support for pluggable transaction manager @@ -8948,7 +9036,7 @@ + Forward masks include attributes and vice versa + Updates javax to MR2 release -jetty-6.0.0beta9 - 09 February 2006 +jetty-6.0.0beta9 - 14 February 2006 + Added CGI servlet. + Added request log. + Added TLD tag listener handling. @@ -8962,7 +9050,7 @@ + PathMap for direct context mapping. + Refactored chat demo and upgraded prototype.js -jetty-6.0.0beta8 - 24 January 2006 +jetty-6.0.0beta8 - 25 January 2006 + conveniance addHandler removeHandler methods + fixed bug in overloaded write method on HttpConnection (reported against Tapestry4.0) @@ -8979,7 +9067,7 @@ + reinstated rfc2616 test harness + Removed queue from thread pool. -jetty-6.0.0Beta7 +jetty-6.0.0beta7 - 10 January 2006 + Faster header name lookup + Fixed infinite loop with chunk handling + maven-jetty6-plugin added tmpDirectory property @@ -8987,96 +9075,6 @@ directory + null dispatch attributes not in names + reduced info verbosity - + removed singleton Container - -jetty-6.0.0Beta6 - + Fixed issue with blocking reads - + Fixed issue with unknown headers - + optimizations - -jetty-6.0.0Beta5 - + Added management module for mbeans - + Fixed writer char[] creations - + Moved to SVN - -jetty-6.0.0Beta4 - + CVE-2006-2758 Fixed JSP visibility security issue. - + Improved jetty-web.xml access to org.mortbay classes. - + Jasper 5.5.12 - + System property support in plugin - -jetty-6.0.0Beta3 - + Fixed classloader issue with server classes - + Fixed error in block read - + Named dispatch. - -jetty-6.0.0Beta2 - + Improved buffer return - + Improved reuse of HttpField values and cookies. - + loosely coupled with JSP servlet - + loosely coupled with SLF4J - + merged util jar back into jetty jar - + Simpler continuation API - -jetty-6.0.0Beta1 - + Error pages - + Implemented all listeners - + maven2 plugin - + Multiple select sets - + refactored start/stop - + Servlet 2.5 API - + shutdown hook - + SSL connector - + Virtual hosts - -jetty-6.0.0Beta0 - + Dispatcher parameters - + Fixed blocking read - + Maven 2 build - + UTF-8 encoding for URLs - -jetty-6.0.0APLPA3 - + Added demo for Continuations - + Jasper and associated libraries. - -jetty-6.0.0ALPHA2 - + Continuations - way cool way to suspend a request and retry later. - + Dispatchers - + Security - -jetty-6.0.0ALPHA1 - + Filters - + web.xml handling - -jetty-6.0.0ALPHA0 - + file may be sent as sent is a single operation. - + Improved "dependancy injection" and "inversion of control" design of - components - + Improved "interceptor" design of handlers - + Missing Request Dispatchers - + Missing Security - + Missing war support - + Missing web.xml based configuration - + Optional use of NIO Buffering so that efficient direct buffers and memory - mapped files can be used. - + Optional use of NIO gather writes, so that for example a HTTP header and a - memory mapped - + Optional use of NIO non-blocking scheduling so that threads are not - allocated per connection. - + Smart split buffer design allows large buffers to only be allocated to - active connections. The resulting memory savings allow very large buffers to - be used, which increases the chance of efficient asynchronous flushing and - of avoiding chunking. - + Totally rearchitected and rebuilt, so 10 years of cruft could be removed! - -jetty-5.1.11RC0 - 05 April 2006 - + Added provider support to SslListener - + Fixed AJP handling of ;jsessionid. - + force close with shutdownOutput for win32 - + improved contentType param handling - + logging improvements for servlet and runtime exceptions - + NPE protection if desirable client certificates - + stop JDBCUserRealm forcing all credentials to be String jetty-5.1.10 - 05 January 2006 + Fixed path aliasing with // on windows. @@ -9088,12 +9086,13 @@ jetty-4.2.25 - 04 January 2006 + Fixed aliasing of // for win32 +jetty-6.0.0beta6 - 09 December 2005 + + Fixed issue with blocking reads + + Fixed issue with unknown headers + jetty-5.1.9 - 07 December 2005 + Fixed wantClientAuth(false) overriding netClientAuth(true) -jetty-6.0.0betaX - + See http://jetty.mortbay.org/jetty6 for 6.0 releases - jetty-5.1.8 - 07 December 2005 + Fixed space in URL issued created in 5.1.6 @@ -9110,10 +9109,40 @@ + Updated to 2.6.2 xerces + use commons logging jar instead of api jar. +jetty-6.0.0beta5 - 05 December 2005 + + Added management module for mbeans + + Fixed writer char[] creations + +jetty-6.0.0beta4 - 22 November 2005 + + Fixed JSP visibility security issue (CVE-2006-2758) + + Improved jetty-web.xml access to org.mortbay classes. + + Jasper 5.5.12 + jetty-5.1.6 - 18 November 2005 + CVE-2006-2758 Fixed JSP visibility security issue. + Improved jetty-web.xml access to org.mortbay classes. +jetty-6.0.0beta3 - 17 November 2005 + + Fixed classloader issue with server classes + + Fixed error in block read + +jetty-6.0.0beta2 - 14 November 2005 + + Improved buffer return + + Improved reuse of HttpField values and cookies. + + loosely coupled with JSP servlet + + loosely coupled with SLF4J + + merged util jar back into jetty jar + +jetty-6.0.0beta1 - 11 November 2005 + + Error pages + + Implemented all listeners + + maven2 plugin + + Multiple select sets + + refactored start/stop + + Servlet 2.5 API + + shutdown hook + + SSL connector + jetty-5.1.5 - 10 November 2005 + Improved mapping of JSP files. + Improved shutdown hook @@ -9164,6 +9193,9 @@ + Stop start.jar putting current directory on classpath. + Turn off web.xml validation for JBoss. +jetty-5.1.13 - 07 April 2005 + + Sourceforge 1648335: problem setting version for AJP13 + jetty-5.1.3 - 07 April 2005 + Some minor code janitorial services @@ -9192,7 +9224,7 @@ + JettyPlus updated to JOTM 2.0.5, XAPool 1.4.2 + update to demo site look and feel. -jetty-4.2.24rc1 +jetty-4.2.24rc1 - 11 March 2005 + Fixed principal naming in FormAuthenticator jetty-5.1.3rc0 - 08 March 2005 @@ -9239,7 +9271,7 @@ jetty-5.1.1 - 01 December 2004 -jetty-5.1.1RC1 +jetty-5.1.1RC1 - 24 November 2004 + Allow double // within URIs + Applied patch for MD5 hashed credentials for MD5 + Fixed ordering of filters with multiple interleaved mappings. @@ -9299,7 +9331,7 @@ + Less verbose warning for non validating xml parser. + Update to jasper 5.0.27 -jetty-4.2.22 +jetty-4.2.22 - 24 August 2004 + Added parameters for acceptQueueSize and lowResources level. + fixed deployment of ejb-link elements in web.xml for jboss + fixed jaas logout for jetty-jboss integration @@ -9370,6 +9402,14 @@ jetty-4.2.19 - 19 March 2004 + Fixed DOS attack problem +jetty-4.2.18 - 01 March 2004 + + Added log4j context repository to jettyplus + + Default servlet respectes servlet path + + Fixed j2se 1.3 problem with HttpFields + + Improved log performance + + NPE guard for no-listener junit deployment + + Suppress some more IOExceptions + jetty-5.0.beta2 - 12 February 2004 + Added experimental NIO listeners again. + Added log4j context repository to jettyplus @@ -9389,14 +9429,6 @@ + RequestDispatcher uses request encoding for query params + Updated to Japser 5.0.16 -jetty-4.2.18 - 01 March 2004 - + Added log4j context repository to jettyplus - + Default servlet respectes servlet path - + Fixed j2se 1.3 problem with HttpFields - + Improved log performance - + NPE guard for no-listener junit deployment - + Suppress some more IOExceptions - jetty-4.2.17 - 01 February 2004 + Fixed busy loop in threadpool run + Reorganized ServletHolder init @@ -9516,15 +9548,6 @@ + Synced with 4.2.12 + Updated to Jasper 5.0.7 -jetty-5.0.alpha0 - 16 July 2003 - + Compiled against 2.4 servlet spec. - + Implemented Dispatcher forward attributes. - + Implemented filter-mapping element - + Implemented remote/local addr/port methods - + Implemented setCharaterEncoding - + Updated authentication so that a normal Principal is used. - + updated to jasper 5.0.3 - jetty-4.2.12 - 12 August 2003 + Added missing S to some OPTIONS strings + Added open method to threaded server. @@ -9537,6 +9560,15 @@ + Removed protection of org.mortbay.http attributes + Restore max inactive interval for session manager +jetty-5.0.alpha0 - 16 July 2003 + + Compiled against 2.4 servlet spec. + + Implemented Dispatcher forward attributes. + + Implemented filter-mapping element + + Implemented remote/local addr/port methods + + Implemented setCharaterEncoding + + Updated authentication so that a normal Principal is used. + + updated to jasper 5.0.3 + jetty-4.2.11 - 12 July 2003 + Branched for Jetty 5 development. + Cookie params all in lower case. @@ -10666,6 +10698,11 @@ + Prevented multiple init of ServletHolder + Replaced ISO-8859-1 literals with StringUtil static +jetty-2.4.8 - 23 October 2000 + + Fixed bug with 304 replies with bodies. + + Fixed closing socket problem + + Improved win32 make files. + jetty-3.0.0.rc1 - 22 October 2000 + Added CGI to demo + Added HashUserRealm and cleaned up security constraints @@ -10678,11 +10715,6 @@ + Partial handling of 0.9 requests. + removed Thread.destroy() calls. -jetty-2.4.8 - 23 October 2000 - + Fixed bug with 304 replies with bodies. - + Fixed closing socket problem - + Improved win32 make files. - jetty-3.0.B05 - 18 October 2000 + Added default webapp servlet mapping /servlet/name/* + Cleaned up response committing and flushing @@ -11457,41 +11489,41 @@ + ServletHandler now takes an optional file base directory name which is used to set the translated path for pathInfo in servlet requests. -jetty-1.3.3 +jetty-1.3.3 - 01 March 1998 + Closed exception window in HttpListener.java + Fixed TableForm.addButtonArea bug. + TableForm.extendRow() uses existing cell -jetty-1.3.2 +jetty-1.3.2 - 20 February 1998 + Added per Table cell composite factories + Fixed proxy bug with no port number -jetty-1.3.1 +jetty-1.3.1 - 12 February 1998 + Better handling of InvocationTargetException in debug + ForwardHandler only forwards as http/1.0 (from Tobias.Miller) + Improved parsing of stack traces + Minor fixes in SmtpMail + Minor release adjustments for Tracker -jetty-1.3.0 +jetty-1.3.0 - 03 February 1998 + Added DbAdaptor to JDBC wrappers + Beta release of Tracker -jetty-1.2.0 +jetty-1.2.0 - 22 January 1998 + Alternate look and feel for Jetty + Better Debug configuration + DebugServlet + Fixed install bug for nested classes + Reintroduced STF -jetty-1.1.1 +jetty-1.1.1 - 13 January 1998 + Improved documentation -jetty-1.1 +jetty-1.1 - 09 January 1998 + Improved connection caching in java.mortbay.JDBC + Moved HttpCode to com.mortbay.Util -jetty-1.0.1 +jetty-1.0.1 - 06 January 1998 + Bug fixes jetty-1.0 - 01 January 1998 diff -Nru jetty9-9.4.50/aggregates/jetty-all/pom.xml jetty9-9.4.57/aggregates/jetty-all/pom.xml --- jetty9-9.4.50/aggregates/jetty-all/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/aggregates/jetty-all/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 ../../pom.xml 4.0.0 diff -Nru jetty9-9.4.50/aggregates/jetty-all/src/main/resources/META-INF/MANIFEST.MF jetty9-9.4.57/aggregates/jetty-all/src/main/resources/META-INF/MANIFEST.MF --- jetty9-9.4.50/aggregates/jetty-all/src/main/resources/META-INF/MANIFEST.MF 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/aggregates/jetty-all/src/main/resources/META-INF/MANIFEST.MF 2024-12-19 21:51:26.000000000 +0000 @@ -4,5 +4,5 @@ Implementation-Vendor: Eclipse Jetty Project Implementation-Vendor-Id: org.eclipse.jetty Implementation-Version: @project.version@ -X-License: https://www.eclipse.org/jetty/licenses.php +X-License: https://jetty.org/licenses.html diff -Nru jetty9-9.4.50/aggregates/jetty-all-compact3/pom.xml jetty9-9.4.57/aggregates/jetty-all-compact3/pom.xml --- jetty9-9.4.50/aggregates/jetty-all-compact3/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/aggregates/jetty-all-compact3/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 ../../pom.xml 4.0.0 @@ -83,7 +83,7 @@ development - https://eclipse.org/jetty + https://jetty.org/ ${user.name} org.eclipse.jetty https://raw.githubusercontent.com/eclipse/jetty.project/master/NOTICE.txt diff -Nru jetty9-9.4.50/aggregates/jetty-websocket-all/pom.xml jetty9-9.4.57/aggregates/jetty-websocket-all/pom.xml --- jetty9-9.4.50/aggregates/jetty-websocket-all/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/aggregates/jetty-websocket-all/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -65,7 +65,7 @@ development - https://eclipse.org/jetty + https://jetty.org/ ${user.name} org.eclipse.jetty https://raw.githubusercontent.com/eclipse/jetty.project/master/NOTICE.txt diff -Nru jetty9-9.4.50/apache-jsp/pom.xml jetty9-9.4.57/apache-jsp/pom.xml --- jetty9-9.4.50/apache-jsp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/apache-jsp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 apache-jsp diff -Nru jetty9-9.4.50/apache-jsp/src/main/config/modules/apache-jsp.mod jetty9-9.4.57/apache-jsp/src/main/config/modules/apache-jsp.mod --- jetty9-9.4.50/apache-jsp/src/main/config/modules/apache-jsp.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/apache-jsp/src/main/config/modules/apache-jsp.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables use of the apache implementation of JSP diff -Nru jetty9-9.4.50/apache-jstl/pom.xml jetty9-9.4.57/apache-jstl/pom.xml --- jetty9-9.4.50/apache-jstl/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/apache-jstl/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 apache-jstl diff -Nru jetty9-9.4.50/apache-jstl/src/main/config/modules/apache-jstl.mod jetty9-9.4.57/apache-jstl/src/main/config/modules/apache-jstl.mod --- jetty9-9.4.50/apache-jstl/src/main/config/modules/apache-jstl.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/apache-jstl/src/main/config/modules/apache-jstl.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables the apache version of JSTL diff -Nru jetty9-9.4.50/build-resources/pom.xml jetty9-9.4.57/build-resources/pom.xml --- jetty9-9.4.50/build-resources/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/build-resources/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ 4.0.0 org.eclipse.jetty build-resources - 9.4.50.v20221107 + 9.4.57.v20241219 jar Jetty :: Build Resources diff -Nru jetty9-9.4.50/debian/changelog jetty9-9.4.57/debian/changelog --- jetty9-9.4.50/debian/changelog 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/changelog 2025-04-01 17:22:08.000000000 +0000 @@ -1,77 +1,77 @@ -jetty9 (9.4.50-4+deb12u3) bookworm-security; urgency=high +jetty9 (9.4.57-0+deb12u1) bookworm-security; urgency=high * Team upload. - * Fix CVE-2024-22201: - It was discovered that remote attackers may leave many HTTP/2 connections - in ESTABLISHED state (not closed), TCP congested and idle. Eventually the - server will stop accepting new connections from valid clients which can - cause a denial of service. - - -- Markus Koschany Sun, 07 Apr 2024 22:26:26 +0200 - -jetty9 (9.4.50-4+deb12u2) bookworm-security; urgency=high - - * Team upload. - * Fix CVE-2023-36478 and CVE-2023-44487: - Two remotely exploitable security vulnerabilities were discovered in Jetty - 9, a Java based web server and servlet engine. The HTTP/2 protocol - implementation did not sufficiently verify if HPACK header values exceed - their size limit. Furthermore the HTTP/2 protocol allowed a denial of - service (server resource consumption) because request cancellation can - reset many streams quickly. This problem is also known as Rapid Reset - Attack. - - -- Markus Koschany Sun, 29 Oct 2023 16:12:42 +0100 - -jetty9 (9.4.50-4+deb12u1) bookworm-security; urgency=high - - * Team upload. - * The org.eclipse.jetty.servlets.CGI has been deprecated. It is potentially - unsafe to use it. The upstream developers of Jetty recommend to use Fast CGI - instead. See also CVE-2023-36479. - * Fix CVE-2023-26048: - Jetty is a java based web server and servlet engine. In affected versions - servlets with multipart support (e.g. annotated with `@MultipartConfig`) - that call `HttpServletRequest.getParameter()` or - `HttpServletRequest.getParts()` may cause `OutOfMemoryError` when the - client sends a multipart request with a part that has a name but no - filename and very large content. This happens even with the default - settings of `fileSizeThreshold=0` which should stream the whole part - content to disk. - * Fix CVE-2023-26049: - Nonstandard cookie parsing in Jetty may allow an attacker to smuggle - cookies within other cookies, or otherwise perform unintended behavior by - tampering with the cookie parsing mechanism. - * Fix CVE-2023-40167: - Prior to this version Jetty accepted the `+` character proceeding the - content-length value in a HTTP/1 header field. This is more permissive than - allowed by the RFC and other servers routinely reject such requests with - 400 responses. There is no known exploit scenario, but it is conceivable - that request smuggling could result if jetty is used in combination with a - server that does not close the connection after sending such a 400 - response. - * CVE-2023-36479: - Users of the CgiServlet with a very specific command structure may have the - wrong command executed. If a user sends a request to a - org.eclipse.jetty.servlets.CGI Servlet for a binary with a space in its - name, the servlet will escape the command by wrapping it in quotation - marks. This wrapped command, plus an optional command prefix, will then be - executed through a call to Runtime.exec. If the original binary name - provided by the user contains a quotation mark followed by a space, the - resulting command line will contain multiple tokens instead of one. - * Fix CVE-2023-41900: - Jetty is vulnerable to weak authentication. If a Jetty - `OpenIdAuthenticator` uses the optional nested `LoginService`, and that - `LoginService` decides to revoke an already authenticated user, then the - current request will still treat the user as authenticated. The - authentication is then cleared from the session and subsequent requests - will not be treated as authenticated. So a request on a previously - authenticated session could be allowed to bypass authentication after it - had been rejected by the `LoginService`. This impacts usages of the - jetty-openid which have configured a nested `LoginService` and where that - `LoginService` is capable of rejecting previously authenticated users. + * New upstream release 9.4.57. + - Fix CVE-2024-8184: + There exists a security vulnerability in Jetty's + ThreadLimitHandler.getRemote() which can be exploited by unauthorized + users to cause remote denial-of-service (DoS) attack. By repeatedly + sending crafted requests, attackers can trigger OutofMemory errors and + exhaust the server's memory. + - Fix CVE-2024-9823: + There exists a security vulnerability in Jetty's DosFilter which can be + exploited by unauthorized users to cause remote denial-of-service (DoS) + attack on the server using DosFilter. By repeatedly sending crafted + requests, attackers can trigger OutofMemory errors and exhaust the + server's memory finally. + - CVE-2024-6762: Deprecate and warn about using PushSessionCacheFilter and + PushCacheFilter. - -- Markus Koschany Wed, 27 Sep 2023 16:35:19 +0200 + -- Markus Koschany Tue, 01 Apr 2025 19:22:08 +0200 + +jetty9 (9.4.57-1) unstable; urgency=medium + + * New upstream release + + -- Emmanuel Bourg Mon, 03 Mar 2025 13:04:12 +0100 + +jetty9 (9.4.56-1) unstable; urgency=medium + + * New upstream release + + -- Emmanuel Bourg Mon, 07 Oct 2024 17:27:31 +0200 + +jetty9 (9.4.55-1) unstable; urgency=medium + + * New upstream release + - Refreshed the patches + * Standards-Version updated to 4.7.0 + + -- Emmanuel Bourg Fri, 02 Aug 2024 08:55:22 +0200 + +jetty9 (9.4.54-1) unstable; urgency=high + + * Team upload. + * New upstream version 9.4.54. + - Fix CVE-2024-22201: + It was discovered that remote attackers may leave many HTTP/2 connections + in ESTABLISHED state (not closed), TCP congested and idle. Eventually the + server will stop accepting new connections from valid clients which can + cause a denial of service. (Closes: #1064923) + Thanks to Salvatore Bonaccorso for the report. + + -- Markus Koschany Sat, 06 Apr 2024 12:54:58 +0200 + +jetty9 (9.4.53-1) unstable; urgency=medium + + * New upstream release + + -- Emmanuel Bourg Mon, 09 Oct 2023 23:07:28 +0200 + +jetty9 (9.4.52-1) unstable; urgency=medium + + * Team upload. + * New upstream version 9.4.52. + * Refresh the patches. + + -- Markus Koschany Sun, 24 Sep 2023 01:40:05 +0200 + +jetty9 (9.4.51-2) experimental; urgency=medium + + * Team upload. + * Revert switch to libtomcat10-java. (Closes: #1036798) + + -- Markus Koschany Sat, 27 May 2023 16:47:13 +0200 jetty9 (9.4.50-4) unstable; urgency=medium @@ -81,6 +81,19 @@ -- Markus Koschany Sat, 27 May 2023 16:28:19 +0200 +jetty9 (9.4.51-1) experimental; urgency=medium + + * Team upload. + * New upstream release. + * Replace dependency on lsb-base with sysvinit-utils. + - Fix: lintian error depends-on-obsolete-package. + * Add a systemd timer for debian/jetty9.service. + - Fix: lintian warning missing-systemd-timer-for-cron-script. + * Fix lintian warning skip-systemd-native-flag-missing-pre-depends. + * Fix lintian warning mismatched-override. + + -- sun min Wed, 29 Mar 2023 10:10:33 +0800 + jetty9 (9.4.50-3) unstable; urgency=medium * Team upload. diff -Nru jetty9-9.4.50/debian/control jetty9-9.4.57/debian/control --- jetty9-9.4.50/debian/control 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/control 2025-04-01 17:22:08.000000000 +0000 @@ -33,7 +33,7 @@ libwebsocket-api-java, maven-debian-helper (>= 2.2.8~), maven-repo-helper -Standards-Version: 4.6.2 +Standards-Version: 4.7.0 Vcs-Git: https://salsa.debian.org/java-team/jetty9.git Vcs-Browser: https://salsa.debian.org/java-team/jetty9 Homepage: http://www.eclipse.org/jetty/ @@ -41,6 +41,7 @@ Package: libjetty9-java Architecture: all Depends: ${misc:Depends}, libel-api-java, libjsp-api-java, libservlet-api-java, libwebsocket-api-java +Pre-Depends: ${misc:Pre-Depends} Suggests: jetty9 Description: Java servlet engine and webserver -- core libraries Jetty is an Open Source HTTP Servlet Server written in 100% Java. @@ -62,6 +63,7 @@ libtaglibs-standard-spec-java, libtomcat9-java, ${misc:Depends} +Pre-Depends: ${misc:Pre-Depends} Suggests: jetty9 Description: Java servlet engine and webserver -- extra libraries Jetty is an Open Source HTTP Servlet Server written in 100% Java. @@ -81,8 +83,9 @@ libeclipse-jdt-core-java, libjetty9-extra-java (>= ${source:Version}), libjetty9-java (>= ${source:Version}), - lsb-base, + sysvinit-utils (>= 3.05-4~), ${misc:Depends} +Pre-Depends: ${misc:Pre-Depends} Recommends: authbind Description: Java servlet engine and webserver Jetty is an Open Source HTTP Servlet Server written in 100% Java. diff -Nru jetty9-9.4.50/debian/copyright jetty9-9.4.57/debian/copyright --- jetty9-9.4.50/debian/copyright 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/copyright 2025-04-01 17:22:08.000000000 +0000 @@ -6,7 +6,7 @@ jetty-unixsocket/src/test/resources/haproxy Files: * -Copyright: 2006-2022, Mort Bay Consulting Pty. Ltd. +Copyright: 2006-2023, Mort Bay Consulting Pty. Ltd. License: Apache-2.0 or EPL-1.0 Files: jetty-ant/src/main/java/org/eclipse/jetty/ant/utils/TaskLog.java diff -Nru jetty9-9.4.50/debian/jetty9.install jetty9-9.4.57/debian/jetty9.install --- jetty9-9.4.50/debian/jetty9.install 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/jetty9.install 2025-04-01 17:22:08.000000000 +0000 @@ -11,4 +11,5 @@ debian/README.Debian usr/share/doc/jetty9 NOTICE.txt usr/share/doc/jetty9 +debian/jetty9.timer /etc/sytemd/system/jetty9.timer diff -Nru jetty9-9.4.50/debian/jetty9.timer jetty9-9.4.57/debian/jetty9.timer --- jetty9-9.4.50/debian/jetty9.timer 1970-01-01 00:00:00.000000000 +0000 +++ jetty9-9.4.57/debian/jetty9.timer 2025-04-01 17:22:08.000000000 +0000 @@ -0,0 +1,9 @@ +[Unit] +Description=Weekly trigger for jetty9 logging. + +[Timer] +OnCalendar=daily +Persistent=true + +[Install] +WantedBy=multi-user.target diff -Nru jetty9-9.4.50/debian/patches/01-maven-bundle-plugin-version.patch jetty9-9.4.57/debian/patches/01-maven-bundle-plugin-version.patch --- jetty9-9.4.50/debian/patches/01-maven-bundle-plugin-version.patch 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/patches/01-maven-bundle-plugin-version.patch 2025-04-01 17:22:08.000000000 +0000 @@ -8,7 +8,7 @@ --- a/pom.xml +++ b/pom.xml -@@ -436,6 +436,7 @@ +@@ -465,6 +465,7 @@ org.apache.felix maven-bundle-plugin diff -Nru jetty9-9.4.50/debian/patches/02-import-alpn-api.patch jetty9-9.4.57/debian/patches/02-import-alpn-api.patch --- jetty9-9.4.50/debian/patches/02-import-alpn-api.patch 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/patches/02-import-alpn-api.patch 2025-04-01 17:22:08.000000000 +0000 @@ -11,9 +11,6 @@ create mode 100644 jetty-alpn/jetty-alpn-api/pom.xml create mode 100644 jetty-alpn/jetty-alpn-api/src/main/java/org/eclipse/jetty/alpn/ALPN.java -diff --git a/jetty-alpn/jetty-alpn-api/pom.xml b/jetty-alpn/jetty-alpn-api/pom.xml -new file mode 100644 -index 0000000..4b3b511 --- /dev/null +++ b/jetty-alpn/jetty-alpn-api/pom.xml @@ -0,0 +1,117 @@ @@ -134,9 +131,6 @@ + + + -diff --git a/jetty-alpn/jetty-alpn-api/src/main/java/org/eclipse/jetty/alpn/ALPN.java b/jetty-alpn/jetty-alpn-api/src/main/java/org/eclipse/jetty/alpn/ALPN.java -new file mode 100644 -index 0000000..8a40558 --- /dev/null +++ b/jetty-alpn/jetty-alpn-api/src/main/java/org/eclipse/jetty/alpn/ALPN.java @@ -0,0 +1,249 @@ @@ -389,8 +383,6 @@ + } +} + -diff --git a/jetty-alpn/pom.xml b/jetty-alpn/pom.xml -index 73b2b73..ebf2eaa 100644 --- a/jetty-alpn/pom.xml +++ b/jetty-alpn/pom.xml @@ -10,6 +10,7 @@ diff -Nru jetty9-9.4.50/debian/patches/04-weksocket-1.1-compatibility.patch jetty9-9.4.57/debian/patches/04-weksocket-1.1-compatibility.patch --- jetty9-9.4.50/debian/patches/04-weksocket-1.1-compatibility.patch 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/patches/04-weksocket-1.1-compatibility.patch 2025-04-01 17:22:08.000000000 +0000 @@ -7,15 +7,12 @@ .../java/org/eclipse/jetty/websocket/jsr356/JsrSession.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) -diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JsrSession.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JsrSession.java -index c567a1f..3c1ca80 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JsrSession.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JsrSession.java -@@ -144,6 +144,18 @@ public class JsrSession extends WebSocketSession implements javax.websocket.Sess - } +@@ -145,6 +145,18 @@ public class JsrSession extends WebSocke } -+ @Override + @Override + public void addMessageHandler(Class clazz, MessageHandler.Partial handler) throws IllegalStateException + { + throw new UnsupportedOperationException(); @@ -27,6 +24,7 @@ + throw new UnsupportedOperationException(); + } + - @Override ++ @Override public void close(CloseReason closeReason) throws IOException { + close(closeReason.getCloseCode().getCode(), closeReason.getReasonPhrase()); diff -Nru jetty9-9.4.50/debian/patches/06-ignore-jetty-documentation.patch jetty9-9.4.57/debian/patches/06-ignore-jetty-documentation.patch --- jetty9-9.4.50/debian/patches/06-ignore-jetty-documentation.patch 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/patches/06-ignore-jetty-documentation.patch 2025-04-01 17:22:08.000000000 +0000 @@ -10,7 +10,7 @@ --- a/pom.xml +++ b/pom.xml -@@ -221,7 +221,6 @@ +@@ -224,7 +224,6 @@ jetty-alpn jetty-home jetty-bom diff -Nru jetty9-9.4.50/debian/patches/07-assembly-plugin-configuration.patch jetty9-9.4.57/debian/patches/07-assembly-plugin-configuration.patch --- jetty9-9.4.50/debian/patches/07-assembly-plugin-configuration.patch 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/patches/07-assembly-plugin-configuration.patch 2025-04-01 17:22:08.000000000 +0000 @@ -14,7 +14,7 @@ --- a/jetty-cdi/pom.xml +++ b/jetty-cdi/pom.xml -@@ -60,9 +60,9 @@ +@@ -70,9 +70,9 @@ single @@ -44,7 +44,7 @@ --- a/pom.xml +++ b/pom.xml -@@ -1364,9 +1364,9 @@ +@@ -1403,9 +1403,9 @@ single diff -Nru jetty9-9.4.50/debian/patches/08-ignore-jetty-test-policy.patch jetty9-9.4.57/debian/patches/08-ignore-jetty-test-policy.patch --- jetty9-9.4.50/debian/patches/08-ignore-jetty-test-policy.patch 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/patches/08-ignore-jetty-test-policy.patch 2025-04-01 17:22:08.000000000 +0000 @@ -8,8 +8,6 @@ jetty-client/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/jetty-client/pom.xml b/jetty-client/pom.xml -index ac6bfd0..3ae9d0e 100644 --- a/jetty-client/pom.xml +++ b/jetty-client/pom.xml @@ -21,7 +21,7 @@ diff -Nru jetty9-9.4.50/debian/patches/09-tweak-distribution.patch jetty9-9.4.57/debian/patches/09-tweak-distribution.patch --- jetty9-9.4.50/debian/patches/09-tweak-distribution.patch 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/patches/09-tweak-distribution.patch 2025-04-01 17:22:08.000000000 +0000 @@ -9,8 +9,6 @@ jetty-home/pom.xml | 20 ++++++-------------- 2 files changed, 12 insertions(+), 20 deletions(-) -diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml -index 6de9e06..9f1c398 100644 --- a/jetty-distribution/pom.xml +++ b/jetty-distribution/pom.xml @@ -75,7 +75,7 @@ @@ -67,16 +65,12 @@ unpack -diff --git a/jetty-home/pom.xml b/jetty-home/pom.xml -index 6b3f176..90471d7 100644 --- a/jetty-home/pom.xml +++ b/jetty-home/pom.xml -@@ -78,16 +78,6 @@ - - +@@ -80,16 +80,6 @@ -- -- org.eclipse.jetty + + org.eclipse.jetty - jetty-project - ${project.version} - version @@ -85,9 +79,11 @@ - ${assembly-directory}/ - VERSION.txt - - - org.eclipse.jetty +- +- org.eclipse.jetty jetty-start + ${project.version} + shaded @@ -104,7 +94,7 @@ diff -Nru jetty9-9.4.50/debian/patches/CVE-2023-26048.patch jetty9-9.4.57/debian/patches/CVE-2023-26048.patch --- jetty9-9.4.50/debian/patches/CVE-2023-26048.patch 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/patches/CVE-2023-26048.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,433 +0,0 @@ -From: Markus Koschany -Date: Tue, 26 Sep 2023 18:15:11 +0200 -Subject: CVE-2023-26048 - -Origin: https://github.com/eclipse/jetty.project/pull/9345 ---- - .../jetty/http/MultiPartFormInputStream.java | 24 +++- - .../java/org/eclipse/jetty/server/MultiParts.java | 14 +- - .../java/org/eclipse/jetty/server/Request.java | 27 +++- - .../jetty/servlet/MultiPartServletTest.java | 141 +++++++++++++++++++++ - .../jetty/util/MultiPartInputStreamParser.java | 23 +++- - 5 files changed, 219 insertions(+), 10 deletions(-) - -diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormInputStream.java b/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormInputStream.java -index 2253346..4f1811f 100644 ---- a/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormInputStream.java -+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormInputStream.java -@@ -61,9 +61,12 @@ import org.eclipse.jetty.util.log.Logger; - public class MultiPartFormInputStream - { - private static final Logger LOG = Log.getLogger(MultiPartFormInputStream.class); -+ private static final int DEFAULT_MAX_FORM_KEYS = 1000; - private static final MultiMap EMPTY_MAP = new MultiMap<>(Collections.emptyMap()); -- private final MultiMap _parts; - private final EnumSet _nonComplianceWarnings = EnumSet.noneOf(NonCompliance.class); -+ private final MultiMap _parts; -+ private final int _maxParts; -+ private int _numParts = 0; - private InputStream _in; - private MultipartConfigElement _config; - private String _contentType; -@@ -350,18 +353,30 @@ public class MultiPartFormInputStream - * @param contextTmpDir javax.servlet.context.tempdir - */ - public MultiPartFormInputStream(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir) -+ { -+ this(in, contentType, config, contextTmpDir, DEFAULT_MAX_FORM_KEYS); -+ } -+ -+ /** -+ * @param in Request input stream -+ * @param contentType Content-Type header -+ * @param config MultipartConfigElement -+ * @param contextTmpDir javax.servlet.context.tempdir -+ * @param maxParts the maximum number of parts that can be parsed from the multipart content (0 for no parts allowed, -1 for unlimited parts). -+ */ -+ public MultiPartFormInputStream(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir, int maxParts) - { - _contentType = contentType; - _config = config; - _contextTmpDir = contextTmpDir; -+ _maxParts = maxParts; - if (_contextTmpDir == null) - _contextTmpDir = new File(System.getProperty("java.io.tmpdir")); - - if (_config == null) - _config = new MultipartConfigElement(_contextTmpDir.getAbsolutePath()); - -- MultiMap parts = new MultiMap(); -- -+ MultiMap parts = new MultiMap<>(); - if (in instanceof ServletInputStream) - { - if (((ServletInputStream)in).isFinished()) -@@ -752,6 +767,9 @@ public class MultiPartFormInputStream - public void startPart() - { - reset(); -+ _numParts++; -+ if (_maxParts >= 0 && _numParts > _maxParts) -+ throw new IllegalStateException(String.format("Form with too many parts [%d > %d]", _numParts, _maxParts)); - } - - @Override -diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java b/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java -index 5bb283d..8ae73f7 100644 ---- a/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java -+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java -@@ -58,7 +58,12 @@ public interface MultiParts extends Closeable - - public MultiPartsHttpParser(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir, Request request) throws IOException - { -- _httpParser = new MultiPartFormInputStream(in, contentType, config, contextTmpDir); -+ this(in, contentType, config, contextTmpDir, request, ContextHandler.DEFAULT_MAX_FORM_KEYS); -+ } -+ -+ public MultiPartsHttpParser(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir, Request request, int maxParts) throws IOException -+ { -+ _httpParser = new MultiPartFormInputStream(in, contentType, config, contextTmpDir, maxParts); - _context = request.getContext(); - _request = request; - } -@@ -123,7 +128,12 @@ public interface MultiParts extends Closeable - - public MultiPartsUtilParser(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir, Request request) throws IOException - { -- _utilParser = new MultiPartInputStreamParser(in, contentType, config, contextTmpDir); -+ this(in, contentType, config, contextTmpDir, request, ContextHandler.DEFAULT_MAX_FORM_KEYS); -+ } -+ -+ public MultiPartsUtilParser(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir, Request request, int maxParts) throws IOException -+ { -+ _utilParser = new MultiPartInputStreamParser(in, contentType, config, contextTmpDir, maxParts); - _context = request.getContext(); - _request = request; - } -diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java -index 4d66f75..2f60fb7 100644 ---- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java -+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java -@@ -2431,7 +2431,21 @@ public class Request implements HttpServletRequest - if (config == null) - throw new IllegalStateException("No multipart config for servlet"); - -- _multiParts = newMultiParts(config); -+ int maxFormContentSize = ContextHandler.DEFAULT_MAX_FORM_CONTENT_SIZE; -+ int maxFormKeys = ContextHandler.DEFAULT_MAX_FORM_KEYS; -+ if (_context != null) -+ { -+ ContextHandler contextHandler = _context.getContextHandler(); -+ maxFormContentSize = contextHandler.getMaxFormContentSize(); -+ maxFormKeys = contextHandler.getMaxFormKeys(); -+ } -+ else -+ { -+ maxFormContentSize = lookupServerAttribute(ContextHandler.MAX_FORM_CONTENT_SIZE_KEY, maxFormContentSize); -+ maxFormKeys = lookupServerAttribute(ContextHandler.MAX_FORM_KEYS_KEY, maxFormKeys); -+ } -+ -+ _multiParts = newMultiParts(config, maxFormKeys); - setAttribute(MULTIPARTS, _multiParts); - Collection parts = _multiParts.getParts(); - -@@ -2465,11 +2479,16 @@ public class Request implements HttpServletRequest - else - defaultCharset = StandardCharsets.UTF_8; - -+ long formContentSize = 0; - ByteArrayOutputStream os = null; - for (Part p : parts) - { - if (p.getSubmittedFileName() == null) - { -+ formContentSize = Math.addExact(formContentSize, p.getSize()); -+ if (maxFormContentSize >= 0 && formContentSize > maxFormContentSize) -+ throw new IllegalStateException("Form is larger than max length " + maxFormContentSize); -+ - // Servlet Spec 3.0 pg 23, parts without filename must be put into params. - String charset = null; - if (p.getContentType() != null) -@@ -2494,7 +2513,7 @@ public class Request implements HttpServletRequest - return _multiParts.getParts(); - } - -- private MultiParts newMultiParts(MultipartConfigElement config) throws IOException -+ private MultiParts newMultiParts(MultipartConfigElement config, int maxParts) throws IOException - { - MultiPartFormDataCompliance compliance = getHttpChannel().getHttpConfiguration().getMultipartFormDataCompliance(); - if (LOG.isDebugEnabled()) -@@ -2504,12 +2523,12 @@ public class Request implements HttpServletRequest - { - case RFC7578: - return new MultiParts.MultiPartsHttpParser(getInputStream(), getContentType(), config, -- (_context != null ? (File)_context.getAttribute("javax.servlet.context.tempdir") : null), this); -+ (_context != null ? (File)_context.getAttribute("javax.servlet.context.tempdir") : null), this, maxParts); - - case LEGACY: - default: - return new MultiParts.MultiPartsUtilParser(getInputStream(), getContentType(), config, -- (_context != null ? (File)_context.getAttribute("javax.servlet.context.tempdir") : null), this); -+ (_context != null ? (File)_context.getAttribute("javax.servlet.context.tempdir") : null), this, maxParts); - } - } - -diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/MultiPartServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/MultiPartServletTest.java -index b87e63c..e008921 100644 ---- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/MultiPartServletTest.java -+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/MultiPartServletTest.java -@@ -41,13 +41,16 @@ import org.eclipse.jetty.client.api.Response; - import org.eclipse.jetty.client.util.BytesContentProvider; - import org.eclipse.jetty.client.util.InputStreamResponseListener; - import org.eclipse.jetty.client.util.MultiPartContentProvider; -+import org.eclipse.jetty.client.util.OutputStreamContentProvider; - import org.eclipse.jetty.client.util.StringContentProvider; - import org.eclipse.jetty.http.HttpFields; - import org.eclipse.jetty.http.HttpHeader; - import org.eclipse.jetty.http.HttpMethod; - import org.eclipse.jetty.http.HttpScheme; -+import org.eclipse.jetty.http.HttpStatus; - import org.eclipse.jetty.http.MimeTypes; - import org.eclipse.jetty.http.MultiPartFormInputStream; -+import org.eclipse.jetty.io.EofException; - import org.eclipse.jetty.server.HttpChannel; - import org.eclipse.jetty.server.HttpConnectionFactory; - import org.eclipse.jetty.server.MultiPartFormDataCompliance; -@@ -67,6 +70,8 @@ import org.junit.jupiter.params.provider.MethodSource; - - import static org.hamcrest.MatcherAssert.assertThat; - import static org.hamcrest.Matchers.containsString; -+import static org.hamcrest.Matchers.equalTo; -+import static org.hamcrest.Matchers.instanceOf; - import static org.hamcrest.Matchers.is; - import static org.hamcrest.Matchers.startsWith; - import static org.junit.jupiter.api.Assertions.assertEquals; -@@ -82,6 +87,7 @@ public class MultiPartServletTest - private Path tmpDir; - - private static final int MAX_FILE_SIZE = 512 * 1024; -+ private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 8; - private static final int LARGE_MESSAGE_SIZE = 1024 * 1024; - - public static Stream data() -@@ -89,6 +95,19 @@ public class MultiPartServletTest - return Arrays.asList(MultiPartFormDataCompliance.values()).stream().map(Arguments::of); - } - -+ public static class RequestParameterServlet extends HttpServlet -+ { -+ @Override -+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException -+ { -+ req.getParameterMap(); -+ req.getParts(); -+ resp.setStatus(200); -+ resp.getWriter().print("success"); -+ resp.getWriter().close(); -+ } -+ } -+ - public static class MultiPartServlet extends HttpServlet - { - @Override -@@ -130,6 +149,7 @@ public class MultiPartServletTest - public void start() throws Exception - { - tmpDir = Files.createTempDirectory(MultiPartServletTest.class.getSimpleName()); -+ Files.deleteIfExists(tmpDir); - assertNotNull(tmpDir); - - server = new Server(); -@@ -138,11 +158,19 @@ public class MultiPartServletTest - - MultipartConfigElement config = new MultipartConfigElement(tmpDir.toAbsolutePath().toString(), - MAX_FILE_SIZE, -1, 1); -+ MultipartConfigElement requestSizedConfig = new MultipartConfigElement(tmpDir.toAbsolutePath().toString(), -+ -1, MAX_REQUEST_SIZE, 1); -+ MultipartConfigElement defaultConfig = new MultipartConfigElement(tmpDir.toAbsolutePath().toString(), -+ -1, -1, 1); - - ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); - contextHandler.setContextPath("/"); - ServletHolder servletHolder = contextHandler.addServlet(MultiPartServlet.class, "/"); - servletHolder.getRegistration().setMultipartConfig(config); -+ servletHolder = contextHandler.addServlet(RequestParameterServlet.class, "/defaultConfig"); -+ servletHolder.getRegistration().setMultipartConfig(defaultConfig); -+ servletHolder = contextHandler.addServlet(RequestParameterServlet.class, "/requestSizeLimit"); -+ servletHolder.getRegistration().setMultipartConfig(requestSizedConfig); - servletHolder = contextHandler.addServlet(MultiPartEchoServlet.class, "/echo"); - servletHolder.getRegistration().setMultipartConfig(config); - -@@ -169,6 +197,119 @@ public class MultiPartServletTest - IO.delete(tmpDir.toFile()); - } - -+ @ParameterizedTest -+ @MethodSource("data") -+ public void testLargePart(MultiPartFormDataCompliance compliance) throws Exception -+ { -+ connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration() -+ .setMultiPartFormDataCompliance(compliance); -+ -+ OutputStreamContentProvider content = new OutputStreamContentProvider(); -+ MultiPartContentProvider multiPart = new MultiPartContentProvider(); -+ multiPart.addFieldPart("param", content, null); -+ multiPart.close(); -+ -+ InputStreamResponseListener listener = new InputStreamResponseListener(); -+ client.newRequest("localhost", connector.getLocalPort()) -+ .path("/defaultConfig") -+ .scheme(HttpScheme.HTTP.asString()) -+ .method(HttpMethod.POST) -+ .content(multiPart) -+ .send(listener); -+ -+ // Write large amount of content to the part. -+ byte[] byteArray = new byte[1024 * 1024]; -+ Arrays.fill(byteArray, (byte)1); -+ for (int i = 0; i < 128 * 2; i++) -+ { -+ content.getOutputStream().write(byteArray); -+ } -+ content.close(); -+ -+ Response response = listener.get(2, TimeUnit.MINUTES); -+ assertThat(response.getStatus(), equalTo(HttpStatus.BAD_REQUEST_400)); -+ String responseContent = IO.toString(listener.getInputStream()); -+ assertThat(responseContent, containsString("Unable to parse form content")); -+ assertThat(responseContent, containsString("Form is larger than max length")); -+ } -+ -+ @ParameterizedTest -+ @MethodSource("data") -+ public void testManyParts(MultiPartFormDataCompliance compliance) throws Exception -+ { -+ connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration() -+ .setMultiPartFormDataCompliance(compliance); -+ -+ byte[] byteArray = new byte[1024]; -+ Arrays.fill(byteArray, (byte)1); -+ -+ MultiPartContentProvider multiPart = new MultiPartContentProvider(); -+ for (int i = 0; i < 1024 * 1024; i++) -+ { -+ BytesContentProvider content = new BytesContentProvider(byteArray); -+ multiPart.addFieldPart("part" + i, content, null); -+ } -+ multiPart.close(); -+ -+ InputStreamResponseListener listener = new InputStreamResponseListener(); -+ client.newRequest("localhost", connector.getLocalPort()) -+ .path("/defaultConfig") -+ .scheme(HttpScheme.HTTP.asString()) -+ .method(HttpMethod.POST) -+ .content(multiPart) -+ .send(listener); -+ -+ Response response = listener.get(30, TimeUnit.SECONDS); -+ assertThat(response.getStatus(), equalTo(HttpStatus.BAD_REQUEST_400)); -+ String responseContent = IO.toString(listener.getInputStream()); -+ assertThat(responseContent, containsString("Unable to parse form content")); -+ assertThat(responseContent, containsString("Form with too many parts")); -+ } -+ -+ @ParameterizedTest -+ @MethodSource("data") -+ public void testMaxRequestSize(MultiPartFormDataCompliance compliance) throws Exception -+ { -+ connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration() -+ .setMultiPartFormDataCompliance(compliance); -+ -+ OutputStreamContentProvider content = new OutputStreamContentProvider(); -+ MultiPartContentProvider multiPart = new MultiPartContentProvider(); -+ multiPart.addFieldPart("param", content, null); -+ multiPart.close(); -+ -+ InputStreamResponseListener listener = new InputStreamResponseListener(); -+ client.newRequest("localhost", connector.getLocalPort()) -+ .path("/requestSizeLimit") -+ .scheme(HttpScheme.HTTP.asString()) -+ .method(HttpMethod.POST) -+ .content(multiPart) -+ .send(listener); -+ -+ Throwable writeError = null; -+ try -+ { -+ // Write large amount of content to the part. -+ byte[] byteArray = new byte[1024 * 1024]; -+ Arrays.fill(byteArray, (byte)1); -+ for (int i = 0; i < 512; i++) -+ { -+ content.getOutputStream().write(byteArray); -+ } -+ } -+ catch (Exception e) -+ { -+ writeError = e; -+ } -+ -+ if (writeError != null) -+ assertThat(writeError, instanceOf(EofException.class)); -+ -+ // We should get 400 response. -+ Response response = listener.get(30, TimeUnit.SECONDS); -+ assertThat(response.getStatus(), equalTo(HttpStatus.BAD_REQUEST_400)); -+ } -+ - @ParameterizedTest - @MethodSource("data") - public void testTempFilesDeletedOnError(MultiPartFormDataCompliance compliance) throws Exception -diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java -index bb24248..359af1c 100644 ---- a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java -+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java -@@ -64,8 +64,11 @@ import org.eclipse.jetty.util.log.Logger; - public class MultiPartInputStreamParser - { - private static final Logger LOG = Log.getLogger(MultiPartInputStreamParser.class); -+ private static final int DEFAULT_MAX_FORM_KEYS = 1000; - public static final MultipartConfigElement __DEFAULT_MULTIPART_CONFIG = new MultipartConfigElement(System.getProperty("java.io.tmpdir")); -- public static final MultiMap EMPTY_MAP = new MultiMap(Collections.emptyMap()); -+ public static final MultiMap EMPTY_MAP = new MultiMap<>(Collections.emptyMap()); -+ private final int _maxParts; -+ private int _numParts; - protected InputStream _in; - protected MultipartConfigElement _config; - protected String _contentType; -@@ -394,10 +397,23 @@ public class MultiPartInputStreamParser - * @param contextTmpDir javax.servlet.context.tempdir - */ - public MultiPartInputStreamParser(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir) -+ { -+ this(in, contentType, config, contextTmpDir, DEFAULT_MAX_FORM_KEYS); -+ } -+ -+ /** -+ * @param in Request input stream -+ * @param contentType Content-Type header -+ * @param config MultipartConfigElement -+ * @param contextTmpDir javax.servlet.context.tempdir -+ * @param maxParts the maximum number of parts that can be parsed from the multipart content (0 for no parts allowed, -1 for unlimited parts). -+ */ -+ public MultiPartInputStreamParser(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir, int maxParts) - { - _contentType = contentType; - _config = config; - _contextTmpDir = contextTmpDir; -+ _maxParts = maxParts; - if (_contextTmpDir == null) - _contextTmpDir = new File(System.getProperty("java.io.tmpdir")); - -@@ -693,6 +709,11 @@ public class MultiPartInputStreamParser - continue; - } - -+ // Check if we can create a new part. -+ _numParts++; -+ if (_maxParts >= 0 && _numParts > _maxParts) -+ throw new IllegalStateException(String.format("Form with too many parts [%d > %d]", _numParts, _maxParts)); -+ - //Have a new Part - MultiPart part = new MultiPart(name, filename); - part.setHeaders(headers); diff -Nru jetty9-9.4.50/debian/patches/CVE-2023-26049.patch jetty9-9.4.57/debian/patches/CVE-2023-26049.patch --- jetty9-9.4.50/debian/patches/CVE-2023-26049.patch 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/patches/CVE-2023-26049.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,367 +0,0 @@ -From: Markus Koschany -Date: Tue, 26 Sep 2023 18:35:45 +0200 -Subject: CVE-2023-26049 - -Origin: https://github.com/eclipse/jetty.project/pull/9352 ---- - .../org/eclipse/jetty/http/CookieCompliance.java | 1 + - .../org/eclipse/jetty/server/CookieCutter.java | 102 ++++++++++++++------- - .../jetty/server/CookieCutterLenientTest.java | 3 +- - .../org/eclipse/jetty/server/CookieCutterTest.java | 90 +++++++++++++++++- - .../java/org/eclipse/jetty/server/RequestTest.java | 2 + - 5 files changed, 157 insertions(+), 41 deletions(-) - -diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCompliance.java b/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCompliance.java -index f8696d4..40853a6 100644 ---- a/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCompliance.java -+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCompliance.java -@@ -24,5 +24,6 @@ package org.eclipse.jetty.http; - public enum CookieCompliance - { - RFC6265, -+ RFC6265_LEGACY, // Forgiving of bad quotes. - RFC2965 - } -diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java -index 3753a82..60a9f52 100644 ---- a/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java -+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java -@@ -154,6 +154,13 @@ public class CookieCutter - // Handle quoted values for name or value - if (inQuoted) - { -+ boolean eol = c == 0 && i == hdr.length(); -+ if (!eol && _compliance != CookieCompliance.RFC2965 && isRFC6265RejectedCharacter(inQuoted, c)) -+ { -+ reject = true; -+ continue; -+ } -+ - if (escaped) - { - escaped = false; -@@ -182,15 +189,24 @@ public class CookieCutter - continue; - - case 0: -- // unterminated quote, let's ignore quotes -+ // unterminated quote -+ if (_compliance == CookieCompliance.RFC6265) -+ continue; -+ // let's ignore quotes - unquoted.setLength(0); - inQuoted = false; - i--; - continue; - -+ case ';': -+ if (_compliance == CookieCompliance.RFC6265) -+ reject = true; -+ else -+ unquoted.append(c); -+ continue; -+ - default: - unquoted.append(c); -- continue; - } - } - else -@@ -198,6 +214,13 @@ public class CookieCutter - // Handle name and value state machines - if (invalue) - { -+ boolean eol = c == 0 && i == hdr.length(); -+ if (!eol && _compliance == CookieCompliance.RFC6265 && isRFC6265RejectedCharacter(inQuoted, c)) -+ { -+ reject = true; -+ continue; -+ } -+ - // parse the cookie-value - switch (c) - { -@@ -300,9 +323,20 @@ public class CookieCutter - unquoted = new StringBuilder(); - break; - } -+ else if (_compliance == CookieCompliance.RFC6265) -+ { -+ reject = true; -+ continue; -+ } - // fall through to default case - - default: -+ if (_compliance == CookieCompliance.RFC6265 && quoted) -+ { -+ reject = true; -+ continue; -+ } -+ - if (quoted) - { - // must have been a bad internal quote. let's fix as best we can -@@ -312,18 +346,12 @@ public class CookieCutter - continue; - } - -- if (_compliance == CookieCompliance.RFC6265) -- { -- if (isRFC6265RejectedCharacter(inQuoted, c)) -- { -- reject = true; -- } -- } -+ if (_compliance == CookieCompliance.RFC6265_LEGACY && isRFC6265RejectedCharacter(inQuoted, c)) -+ reject = true; - - if (tokenstart < 0) - tokenstart = i; - tokenend = i; -- continue; - } - } - else -@@ -366,13 +394,8 @@ public class CookieCutter - continue; - } - -- if (_compliance == CookieCompliance.RFC6265) -- { -- if (isRFC6265RejectedCharacter(inQuoted, c)) -- { -- reject = true; -- } -- } -+ if (_compliance != CookieCompliance.RFC2965 && isRFC6265RejectedCharacter(inQuoted, c)) -+ reject = true; - - if (tokenstart < 0) - tokenstart = i; -@@ -390,28 +413,37 @@ public class CookieCutter - - protected boolean isRFC6265RejectedCharacter(boolean inQuoted, char c) - { -- if (inQuoted) -+ // LEGACY test -+ if (_compliance == CookieCompliance.RFC6265_LEGACY) - { -- // We only reject if a Control Character is encountered -- if (Character.isISOControl(c)) -+ if (inQuoted) - { -- return true; -+ // We only reject if a Control Character is encountered -+ if (Character.isISOControl(c)) -+ return true; - } -- } -- else -- { -- /* From RFC6265 - Section 4.1.1 - Syntax -- * cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E -- * ; US-ASCII characters excluding CTLs, -- * ; whitespace DQUOTE, comma, semicolon, -- * ; and backslash -- */ -- return Character.isISOControl(c) || // control characters -- c > 127 || // 8-bit characters -- c == ',' || // comma -- c == ';'; // semicolon -+ else -+ { -+ return Character.isISOControl(c) || // control characters -+ c > 127 || // 8-bit characters -+ c == ',' || // comma -+ c == ';'; // semicolon -+ } -+ return false; - } - -- return false; -+ /* From RFC6265 - Section 4.1.1 - Syntax -+ * cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E -+ * ; US-ASCII characters excluding CTLs, -+ * ; whitespace DQUOTE, comma, semicolon, -+ * ; and backslash -+ * -+ * Note: DQUOTE and semicolon are used as separator by the parser, -+ * so we can consider them authorized. -+ */ -+ return c > 127 || // 8-bit characters -+ Character.isISOControl(c) || // control characters -+ c == ',' || // comma -+ c == '\\'; // backslash - } - } -diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterLenientTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterLenientTest.java -index 3eceac6..1d06c82 100644 ---- a/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterLenientTest.java -+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterLenientTest.java -@@ -21,6 +21,7 @@ package org.eclipse.jetty.server; - import java.util.stream.Stream; - import javax.servlet.http.Cookie; - -+import org.eclipse.jetty.http.CookieCompliance; - import org.junit.jupiter.params.ParameterizedTest; - import org.junit.jupiter.params.provider.Arguments; - import org.junit.jupiter.params.provider.MethodSource; -@@ -162,7 +163,7 @@ public class CookieCutterLenientTest - @MethodSource("data") - public void testLenientBehavior(String rawHeader, String expectedName, String expectedValue) - { -- CookieCutter cutter = new CookieCutter(); -+ CookieCutter cutter = new CookieCutter(CookieCompliance.RFC6265_LEGACY); - cutter.addCookieField(rawHeader); - Cookie[] cookies = cutter.getCookies(); - if (expectedName == null) -diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterTest.java -index 494ff03..3e84ce6 100644 ---- a/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterTest.java -+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterTest.java -@@ -19,10 +19,13 @@ - package org.eclipse.jetty.server; - - import java.util.Arrays; -+import java.util.List; - import javax.servlet.http.Cookie; - - import org.eclipse.jetty.http.CookieCompliance; - import org.junit.jupiter.api.Test; -+import org.junit.jupiter.params.ParameterizedTest; -+import org.junit.jupiter.params.provider.MethodSource; - - import static org.hamcrest.MatcherAssert.assertThat; - import static org.hamcrest.Matchers.is; -@@ -162,15 +165,13 @@ public class CookieCutterTest - "$Version=\"1\"; session_id=\"1111\"; $Domain=\".cracker.edu\""; - - Cookie[] cookies = parseCookieHeaders(CookieCompliance.RFC2965, rawCookie); -- - assertThat("Cookies.length", cookies.length, is(2)); - assertCookie("Cookies[0]", cookies[0], "session_id", "1234", 1, null); - assertCookie("Cookies[1]", cookies[1], "session_id", "1111", 1, null); - - cookies = parseCookieHeaders(CookieCompliance.RFC6265, rawCookie); -- assertThat("Cookies.length", cookies.length, is(2)); -- assertCookie("Cookies[0]", cookies[0], "session_id", "1234\", $Version=\"1", 0, null); -- assertCookie("Cookies[1]", cookies[1], "session_id", "1111", 0, null); -+ assertThat("Cookies.length", cookies.length, is(1)); -+ assertCookie("Cookies[0]", cookies[0], "session_id", "1111", 0, null); - } - - /** -@@ -266,7 +267,7 @@ public class CookieCutterTest - { - char[] excessive = new char[65535]; - Arrays.fill(excessive, ';'); -- String rawCookie = "foo=bar; " + excessive + "; xyz=pdq"; -+ String rawCookie = "foo=bar; " + new String(excessive) + "; xyz=pdq"; - - Cookie[] cookies = parseCookieHeaders(CookieCompliance.RFC6265, rawCookie); - -@@ -274,4 +275,83 @@ public class CookieCutterTest - assertCookie("Cookies[0]", cookies[0], "foo", "bar", 0, null); - assertCookie("Cookies[1]", cookies[1], "xyz", "pdq", 0, null); - } -+ -+ @ParameterizedTest -+ @MethodSource("rfc6265Cookies") -+ public void testRFC6265CookieParsing(Param param) -+ { -+ Cookie[] cookies = parseCookieHeaders(CookieCompliance.RFC6265, param.input); -+ -+ assertThat("Cookies.length (" + dump(cookies) + ")", cookies.length, is(param.expected.size())); -+ for (int i = 0; i < cookies.length; i++) -+ { -+ Cookie cookie = cookies[i]; -+ assertThat("Cookies[" + i + "] (" + dump(cookies) + ")", cookie.getName() + "=" + cookie.getValue(), is(param.expected.get(i))); -+ } -+ } -+ -+ public static List rfc6265Cookies() -+ { -+ return Arrays.asList( -+ new Param("A=1; B=2; C=3", "A=1", "B=2", "C=3"), -+ new Param("A=\"1\"; B=2; C=3", "A=1", "B=2", "C=3"), -+ new Param("A=\"1\"; B=\"2\"; C=\"3\"", "A=1", "B=2", "C=3"), -+ new Param("A=1; B=2; C=\"3", "A=1", "B=2"), -+ new Param("A=1 ; B=2; C=3", "A=1", "B=2", "C=3"), -+ new Param("A= 1; B=2; C=3", "A=1", "B=2", "C=3"), -+ new Param("A=\"1; B=2\"; C=3", "C=3"), -+ new Param("A=\"1; B=2; C=3"), -+ new Param("A=\"1 B=2\"; C=3", "A=1 B=2", "C=3"), -+ new Param("A=\"\"1; B=2; C=3", "B=2", "C=3"), -+ new Param("A=\"\" ; B=2; C=3", "A=", "B=2", "C=3"), -+ new Param("A=\"\"; B=2; C=3", "A=", "B=2", "C=3"), -+ new Param("A=1\"\"; B=2; C=3", "B=2", "C=3"), -+ new Param("A=1\"; B=2; C=3", "B=2", "C=3"), -+ new Param("A=1\"1; B=2; C=3", "B=2", "C=3"), -+ new Param("A=\" 1\"; B=2; C=3", "A= 1", "B=2", "C=3"), -+ new Param("A=\"1 \"; B=2; C=3", "A=1 ", "B=2", "C=3"), -+ new Param("A=\" 1 \"; B=2; C=3", "A= 1 ", "B=2", "C=3"), -+ new Param("A=\" 1 1 \"; B=2; C=3", "A= 1 1 ", "B=2", "C=3"), -+ new Param("A=1,; B=2; C=3", "B=2", "C=3"), -+ new Param("A=\"1,\"; B=2; C=3", "B=2", "C=3"), -+ new Param("A=\\1; B=2; C=3", "B=2", "C=3"), -+ new Param("A=\"\\1\"; B=2; C=3", "B=2", "C=3"), -+ new Param("A=1\u0007; B=2; C=3", "B=2", "C=3"), -+ new Param("A=\"1\u0007\"; B=2; C=3", "B=2", "C=3"), -+ new Param("€"), -+ new Param("@={}"), -+ new Param("$X=Y; N=V", "N=V"), -+ new Param("N=V; $X=Y", "N=V") -+ ); -+ } -+ -+ private static String dump(Cookie[] cookies) -+ { -+ StringBuilder sb = new StringBuilder(); -+ for (Cookie cookie : cookies) -+ { -+ sb.append("<").append(cookie.getName()).append(">=<").append(cookie.getValue()).append("> | "); -+ } -+ if (sb.length() > 0) -+ sb.delete(sb.length() - 2, sb.length() - 1); -+ return sb.toString(); -+ } -+ -+ private static class Param -+ { -+ private final String input; -+ private final List expected; -+ -+ public Param(String input, String... expected) -+ { -+ this.input = input; -+ this.expected = Arrays.asList(expected); -+ } -+ -+ @Override -+ public String toString() -+ { -+ return input + " -> " + expected.toString(); -+ } -+ } - } -diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java -index f77f39b..a4e9125 100644 ---- a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java -+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java -@@ -53,6 +53,7 @@ import javax.servlet.http.HttpServletResponse; - import javax.servlet.http.Part; - - import org.eclipse.jetty.http.BadMessageException; -+import org.eclipse.jetty.http.CookieCompliance; - import org.eclipse.jetty.http.HttpCompliance; - import org.eclipse.jetty.http.HttpComplianceSection; - import org.eclipse.jetty.http.HttpStatus; -@@ -140,6 +141,7 @@ public class RequestTest - http.getHttpConfiguration().setRequestHeaderSize(512); - http.getHttpConfiguration().setResponseHeaderSize(512); - http.getHttpConfiguration().setOutputBufferSize(2048); -+ http.getHttpConfiguration().setRequestCookieCompliance(CookieCompliance.RFC6265_LEGACY); - http.getHttpConfiguration().addCustomizer(new ForwardedRequestCustomizer()); - _connector = new LocalConnector(_server, http); - _server.addConnector(_connector); diff -Nru jetty9-9.4.50/debian/patches/CVE-2023-36478.patch jetty9-9.4.57/debian/patches/CVE-2023-36478.patch --- jetty9-9.4.50/debian/patches/CVE-2023-36478.patch 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/patches/CVE-2023-36478.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,7110 +0,0 @@ -From: Markus Koschany -Date: Thu, 26 Oct 2023 20:28:28 +0200 -Subject: CVE-2023-36478 - -Origin: https://github.com/jetty/jetty.project/commit/a4d61e9eb026ec98c79107e840cabdf520482c56 -Origin: https://github.com/jetty/jetty.project/commit/bbeb66bbc0c79afa52d5454e27265640898fab16 ---- - .../java/org/eclipse/jetty/http/HttpTokens.java | 44 ++ - .../jetty/http/compression/EncodingException.java | 27 + - .../eclipse/jetty/http/compression/Huffman.java | 357 +++++++++++++ - .../jetty/http/compression/HuffmanDecoder.java | 143 ++++++ - .../jetty/http/compression/HuffmanEncoder.java | 142 ++++++ - .../jetty/http/compression/NBitIntegerDecoder.java | 113 +++++ - .../jetty/http/compression/NBitIntegerEncoder.java | 96 ++++ - .../jetty/http/compression/NBitStringDecoder.java | 138 ++++++ - .../jetty/http/compression/NBitStringEncoder.java | 82 +++ - .../java/org/eclipse/jetty/http/HuffmanTest.java | 168 +++++++ - .../org/eclipse/jetty/http/NBitIntegerTest.java | 207 ++++++++ - .../eclipse/jetty/http2/client/HTTP2Client.java | 81 ++- - .../http2/client/HTTP2ClientConnectionFactory.java | 83 +++- - .../jetty/http2/client/HTTP2ClientSession.java | 10 +- - .../org/eclipse/jetty/http2/client/HTTP2Test.java | 173 ++++++- - .../eclipse/jetty/http2/client/PrefaceTest.java | 13 +- - .../org/eclipse/jetty/http2/HTTP2Connection.java | 22 +- - .../java/org/eclipse/jetty/http2/HTTP2Session.java | 135 +++-- - .../eclipse/jetty/http2/generator/Generator.java | 26 +- - .../jetty/http2/parser/HeaderBlockParser.java | 5 + - .../jetty/http2/parser/HeadersBodyParser.java | 4 + - .../org/eclipse/jetty/http2/parser/Parser.java | 58 ++- - .../jetty/http2/parser/PushPromiseBodyParser.java | 4 + - .../eclipse/jetty/http2/parser/ServerParser.java | 39 +- - .../jetty/http2/frames/ContinuationParseTest.java | 7 +- - .../jetty/http2/frames/DataGenerateParseTest.java | 13 +- - .../eclipse/jetty/http2/frames/FrameFloodTest.java | 7 +- - .../http2/frames/GoAwayGenerateParseTest.java | 13 +- - .../http2/frames/HeadersGenerateParseTest.java | 13 +- - .../jetty/http2/frames/MaxFrameSizeParseTest.java | 9 +- - .../jetty/http2/frames/PingGenerateParseTest.java | 19 +- - .../http2/frames/PriorityGenerateParseTest.java | 13 +- - .../http2/frames/PushPromiseGenerateParseTest.java | 13 +- - .../jetty/http2/frames/ResetGenerateParseTest.java | 13 +- - .../http2/frames/SettingsGenerateParseTest.java | 45 +- - .../jetty/http2/frames/UnknownParseTest.java | 13 +- - .../frames/WindowUpdateGenerateParseTest.java | 13 +- - .../eclipse/jetty/http2/hpack/HpackContext.java | 61 +-- - .../eclipse/jetty/http2/hpack/HpackDecoder.java | 174 +++++-- - .../eclipse/jetty/http2/hpack/HpackEncoder.java | 174 +++---- - .../eclipse/jetty/http2/hpack/HpackException.java | 5 +- - .../jetty/http2/hpack/HpackFieldPreEncoder.java | 14 +- - .../org/eclipse/jetty/http2/hpack/Huffman.java | 551 --------------------- - .../eclipse/jetty/http2/hpack/MetaDataBuilder.java | 42 +- - .../org/eclipse/jetty/http2/hpack/NBitInteger.java | 151 ------ - .../jetty/http2/hpack/HpackContextTest.java | 33 +- - .../jetty/http2/hpack/HpackDecoderTest.java | 50 +- - .../jetty/http2/hpack/HpackEncoderTest.java | 30 +- - .../eclipse/jetty/http2/hpack/HpackPerfTest.java | 29 +- - .../org/eclipse/jetty/http2/hpack/HpackTest.java | 49 +- - .../org/eclipse/jetty/http2/hpack/HuffmanTest.java | 87 ---- - .../eclipse/jetty/http2/hpack/NBitIntegerTest.java | 204 -------- - .../http/HttpClientTransportOverHTTP2Test.java | 8 +- - .../AbstractHTTP2ServerConnectionFactory.java | 85 +++- - .../jetty/http2/server/HTTP2ServerConnection.java | 8 +- - .../jetty/http2/server/HTTP2ServerSession.java | 10 +- - .../org/eclipse/jetty/http2/server/CloseTest.java | 19 +- - .../jetty/http2/server/HTTP2CServerTest.java | 13 +- - .../jetty/http2/server/HTTP2ServerTest.java | 45 +- - .../eclipse/jetty/util/CharsetStringBuilder.java | 312 ++++++++++++ - .../java/org/eclipse/jetty/util/StringUtil.java | 73 +++ - 61 files changed, 3044 insertions(+), 1544 deletions(-) - create mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/compression/EncodingException.java - create mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/compression/Huffman.java - create mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/compression/HuffmanDecoder.java - create mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/compression/HuffmanEncoder.java - create mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitIntegerDecoder.java - create mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitIntegerEncoder.java - create mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitStringDecoder.java - create mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitStringEncoder.java - create mode 100644 jetty-http/src/test/java/org/eclipse/jetty/http/HuffmanTest.java - create mode 100644 jetty-http/src/test/java/org/eclipse/jetty/http/NBitIntegerTest.java - delete mode 100644 jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/Huffman.java - delete mode 100644 jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/NBitInteger.java - delete mode 100644 jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java - delete mode 100644 jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/NBitIntegerTest.java - create mode 100644 jetty-util/src/main/java/org/eclipse/jetty/util/CharsetStringBuilder.java - -diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpTokens.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpTokens.java -index 8aebd00..720faf4 100644 ---- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpTokens.java -+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpTokens.java -@@ -188,5 +188,49 @@ public class HttpTokens - } - } - } -+ -+ /** -+ * This is used when decoding to not decode illegal characters based on RFC9110. -+ * CR, LF, or NUL are replaced with ' ', all other control and multibyte characters -+ * are replaced with '?'. If this is given a legal character the same value will be returned. -+ *
-+     * field-vchar = VCHAR / obs-text
-+     * obs-text    = %x80-FF
-+     * VCHAR       = %x21-7E
-+     * 
-+ * @param c the character to test. -+ * @return the original character or the replacement character ' ' or '?', -+ * the return value is guaranteed to be a valid ISO-8859-1 character. -+ */ -+ public static char sanitizeFieldVchar(char c) -+ { -+ switch (c) -+ { -+ // A recipient of CR, LF, or NUL within a field value MUST either reject the message -+ // or replace each of those characters with SP before further processing -+ case '\r': -+ case '\n': -+ case 0x00: -+ return ' '; -+ -+ default: -+ if (isIllegalFieldVchar(c)) -+ return '?'; -+ } -+ return c; -+ } -+ -+ /** -+ * Checks whether this is an invalid VCHAR based on RFC9110. -+ * If this not a valid ISO-8859-1 character or a control character -+ * we say that it is illegal. -+ * -+ * @param c the character to test. -+ * @return true if this is invalid VCHAR. -+ */ -+ public static boolean isIllegalFieldVchar(char c) -+ { -+ return (c >= 256 || c < ' '); -+ } - } - -diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/compression/EncodingException.java b/jetty-http/src/main/java/org/eclipse/jetty/http/compression/EncodingException.java -new file mode 100644 -index 0000000..5f05557 ---- /dev/null -+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/compression/EncodingException.java -@@ -0,0 +1,27 @@ -+// -+// ======================================================================== -+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -+// ------------------------------------------------------------------------ -+// All rights reserved. This program and the accompanying materials -+// are made available under the terms of the Eclipse Public License v1.0 -+// and Apache License v2.0 which accompanies this distribution. -+// -+// The Eclipse Public License is available at -+// http://www.eclipse.org/legal/epl-v10.html -+// -+// The Apache License v2.0 is available at -+// http://www.opensource.org/licenses/apache2.0.php -+// -+// You may elect to redistribute this code under either of these licenses. -+// ======================================================================== -+// -+ -+package org.eclipse.jetty.http.compression; -+ -+public class EncodingException extends Exception -+{ -+ public EncodingException(String message) -+ { -+ super(message); -+ } -+} -diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/compression/Huffman.java b/jetty-http/src/main/java/org/eclipse/jetty/http/compression/Huffman.java -new file mode 100644 -index 0000000..6e2cb33 ---- /dev/null -+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/compression/Huffman.java -@@ -0,0 +1,357 @@ -+// -+// ======================================================================== -+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -+// ------------------------------------------------------------------------ -+// All rights reserved. This program and the accompanying materials -+// are made available under the terms of the Eclipse Public License v1.0 -+// and Apache License v2.0 which accompanies this distribution. -+// -+// The Eclipse Public License is available at -+// http://www.eclipse.org/legal/epl-v10.html -+// -+// The Apache License v2.0 is available at -+// http://www.opensource.org/licenses/apache2.0.php -+// -+// You may elect to redistribute this code under either of these licenses. -+// ======================================================================== -+// -+ -+package org.eclipse.jetty.http.compression; -+ -+/** -+ * This class contains the Huffman Codes defined in RFC7541. -+ */ -+public class Huffman -+{ -+ private Huffman() -+ { -+ } -+ -+ // Appendix C: Huffman Codes -+ // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-12#appendix-C -+ static final int[][] CODES = -+ { -+ /* ( 0) |11111111|11000 */ {0x1ff8, 13}, -+ /* ( 1) |11111111|11111111|1011000 */ {0x7fffd8, 23}, -+ /* ( 2) |11111111|11111111|11111110|0010 */ {0xfffffe2, 28}, -+ /* ( 3) |11111111|11111111|11111110|0011 */ {0xfffffe3, 28}, -+ /* ( 4) |11111111|11111111|11111110|0100 */ {0xfffffe4, 28}, -+ /* ( 5) |11111111|11111111|11111110|0101 */ {0xfffffe5, 28}, -+ /* ( 6) |11111111|11111111|11111110|0110 */ {0xfffffe6, 28}, -+ /* ( 7) |11111111|11111111|11111110|0111 */ {0xfffffe7, 28}, -+ /* ( 8) |11111111|11111111|11111110|1000 */ {0xfffffe8, 28}, -+ /* ( 9) |11111111|11111111|11101010 */ {0xffffea, 24}, -+ /* ( 10) |11111111|11111111|11111111|111100 */ {0x3ffffffc, 30}, -+ /* ( 11) |11111111|11111111|11111110|1001 */ {0xfffffe9, 28}, -+ /* ( 12) |11111111|11111111|11111110|1010 */ {0xfffffea, 28}, -+ /* ( 13) |11111111|11111111|11111111|111101 */ {0x3ffffffd, 30}, -+ /* ( 14) |11111111|11111111|11111110|1011 */ {0xfffffeb, 28}, -+ /* ( 15) |11111111|11111111|11111110|1100 */ {0xfffffec, 28}, -+ /* ( 16) |11111111|11111111|11111110|1101 */ {0xfffffed, 28}, -+ /* ( 17) |11111111|11111111|11111110|1110 */ {0xfffffee, 28}, -+ /* ( 18) |11111111|11111111|11111110|1111 */ {0xfffffef, 28}, -+ /* ( 19) |11111111|11111111|11111111|0000 */ {0xffffff0, 28}, -+ /* ( 20) |11111111|11111111|11111111|0001 */ {0xffffff1, 28}, -+ /* ( 21) |11111111|11111111|11111111|0010 */ {0xffffff2, 28}, -+ /* ( 22) |11111111|11111111|11111111|111110 */ {0x3ffffffe, 30}, -+ /* ( 23) |11111111|11111111|11111111|0011 */ {0xffffff3, 28}, -+ /* ( 24) |11111111|11111111|11111111|0100 */ {0xffffff4, 28}, -+ /* ( 25) |11111111|11111111|11111111|0101 */ {0xffffff5, 28}, -+ /* ( 26) |11111111|11111111|11111111|0110 */ {0xffffff6, 28}, -+ /* ( 27) |11111111|11111111|11111111|0111 */ {0xffffff7, 28}, -+ /* ( 28) |11111111|11111111|11111111|1000 */ {0xffffff8, 28}, -+ /* ( 29) |11111111|11111111|11111111|1001 */ {0xffffff9, 28}, -+ /* ( 30) |11111111|11111111|11111111|1010 */ {0xffffffa, 28}, -+ /* ( 31) |11111111|11111111|11111111|1011 */ {0xffffffb, 28}, -+ /*' ' ( 32) |010100 */ {0x14, 6}, -+ /*'!' ( 33) |11111110|00 */ {0x3f8, 10}, -+ /*'"' ( 34) |11111110|01 */ {0x3f9, 10}, -+ /*'#' ( 35) |11111111|1010 */ {0xffa, 12}, -+ /*'$' ( 36) |11111111|11001 */ {0x1ff9, 13}, -+ /*'%' ( 37) |010101 */ {0x15, 6}, -+ /*'&' ( 38) |11111000 */ {0xf8, 8}, -+ /*''' ( 39) |11111111|010 */ {0x7fa, 11}, -+ /*'(' ( 40) |11111110|10 */ {0x3fa, 10}, -+ /*')' ( 41) |11111110|11 */ {0x3fb, 10}, -+ /*'*' ( 42) |11111001 */ {0xf9, 8}, -+ /*'+' ( 43) |11111111|011 */ {0x7fb, 11}, -+ /*',' ( 44) |11111010 */ {0xfa, 8}, -+ /*'-' ( 45) |010110 */ {0x16, 6}, -+ /*'.' ( 46) |010111 */ {0x17, 6}, -+ /*'/' ( 47) |011000 */ {0x18, 6}, -+ /*'0' ( 48) |00000 */ {0x0, 5}, -+ /*'1' ( 49) |00001 */ {0x1, 5}, -+ /*'2' ( 50) |00010 */ {0x2, 5}, -+ /*'3' ( 51) |011001 */ {0x19, 6}, -+ /*'4' ( 52) |011010 */ {0x1a, 6}, -+ /*'5' ( 53) |011011 */ {0x1b, 6}, -+ /*'6' ( 54) |011100 */ {0x1c, 6}, -+ /*'7' ( 55) |011101 */ {0x1d, 6}, -+ /*'8' ( 56) |011110 */ {0x1e, 6}, -+ /*'9' ( 57) |011111 */ {0x1f, 6}, -+ /*':' ( 58) |1011100 */ {0x5c, 7}, -+ /*';' ( 59) |11111011 */ {0xfb, 8}, -+ /*'<' ( 60) |11111111|1111100 */ {0x7ffc, 15}, -+ /*'=' ( 61) |100000 */ {0x20, 6}, -+ /*'>' ( 62) |11111111|1011 */ {0xffb, 12}, -+ /*'?' ( 63) |11111111|00 */ {0x3fc, 10}, -+ /*'@' ( 64) |11111111|11010 */ {0x1ffa, 13}, -+ /*'A' ( 65) |100001 */ {0x21, 6}, -+ /*'B' ( 66) |1011101 */ {0x5d, 7}, -+ /*'C' ( 67) |1011110 */ {0x5e, 7}, -+ /*'D' ( 68) |1011111 */ {0x5f, 7}, -+ /*'E' ( 69) |1100000 */ {0x60, 7}, -+ /*'F' ( 70) |1100001 */ {0x61, 7}, -+ /*'G' ( 71) |1100010 */ {0x62, 7}, -+ /*'H' ( 72) |1100011 */ {0x63, 7}, -+ /*'I' ( 73) |1100100 */ {0x64, 7}, -+ /*'J' ( 74) |1100101 */ {0x65, 7}, -+ /*'K' ( 75) |1100110 */ {0x66, 7}, -+ /*'L' ( 76) |1100111 */ {0x67, 7}, -+ /*'M' ( 77) |1101000 */ {0x68, 7}, -+ /*'N' ( 78) |1101001 */ {0x69, 7}, -+ /*'O' ( 79) |1101010 */ {0x6a, 7}, -+ /*'P' ( 80) |1101011 */ {0x6b, 7}, -+ /*'Q' ( 81) |1101100 */ {0x6c, 7}, -+ /*'R' ( 82) |1101101 */ {0x6d, 7}, -+ /*'S' ( 83) |1101110 */ {0x6e, 7}, -+ /*'T' ( 84) |1101111 */ {0x6f, 7}, -+ /*'U' ( 85) |1110000 */ {0x70, 7}, -+ /*'V' ( 86) |1110001 */ {0x71, 7}, -+ /*'W' ( 87) |1110010 */ {0x72, 7}, -+ /*'X' ( 88) |11111100 */ {0xfc, 8}, -+ /*'Y' ( 89) |1110011 */ {0x73, 7}, -+ /*'Z' ( 90) |11111101 */ {0xfd, 8}, -+ /*'[' ( 91) |11111111|11011 */ {0x1ffb, 13}, -+ /*'\' ( 92) |11111111|11111110|000 */ {0x7fff0, 19}, -+ /*']' ( 93) |11111111|11100 */ {0x1ffc, 13}, -+ /*'^' ( 94) |11111111|111100 */ {0x3ffc, 14}, -+ /*'_' ( 95) |100010 */ {0x22, 6}, -+ /*'`' ( 96) |11111111|1111101 */ {0x7ffd, 15}, -+ /*'a' ( 97) |00011 */ {0x3, 5}, -+ /*'b' ( 98) |100011 */ {0x23, 6}, -+ /*'c' ( 99) |00100 */ {0x4, 5}, -+ /*'d' (100) |100100 */ {0x24, 6}, -+ /*'e' (101) |00101 */ {0x5, 5}, -+ /*'f' (102) |100101 */ {0x25, 6}, -+ /*'g' (103) |100110 */ {0x26, 6}, -+ /*'h' (104) |100111 */ {0x27, 6}, -+ /*'i' (105) |00110 */ {0x6, 5}, -+ /*'j' (106) |1110100 */ {0x74, 7}, -+ /*'k' (107) |1110101 */ {0x75, 7}, -+ /*'l' (108) |101000 */ {0x28, 6}, -+ /*'m' (109) |101001 */ {0x29, 6}, -+ /*'n' (110) |101010 */ {0x2a, 6}, -+ /*'o' (111) |00111 */ {0x7, 5}, -+ /*'p' (112) |101011 */ {0x2b, 6}, -+ /*'q' (113) |1110110 */ {0x76, 7}, -+ /*'r' (114) |101100 */ {0x2c, 6}, -+ /*'s' (115) |01000 */ {0x8, 5}, -+ /*'t' (116) |01001 */ {0x9, 5}, -+ /*'u' (117) |101101 */ {0x2d, 6}, -+ /*'v' (118) |1110111 */ {0x77, 7}, -+ /*'w' (119) |1111000 */ {0x78, 7}, -+ /*'x' (120) |1111001 */ {0x79, 7}, -+ /*'y' (121) |1111010 */ {0x7a, 7}, -+ /*'z' (122) |1111011 */ {0x7b, 7}, -+ /*'{' (123) |11111111|1111110 */ {0x7ffe, 15}, -+ /*'|' (124) |11111111|100 */ {0x7fc, 11}, -+ /*'}' (125) |11111111|111101 */ {0x3ffd, 14}, -+ /*'~' (126) |11111111|11101 */ {0x1ffd, 13}, -+ /* (127) |11111111|11111111|11111111|1100 */ {0xffffffc, 28}, -+ /* (128) |11111111|11111110|0110 */ {0xfffe6, 20}, -+ /* (129) |11111111|11111111|010010 */ {0x3fffd2, 22}, -+ /* (130) |11111111|11111110|0111 */ {0xfffe7, 20}, -+ /* (131) |11111111|11111110|1000 */ {0xfffe8, 20}, -+ /* (132) |11111111|11111111|010011 */ {0x3fffd3, 22}, -+ /* (133) |11111111|11111111|010100 */ {0x3fffd4, 22}, -+ /* (134) |11111111|11111111|010101 */ {0x3fffd5, 22}, -+ /* (135) |11111111|11111111|1011001 */ {0x7fffd9, 23}, -+ /* (136) |11111111|11111111|010110 */ {0x3fffd6, 22}, -+ /* (137) |11111111|11111111|1011010 */ {0x7fffda, 23}, -+ /* (138) |11111111|11111111|1011011 */ {0x7fffdb, 23}, -+ /* (139) |11111111|11111111|1011100 */ {0x7fffdc, 23}, -+ /* (140) |11111111|11111111|1011101 */ {0x7fffdd, 23}, -+ /* (141) |11111111|11111111|1011110 */ {0x7fffde, 23}, -+ /* (142) |11111111|11111111|11101011 */ {0xffffeb, 24}, -+ /* (143) |11111111|11111111|1011111 */ {0x7fffdf, 23}, -+ /* (144) |11111111|11111111|11101100 */ {0xffffec, 24}, -+ /* (145) |11111111|11111111|11101101 */ {0xffffed, 24}, -+ /* (146) |11111111|11111111|010111 */ {0x3fffd7, 22}, -+ /* (147) |11111111|11111111|1100000 */ {0x7fffe0, 23}, -+ /* (148) |11111111|11111111|11101110 */ {0xffffee, 24}, -+ /* (149) |11111111|11111111|1100001 */ {0x7fffe1, 23}, -+ /* (150) |11111111|11111111|1100010 */ {0x7fffe2, 23}, -+ /* (151) |11111111|11111111|1100011 */ {0x7fffe3, 23}, -+ /* (152) |11111111|11111111|1100100 */ {0x7fffe4, 23}, -+ /* (153) |11111111|11111110|11100 */ {0x1fffdc, 21}, -+ /* (154) |11111111|11111111|011000 */ {0x3fffd8, 22}, -+ /* (155) |11111111|11111111|1100101 */ {0x7fffe5, 23}, -+ /* (156) |11111111|11111111|011001 */ {0x3fffd9, 22}, -+ /* (157) |11111111|11111111|1100110 */ {0x7fffe6, 23}, -+ /* (158) |11111111|11111111|1100111 */ {0x7fffe7, 23}, -+ /* (159) |11111111|11111111|11101111 */ {0xffffef, 24}, -+ /* (160) |11111111|11111111|011010 */ {0x3fffda, 22}, -+ /* (161) |11111111|11111110|11101 */ {0x1fffdd, 21}, -+ /* (162) |11111111|11111110|1001 */ {0xfffe9, 20}, -+ /* (163) |11111111|11111111|011011 */ {0x3fffdb, 22}, -+ /* (164) |11111111|11111111|011100 */ {0x3fffdc, 22}, -+ /* (165) |11111111|11111111|1101000 */ {0x7fffe8, 23}, -+ /* (166) |11111111|11111111|1101001 */ {0x7fffe9, 23}, -+ /* (167) |11111111|11111110|11110 */ {0x1fffde, 21}, -+ /* (168) |11111111|11111111|1101010 */ {0x7fffea, 23}, -+ /* (169) |11111111|11111111|011101 */ {0x3fffdd, 22}, -+ /* (170) |11111111|11111111|011110 */ {0x3fffde, 22}, -+ /* (171) |11111111|11111111|11110000 */ {0xfffff0, 24}, -+ /* (172) |11111111|11111110|11111 */ {0x1fffdf, 21}, -+ /* (173) |11111111|11111111|011111 */ {0x3fffdf, 22}, -+ /* (174) |11111111|11111111|1101011 */ {0x7fffeb, 23}, -+ /* (175) |11111111|11111111|1101100 */ {0x7fffec, 23}, -+ /* (176) |11111111|11111111|00000 */ {0x1fffe0, 21}, -+ /* (177) |11111111|11111111|00001 */ {0x1fffe1, 21}, -+ /* (178) |11111111|11111111|100000 */ {0x3fffe0, 22}, -+ /* (179) |11111111|11111111|00010 */ {0x1fffe2, 21}, -+ /* (180) |11111111|11111111|1101101 */ {0x7fffed, 23}, -+ /* (181) |11111111|11111111|100001 */ {0x3fffe1, 22}, -+ /* (182) |11111111|11111111|1101110 */ {0x7fffee, 23}, -+ /* (183) |11111111|11111111|1101111 */ {0x7fffef, 23}, -+ /* (184) |11111111|11111110|1010 */ {0xfffea, 20}, -+ /* (185) |11111111|11111111|100010 */ {0x3fffe2, 22}, -+ /* (186) |11111111|11111111|100011 */ {0x3fffe3, 22}, -+ /* (187) |11111111|11111111|100100 */ {0x3fffe4, 22}, -+ /* (188) |11111111|11111111|1110000 */ {0x7ffff0, 23}, -+ /* (189) |11111111|11111111|100101 */ {0x3fffe5, 22}, -+ /* (190) |11111111|11111111|100110 */ {0x3fffe6, 22}, -+ /* (191) |11111111|11111111|1110001 */ {0x7ffff1, 23}, -+ /* (192) |11111111|11111111|11111000|00 */ {0x3ffffe0, 26}, -+ /* (193) |11111111|11111111|11111000|01 */ {0x3ffffe1, 26}, -+ /* (194) |11111111|11111110|1011 */ {0xfffeb, 20}, -+ /* (195) |11111111|11111110|001 */ {0x7fff1, 19}, -+ /* (196) |11111111|11111111|100111 */ {0x3fffe7, 22}, -+ /* (197) |11111111|11111111|1110010 */ {0x7ffff2, 23}, -+ /* (198) |11111111|11111111|101000 */ {0x3fffe8, 22}, -+ /* (199) |11111111|11111111|11110110|0 */ {0x1ffffec, 25}, -+ /* (200) |11111111|11111111|11111000|10 */ {0x3ffffe2, 26}, -+ /* (201) |11111111|11111111|11111000|11 */ {0x3ffffe3, 26}, -+ /* (202) |11111111|11111111|11111001|00 */ {0x3ffffe4, 26}, -+ /* (203) |11111111|11111111|11111011|110 */ {0x7ffffde, 27}, -+ /* (204) |11111111|11111111|11111011|111 */ {0x7ffffdf, 27}, -+ /* (205) |11111111|11111111|11111001|01 */ {0x3ffffe5, 26}, -+ /* (206) |11111111|11111111|11110001 */ {0xfffff1, 24}, -+ /* (207) |11111111|11111111|11110110|1 */ {0x1ffffed, 25}, -+ /* (208) |11111111|11111110|010 */ {0x7fff2, 19}, -+ /* (209) |11111111|11111111|00011 */ {0x1fffe3, 21}, -+ /* (210) |11111111|11111111|11111001|10 */ {0x3ffffe6, 26}, -+ /* (211) |11111111|11111111|11111100|000 */ {0x7ffffe0, 27}, -+ /* (212) |11111111|11111111|11111100|001 */ {0x7ffffe1, 27}, -+ /* (213) |11111111|11111111|11111001|11 */ {0x3ffffe7, 26}, -+ /* (214) |11111111|11111111|11111100|010 */ {0x7ffffe2, 27}, -+ /* (215) |11111111|11111111|11110010 */ {0xfffff2, 24}, -+ /* (216) |11111111|11111111|00100 */ {0x1fffe4, 21}, -+ /* (217) |11111111|11111111|00101 */ {0x1fffe5, 21}, -+ /* (218) |11111111|11111111|11111010|00 */ {0x3ffffe8, 26}, -+ /* (219) |11111111|11111111|11111010|01 */ {0x3ffffe9, 26}, -+ /* (220) |11111111|11111111|11111111|1101 */ {0xffffffd, 28}, -+ /* (221) |11111111|11111111|11111100|011 */ {0x7ffffe3, 27}, -+ /* (222) |11111111|11111111|11111100|100 */ {0x7ffffe4, 27}, -+ /* (223) |11111111|11111111|11111100|101 */ {0x7ffffe5, 27}, -+ /* (224) |11111111|11111110|1100 */ {0xfffec, 20}, -+ /* (225) |11111111|11111111|11110011 */ {0xfffff3, 24}, -+ /* (226) |11111111|11111110|1101 */ {0xfffed, 20}, -+ /* (227) |11111111|11111111|00110 */ {0x1fffe6, 21}, -+ /* (228) |11111111|11111111|101001 */ {0x3fffe9, 22}, -+ /* (229) |11111111|11111111|00111 */ {0x1fffe7, 21}, -+ /* (230) |11111111|11111111|01000 */ {0x1fffe8, 21}, -+ /* (231) |11111111|11111111|1110011 */ {0x7ffff3, 23}, -+ /* (232) |11111111|11111111|101010 */ {0x3fffea, 22}, -+ /* (233) |11111111|11111111|101011 */ {0x3fffeb, 22}, -+ /* (234) |11111111|11111111|11110111|0 */ {0x1ffffee, 25}, -+ /* (235) |11111111|11111111|11110111|1 */ {0x1ffffef, 25}, -+ /* (236) |11111111|11111111|11110100 */ {0xfffff4, 24}, -+ /* (237) |11111111|11111111|11110101 */ {0xfffff5, 24}, -+ /* (238) |11111111|11111111|11111010|10 */ {0x3ffffea, 26}, -+ /* (239) |11111111|11111111|1110100 */ {0x7ffff4, 23}, -+ /* (240) |11111111|11111111|11111010|11 */ {0x3ffffeb, 26}, -+ /* (241) |11111111|11111111|11111100|110 */ {0x7ffffe6, 27}, -+ /* (242) |11111111|11111111|11111011|00 */ {0x3ffffec, 26}, -+ /* (243) |11111111|11111111|11111011|01 */ {0x3ffffed, 26}, -+ /* (244) |11111111|11111111|11111100|111 */ {0x7ffffe7, 27}, -+ /* (245) |11111111|11111111|11111101|000 */ {0x7ffffe8, 27}, -+ /* (246) |11111111|11111111|11111101|001 */ {0x7ffffe9, 27}, -+ /* (247) |11111111|11111111|11111101|010 */ {0x7ffffea, 27}, -+ /* (248) |11111111|11111111|11111101|011 */ {0x7ffffeb, 27}, -+ /* (249) |11111111|11111111|11111111|1110 */ {0xffffffe, 28}, -+ /* (250) |11111111|11111111|11111101|100 */ {0x7ffffec, 27}, -+ /* (251) |11111111|11111111|11111101|101 */ {0x7ffffed, 27}, -+ /* (252) |11111111|11111111|11111101|110 */ {0x7ffffee, 27}, -+ /* (253) |11111111|11111111|11111101|111 */ {0x7ffffef, 27}, -+ /* (254) |11111111|11111111|11111110|000 */ {0x7fffff0, 27}, -+ /* (255) |11111111|11111111|11111011|10 */ {0x3ffffee, 26}, -+ /*EOS (256) |11111111|11111111|11111111|111111 */ {0x3fffffff, 30} -+ }; -+ -+ static final int[][] LCCODES = new int[CODES.length][]; -+ static final char EOS = 256; -+ -+ // Huffman decode tree stored in a flattened char array for good -+ // locality of reference. -+ static final char[] tree; -+ static final char[] rowsym; -+ static final byte[] rowbits; -+ -+ // Build the Huffman lookup tree and LC TABLE -+ static -+ { -+ System.arraycopy(CODES, 0, LCCODES, 0, CODES.length); -+ for (int i = 'A'; i <= 'Z'; i++) -+ { -+ LCCODES[i] = LCCODES['a' + i - 'A']; -+ } -+ -+ int r = 0; -+ for (int[] ints : CODES) -+ { -+ r += (ints[1] + 7) / 8; -+ } -+ tree = new char[r * 256]; -+ rowsym = new char[r]; -+ rowbits = new byte[r]; -+ -+ r = 0; -+ for (int sym = 0; sym < CODES.length; sym++) -+ { -+ int code = CODES[sym][0]; -+ int len = CODES[sym][1]; -+ -+ int current = 0; -+ -+ while (len > 8) -+ { -+ len -= 8; -+ int i = ((code >>> len) & 0xFF); -+ -+ int t = current * 256 + i; -+ current = tree[t]; -+ if (current == 0) -+ { -+ tree[t] = (char)++r; -+ current = r; -+ } -+ } -+ -+ int terminal = ++r; -+ rowsym[r] = (char)sym; -+ int b = len & 0x07; -+ int terminalBits = b == 0 ? 8 : b; -+ -+ rowbits[r] = (byte)terminalBits; -+ int shift = 8 - len; -+ int start = current * 256 + ((code << shift) & 0xFF); -+ int end = start + (1 << shift); -+ for (int i = start; i < end; i++) -+ { -+ tree[i] = (char)terminal; -+ } -+ } -+ } -+} -diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/compression/HuffmanDecoder.java b/jetty-http/src/main/java/org/eclipse/jetty/http/compression/HuffmanDecoder.java -new file mode 100644 -index 0000000..48851c1 ---- /dev/null -+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/compression/HuffmanDecoder.java -@@ -0,0 +1,143 @@ -+// -+// ======================================================================== -+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -+// ------------------------------------------------------------------------ -+// All rights reserved. This program and the accompanying materials -+// are made available under the terms of the Eclipse Public License v1.0 -+// and Apache License v2.0 which accompanies this distribution. -+// -+// The Eclipse Public License is available at -+// http://www.eclipse.org/legal/epl-v10.html -+// -+// The Apache License v2.0 is available at -+// http://www.opensource.org/licenses/apache2.0.php -+// -+// You may elect to redistribute this code under either of these licenses. -+// ======================================================================== -+// -+ -+package org.eclipse.jetty.http.compression; -+ -+import java.nio.ByteBuffer; -+ -+import org.eclipse.jetty.http.HttpTokens; -+import org.eclipse.jetty.util.CharsetStringBuilder; -+ -+import static org.eclipse.jetty.http.compression.Huffman.rowbits; -+import static org.eclipse.jetty.http.compression.Huffman.rowsym; -+ -+/** -+ *

Used to decoded Huffman encoded strings.

-+ * -+ *

Characters which are illegal field-vchar values are replaced with -+ * either ' ' or '?' as described in RFC9110

-+ */ -+public class HuffmanDecoder -+{ -+ private final CharsetStringBuilder.Iso88591StringBuilder _builder = new CharsetStringBuilder.Iso88591StringBuilder(); -+ private int _length = 0; -+ private int _count = 0; -+ private int _node = 0; -+ private int _current = 0; -+ private int _bits = 0; -+ -+ /** -+ * @param length in bytes of the huffman data. -+ */ -+ public void setLength(int length) -+ { -+ if (_count != 0) -+ throw new IllegalStateException(); -+ _length = length; -+ } -+ -+ /** -+ * @param buffer the buffer containing the Huffman encoded bytes. -+ * @return the decoded String. -+ * @throws EncodingException if the huffman encoding is invalid. -+ */ -+ public String decode(ByteBuffer buffer) throws EncodingException -+ { -+ for (; _count < _length; _count++) -+ { -+ if (!buffer.hasRemaining()) -+ return null; -+ -+ int b = buffer.get() & 0xFF; -+ _current = (_current << 8) | b; -+ _bits += 8; -+ while (_bits >= 8) -+ { -+ int i = (_current >>> (_bits - 8)) & 0xFF; -+ _node = Huffman.tree[_node * 256 + i]; -+ if (rowbits[_node] != 0) -+ { -+ if (rowsym[_node] == Huffman.EOS) -+ { -+ reset(); -+ throw new EncodingException("eos_in_content"); -+ } -+ -+ // terminal node -+ char c = rowsym[_node]; -+ c = HttpTokens.sanitizeFieldVchar(c); -+ _builder.append((byte)c); -+ _bits -= rowbits[_node]; -+ _node = 0; -+ } -+ else -+ { -+ // non-terminal node -+ _bits -= 8; -+ } -+ } -+ } -+ -+ while (_bits > 0) -+ { -+ int i = (_current << (8 - _bits)) & 0xFF; -+ int lastNode = _node; -+ _node = Huffman.tree[_node * 256 + i]; -+ -+ if (rowbits[_node] == 0 || rowbits[_node] > _bits) -+ { -+ int requiredPadding = 0; -+ for (int j = 0; j < _bits; j++) -+ { -+ requiredPadding = (requiredPadding << 1) | 1; -+ } -+ -+ if ((i >> (8 - _bits)) != requiredPadding) -+ throw new EncodingException("incorrect_padding"); -+ -+ _node = lastNode; -+ break; -+ } -+ -+ char c = rowsym[_node]; -+ c = HttpTokens.sanitizeFieldVchar(c); -+ _builder.append((byte)c); -+ _bits -= rowbits[_node]; -+ _node = 0; -+ } -+ -+ if (_node != 0) -+ { -+ reset(); -+ throw new EncodingException("bad_termination"); -+ } -+ -+ String value = _builder.build(); -+ reset(); -+ return value; -+ } -+ -+ public void reset() -+ { -+ _builder.reset(); -+ _count = 0; -+ _current = 0; -+ _node = 0; -+ _bits = 0; -+ } -+} -diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/compression/HuffmanEncoder.java b/jetty-http/src/main/java/org/eclipse/jetty/http/compression/HuffmanEncoder.java -new file mode 100644 -index 0000000..533fc21 ---- /dev/null -+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/compression/HuffmanEncoder.java -@@ -0,0 +1,142 @@ -+// -+// ======================================================================== -+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -+// ------------------------------------------------------------------------ -+// All rights reserved. This program and the accompanying materials -+// are made available under the terms of the Eclipse Public License v1.0 -+// and Apache License v2.0 which accompanies this distribution. -+// -+// The Eclipse Public License is available at -+// http://www.eclipse.org/legal/epl-v10.html -+// -+// The Apache License v2.0 is available at -+// http://www.opensource.org/licenses/apache2.0.php -+// -+// You may elect to redistribute this code under either of these licenses. -+// ======================================================================== -+// -+ -+package org.eclipse.jetty.http.compression; -+ -+import java.nio.ByteBuffer; -+ -+import org.eclipse.jetty.http.HttpTokens; -+ -+import static org.eclipse.jetty.http.compression.Huffman.CODES; -+import static org.eclipse.jetty.http.compression.Huffman.LCCODES; -+ -+/** -+ *

Used to encode strings Huffman encoding.

-+ * -+ *

Characters are encoded with ISO-8859-1, if any multi-byte characters or -+ * control characters are present the encoder will throw {@link EncodingException}.

-+ */ -+public class HuffmanEncoder -+{ -+ private HuffmanEncoder() -+ { -+ } -+ -+ /** -+ * @param s the string to encode. -+ * @return the number of octets needed to encode the string, or -1 if it cannot be encoded. -+ */ -+ public static int octetsNeeded(String s) -+ { -+ return octetsNeeded(CODES, s); -+ } -+ -+ /** -+ * @param b the byte array to encode. -+ * @return the number of octets needed to encode the bytes, or -1 if it cannot be encoded. -+ */ -+ public static int octetsNeeded(byte[] b) -+ { -+ int needed = 0; -+ for (byte value : b) -+ { -+ int c = 0xFF & value; -+ needed += CODES[c][1]; -+ } -+ return (needed + 7) / 8; -+ } -+ -+ /** -+ * @param buffer the buffer to encode into. -+ * @param s the string to encode. -+ */ -+ public static void encode(ByteBuffer buffer, String s) -+ { -+ encode(CODES, buffer, s); -+ } -+ -+ /** -+ * @param s the string to encode in lowercase. -+ * @return the number of octets needed to encode the string, or -1 if it cannot be encoded. -+ */ -+ public static int octetsNeededLowerCase(String s) -+ { -+ return octetsNeeded(LCCODES, s); -+ } -+ -+ /** -+ * @param buffer the buffer to encode into in lowercase. -+ * @param s the string to encode. -+ */ -+ public static void encodeLowerCase(ByteBuffer buffer, String s) -+ { -+ encode(LCCODES, buffer, s); -+ } -+ -+ private static int octetsNeeded(final int[][] table, String s) -+ { -+ int needed = 0; -+ int len = s.length(); -+ for (int i = 0; i < len; i++) -+ { -+ char c = s.charAt(i); -+ if (HttpTokens.isIllegalFieldVchar(c)) -+ return -1; -+ needed += table[c][1]; -+ } -+ -+ return (needed + 7) / 8; -+ } -+ -+ /** -+ * @param table The table to encode by -+ * @param buffer The buffer to encode to -+ * @param s The string to encode -+ */ -+ private static void encode(final int[][] table, ByteBuffer buffer, String s) -+ { -+ long current = 0; -+ int n = 0; -+ int len = s.length(); -+ for (int i = 0; i < len; i++) -+ { -+ char c = s.charAt(i); -+ if (HttpTokens.isIllegalFieldVchar(c)) -+ throw new IllegalArgumentException(); -+ int code = table[c][0]; -+ int bits = table[c][1]; -+ -+ current <<= bits; -+ current |= code; -+ n += bits; -+ -+ while (n >= 8) -+ { -+ n -= 8; -+ buffer.put((byte)(current >> n)); -+ } -+ } -+ -+ if (n > 0) -+ { -+ current <<= (8 - n); -+ current |= (0xFF >>> n); -+ buffer.put((byte)(current)); -+ } -+ } -+} -diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitIntegerDecoder.java b/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitIntegerDecoder.java -new file mode 100644 -index 0000000..590b8c1 ---- /dev/null -+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitIntegerDecoder.java -@@ -0,0 +1,113 @@ -+// -+// ======================================================================== -+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -+// ------------------------------------------------------------------------ -+// All rights reserved. This program and the accompanying materials -+// are made available under the terms of the Eclipse Public License v1.0 -+// and Apache License v2.0 which accompanies this distribution. -+// -+// The Eclipse Public License is available at -+// http://www.eclipse.org/legal/epl-v10.html -+// -+// The Apache License v2.0 is available at -+// http://www.opensource.org/licenses/apache2.0.php -+// -+// You may elect to redistribute this code under either of these licenses. -+// ======================================================================== -+// -+ -+package org.eclipse.jetty.http.compression; -+ -+import java.nio.ByteBuffer; -+ -+/** -+ * Used to decode integers as described in RFC7541. -+ */ -+public class NBitIntegerDecoder -+{ -+ private int _prefix; -+ private long _total; -+ private long _multiplier; -+ private boolean _started; -+ -+ /** -+ * Set the prefix length in of the integer representation in bits. -+ * A prefix of 6 means the integer representation starts after the first 2 bits. -+ * @param prefix the number of bits in the integer prefix. -+ */ -+ public void setPrefix(int prefix) -+ { -+ if (_started) -+ throw new IllegalStateException(); -+ _prefix = prefix; -+ } -+ -+ /** -+ * Decode an integer from the buffer. If the buffer does not contain the complete integer representation -+ * a value of -1 is returned to indicate that more data is needed to complete parsing. -+ * This should be only after the prefix has been set with {@link #setPrefix(int)}. -+ * @param buffer the buffer containing the encoded integer. -+ * @return the decoded integer or -1 to indicate that more data is needed. -+ * @throws ArithmeticException if the value overflows a int. -+ */ -+ public int decodeInt(ByteBuffer buffer) -+ { -+ return Math.toIntExact(decodeLong(buffer)); -+ } -+ -+ /** -+ * Decode a long from the buffer. If the buffer does not contain the complete integer representation -+ * a value of -1 is returned to indicate that more data is needed to complete parsing. -+ * This should be only after the prefix has been set with {@link #setPrefix(int)}. -+ * @param buffer the buffer containing the encoded integer. -+ * @return the decoded long or -1 to indicate that more data is needed. -+ * @throws ArithmeticException if the value overflows a long. -+ */ -+ public long decodeLong(ByteBuffer buffer) -+ { -+ if (!_started) -+ { -+ if (!buffer.hasRemaining()) -+ return -1; -+ -+ _started = true; -+ _multiplier = 1; -+ int nbits = 0xFF >>> (8 - _prefix); -+ _total = buffer.get() & nbits; -+ if (_total < nbits) -+ { -+ long total = _total; -+ reset(); -+ return total; -+ } -+ } -+ -+ while (true) -+ { -+ // If we have no more remaining we return -1 to indicate that more data is needed to continue parsing. -+ if (!buffer.hasRemaining()) -+ return -1; -+ -+ int b = buffer.get() & 0xFF; -+ _total = Math.addExact(_total, (b & 127) * _multiplier); -+ _multiplier = Math.multiplyExact(_multiplier, 128); -+ if ((b & 128) == 0) -+ { -+ long total = _total; -+ reset(); -+ return total; -+ } -+ } -+ } -+ -+ /** -+ * Reset the internal state of the parser. -+ */ -+ public void reset() -+ { -+ _prefix = 0; -+ _total = 0; -+ _multiplier = 1; -+ _started = false; -+ } -+} -diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitIntegerEncoder.java b/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitIntegerEncoder.java -new file mode 100644 -index 0000000..f78440f ---- /dev/null -+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitIntegerEncoder.java -@@ -0,0 +1,96 @@ -+// -+// ======================================================================== -+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -+// ------------------------------------------------------------------------ -+// All rights reserved. This program and the accompanying materials -+// are made available under the terms of the Eclipse Public License v1.0 -+// and Apache License v2.0 which accompanies this distribution. -+// -+// The Eclipse Public License is available at -+// http://www.eclipse.org/legal/epl-v10.html -+// -+// The Apache License v2.0 is available at -+// http://www.opensource.org/licenses/apache2.0.php -+// -+// You may elect to redistribute this code under either of these licenses. -+// ======================================================================== -+// -+ -+package org.eclipse.jetty.http.compression; -+ -+import java.nio.ByteBuffer; -+ -+/** -+ * Used to encode integers as described in RFC7541. -+ */ -+public class NBitIntegerEncoder -+{ -+ private NBitIntegerEncoder() -+ { -+ } -+ -+ /** -+ * @param prefix the prefix used to encode this long. -+ * @param value the integer to encode. -+ * @return the number of octets it would take to encode the long. -+ */ -+ public static int octetsNeeded(int prefix, long value) -+ { -+ if (prefix <= 0 || prefix > 8) -+ throw new IllegalArgumentException(); -+ -+ int nbits = 0xFF >>> (8 - prefix); -+ value = value - nbits; -+ if (value < 0) -+ return 1; -+ if (value == 0) -+ return 2; -+ int lz = Long.numberOfLeadingZeros(value); -+ int log = 64 - lz; -+ -+ // The return value is 1 for the prefix + the number of 7-bit groups necessary to encode the value. -+ return 1 + (log + 6) / 7; -+ } -+ -+ /** -+ * -+ * @param buffer the buffer to encode into. -+ * @param prefix the prefix used to encode this long. -+ * @param value the long to encode into the buffer. -+ */ -+ public static void encode(ByteBuffer buffer, int prefix, long value) -+ { -+ if (prefix <= 0 || prefix > 8) -+ throw new IllegalArgumentException(); -+ -+ // If prefix is 8 we add an empty byte as we initially modify last byte from the buffer. -+ if (prefix == 8) -+ buffer.put((byte)0x00); -+ -+ int bits = 0xFF >>> (8 - prefix); -+ int p = buffer.position() - 1; -+ if (value < bits) -+ { -+ buffer.put(p, (byte)((buffer.get(p) & ~bits) | value)); -+ } -+ else -+ { -+ buffer.put(p, (byte)(buffer.get(p) | bits)); -+ long length = value - bits; -+ while (true) -+ { -+ // The value of ~0x7F is different to 0x80 because of all the 1s from the MSB. -+ if ((length & ~0x7FL) == 0) -+ { -+ buffer.put((byte)length); -+ return; -+ } -+ else -+ { -+ buffer.put((byte)((length & 0x7F) | 0x80)); -+ length >>>= 7; -+ } -+ } -+ } -+ } -+} -diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitStringDecoder.java b/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitStringDecoder.java -new file mode 100644 -index 0000000..a871597 ---- /dev/null -+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitStringDecoder.java -@@ -0,0 +1,138 @@ -+// -+// ======================================================================== -+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -+// ------------------------------------------------------------------------ -+// All rights reserved. This program and the accompanying materials -+// are made available under the terms of the Eclipse Public License v1.0 -+// and Apache License v2.0 which accompanies this distribution. -+// -+// The Eclipse Public License is available at -+// http://www.eclipse.org/legal/epl-v10.html -+// -+// The Apache License v2.0 is available at -+// http://www.opensource.org/licenses/apache2.0.php -+// -+// You may elect to redistribute this code under either of these licenses. -+// ======================================================================== -+// -+ -+package org.eclipse.jetty.http.compression; -+ -+import java.nio.ByteBuffer; -+ -+import org.eclipse.jetty.util.CharsetStringBuilder; -+ -+/** -+ *

Used to decode string literals as described in RFC7541.

-+ * -+ *

The string literal representation consists of a single bit to indicate whether huffman encoding is used, -+ * followed by the string byte length encoded with the n-bit integer representation also from RFC7541, and -+ * the bytes of the string are directly after this.

-+ * -+ *

Characters which are illegal field-vchar values are replaced with -+ * either ' ' or '?' as described in RFC9110

-+ */ -+public class NBitStringDecoder -+{ -+ private final NBitIntegerDecoder _integerDecoder; -+ private final HuffmanDecoder _huffmanBuilder; -+ private final CharsetStringBuilder.Iso88591StringBuilder _builder; -+ private boolean _huffman; -+ private int _count; -+ private int _length; -+ private int _prefix; -+ -+ private State _state = State.PARSING; -+ -+ private enum State -+ { -+ PARSING, -+ LENGTH, -+ VALUE -+ } -+ -+ public NBitStringDecoder() -+ { -+ _integerDecoder = new NBitIntegerDecoder(); -+ _huffmanBuilder = new HuffmanDecoder(); -+ _builder = new CharsetStringBuilder.Iso88591StringBuilder(); -+ } -+ -+ /** -+ * Set the prefix length in of the string representation in bits. -+ * A prefix of 6 means the string representation starts after the first 2 bits. -+ * @param prefix the number of bits in the string prefix. -+ */ -+ public void setPrefix(int prefix) -+ { -+ if (_state != State.PARSING) -+ throw new IllegalStateException(); -+ _prefix = prefix; -+ } -+ -+ /** -+ * Decode a string from the buffer. If the buffer does not contain the complete string representation -+ * then a value of null is returned to indicate that more data is needed to complete parsing. -+ * This should be only after the prefix has been set with {@link #setPrefix(int)}. -+ * @param buffer the buffer containing the encoded string. -+ * @return the decoded string or null to indicate that more data is needed. -+ * @throws ArithmeticException if the string length value overflows a int. -+ * @throws EncodingException if the string encoding is invalid. -+ */ -+ public String decode(ByteBuffer buffer) throws EncodingException -+ { -+ while (true) -+ { -+ switch (_state) -+ { -+ case PARSING: -+ byte firstByte = buffer.get(buffer.position()); -+ _huffman = ((0x80 >>> (8 - _prefix)) & firstByte) != 0; -+ _state = State.LENGTH; -+ _integerDecoder.setPrefix(_prefix - 1); -+ continue; -+ -+ case LENGTH: -+ _length = _integerDecoder.decodeInt(buffer); -+ if (_length < 0) -+ return null; -+ _state = State.VALUE; -+ _huffmanBuilder.setLength(_length); -+ continue; -+ -+ case VALUE: -+ String value = _huffman ? _huffmanBuilder.decode(buffer) : stringDecode(buffer); -+ if (value != null) -+ reset(); -+ return value; -+ -+ default: -+ throw new IllegalStateException(_state.name()); -+ } -+ } -+ } -+ -+ private String stringDecode(ByteBuffer buffer) -+ { -+ for (; _count < _length; _count++) -+ { -+ if (!buffer.hasRemaining()) -+ return null; -+ _builder.append(buffer.get()); -+ } -+ -+ return _builder.build(); -+ } -+ -+ public void reset() -+ { -+ _state = State.PARSING; -+ _integerDecoder.reset(); -+ _huffmanBuilder.reset(); -+ _builder.reset(); -+ _prefix = 0; -+ _count = 0; -+ _length = 0; -+ _huffman = false; -+ } -+} -diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitStringEncoder.java b/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitStringEncoder.java -new file mode 100644 -index 0000000..5729ec0 ---- /dev/null -+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitStringEncoder.java -@@ -0,0 +1,82 @@ -+// -+// ======================================================================== -+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -+// ------------------------------------------------------------------------ -+// All rights reserved. This program and the accompanying materials -+// are made available under the terms of the Eclipse Public License v1.0 -+// and Apache License v2.0 which accompanies this distribution. -+// -+// The Eclipse Public License is available at -+// http://www.eclipse.org/legal/epl-v10.html -+// -+// The Apache License v2.0 is available at -+// http://www.opensource.org/licenses/apache2.0.php -+// -+// You may elect to redistribute this code under either of these licenses. -+// ======================================================================== -+// -+ -+package org.eclipse.jetty.http.compression; -+ -+import java.nio.ByteBuffer; -+ -+import org.eclipse.jetty.http.HttpTokens; -+ -+public class NBitStringEncoder -+{ -+ private NBitStringEncoder() -+ { -+ } -+ -+ public static int octetsNeeded(int prefix, String value, boolean huffman) -+ { -+ if (prefix <= 0 || prefix > 8) -+ throw new IllegalArgumentException(); -+ -+ int contentPrefix = (prefix == 1) ? 8 : prefix - 1; -+ int encodedValueSize = huffman ? HuffmanEncoder.octetsNeeded(value) : value.length(); -+ int encodedLengthSize = NBitIntegerEncoder.octetsNeeded(contentPrefix, encodedValueSize); -+ -+ // If prefix was 1, then we count an extra byte needed for the prefix. -+ return encodedLengthSize + encodedValueSize + (prefix == 1 ? 1 : 0); -+ } -+ -+ public static void encode(ByteBuffer buffer, int prefix, String value, boolean huffman) -+ { -+ if (prefix <= 0 || prefix > 8) -+ throw new IllegalArgumentException(); -+ -+ byte huffmanFlag = huffman ? (byte)(0x01 << (prefix - 1)) : (byte)0x00; -+ if (prefix == 8) -+ { -+ buffer.put(huffmanFlag); -+ } -+ else -+ { -+ int p = buffer.position() - 1; -+ buffer.put(p, (byte)(buffer.get(p) | huffmanFlag)); -+ } -+ -+ // Start encoding size & content in rest of prefix. -+ // If prefix was 1 we set it back to 8 to indicate to start on a new byte. -+ prefix = (prefix == 1) ? 8 : prefix - 1; -+ -+ if (huffman) -+ { -+ int encodedValueSize = HuffmanEncoder.octetsNeeded(value); -+ NBitIntegerEncoder.encode(buffer, prefix, encodedValueSize); -+ HuffmanEncoder.encode(buffer, value); -+ } -+ else -+ { -+ int encodedValueSize = value.length(); -+ NBitIntegerEncoder.encode(buffer, prefix, encodedValueSize); -+ for (int i = 0; i < encodedValueSize; i++) -+ { -+ char c = value.charAt(i); -+ c = HttpTokens.sanitizeFieldVchar(c); -+ buffer.put((byte)c); -+ } -+ } -+ } -+} -diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HuffmanTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HuffmanTest.java -new file mode 100644 -index 0000000..e9e5ae8 ---- /dev/null -+++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HuffmanTest.java -@@ -0,0 +1,168 @@ -+// -+// ======================================================================== -+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -+// ------------------------------------------------------------------------ -+// All rights reserved. This program and the accompanying materials -+// are made available under the terms of the Eclipse Public License v1.0 -+// and Apache License v2.0 which accompanies this distribution. -+// -+// The Eclipse Public License is available at -+// http://www.eclipse.org/legal/epl-v10.html -+// -+// The Apache License v2.0 is available at -+// http://www.opensource.org/licenses/apache2.0.php -+// -+// You may elect to redistribute this code under either of these licenses. -+// ======================================================================== -+// -+ -+package org.eclipse.jetty.http; -+ -+import java.nio.ByteBuffer; -+import java.util.Locale; -+import java.util.stream.Stream; -+ -+import org.eclipse.jetty.http.compression.EncodingException; -+import org.eclipse.jetty.http.compression.HuffmanDecoder; -+import org.eclipse.jetty.http.compression.HuffmanEncoder; -+import org.eclipse.jetty.util.BufferUtil; -+import org.eclipse.jetty.util.TypeUtil; -+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.equalTo; -+import static org.hamcrest.Matchers.greaterThan; -+import static org.junit.jupiter.api.Assertions.assertEquals; -+import static org.junit.jupiter.api.Assertions.assertThrows; -+ -+public class HuffmanTest -+{ -+ public static String decode(ByteBuffer buffer, int length) throws EncodingException -+ { -+ HuffmanDecoder huffmanDecoder = new HuffmanDecoder(); -+ huffmanDecoder.setLength(length); -+ String decoded = huffmanDecoder.decode(buffer); -+ if (decoded == null) -+ throw new EncodingException("invalid string encoding"); -+ -+ huffmanDecoder.reset(); -+ return decoded; -+ } -+ -+ public static Stream data() -+ { -+ return Stream.of( -+ new String[][]{ -+ {"D.4.1", "f1e3c2e5f23a6ba0ab90f4ff", "www.example.com"}, -+ {"D.4.2", "a8eb10649cbf", "no-cache"}, -+ {"D.6.1k", "6402", "302"}, -+ {"D.6.1v", "aec3771a4b", "private"}, -+ {"D.6.1d", "d07abe941054d444a8200595040b8166e082a62d1bff", "Mon, 21 Oct 2013 20:13:21 GMT"}, -+ {"D.6.1l", "9d29ad171863c78f0b97c8e9ae82ae43d3", "https://www.example.com"}, -+ {"D.6.2te", "640cff", "303"}, -+ }).map(Arguments::of); -+ } -+ -+ @ParameterizedTest(name = "[{index}] spec={0}") -+ @MethodSource("data") -+ public void testDecode(String specSection, String hex, String expected) throws Exception -+ { -+ byte[] encoded = TypeUtil.fromHexString(hex); -+ HuffmanDecoder huffmanDecoder = new HuffmanDecoder(); -+ huffmanDecoder.setLength(encoded.length); -+ String decoded = huffmanDecoder.decode(ByteBuffer.wrap(encoded)); -+ assertEquals(expected, decoded, specSection); -+ } -+ -+ @ParameterizedTest(name = "[{index}] spec={0}") -+ @MethodSource("data") -+ public void testEncode(String specSection, String hex, String expected) -+ { -+ ByteBuffer buf = BufferUtil.allocate(1024); -+ int pos = BufferUtil.flipToFill(buf); -+ HuffmanEncoder.encode(buf, expected); -+ BufferUtil.flipToFlush(buf, pos); -+ String encoded = TypeUtil.toHexString(BufferUtil.toArray(buf)).toLowerCase(Locale.ENGLISH); -+ assertEquals(hex, encoded, specSection); -+ assertEquals(hex.length() / 2, HuffmanEncoder.octetsNeeded(expected)); -+ } -+ -+ public static Stream testDecode8859OnlyArguments() -+ { -+ return Stream.of( -+ // These are valid characters for ISO-8859-1. -+ Arguments.of("FfFe6f", (char)128), -+ Arguments.of("FfFfFbBf", (char)255), -+ -+ // RFC9110 specifies these to be replaced as ' ' during decoding. -+ Arguments.of("FfC7", ' '), // (char)0 -+ Arguments.of("FfFfFfF7", ' '), // '\r' -+ Arguments.of("FfFfFfF3", ' '), // '\n' -+ -+ // We replace control chars with the default replacement character of '?'. -+ Arguments.of("FfFfFfBf", '?') // (char)(' ' - 1) -+ ); -+ } -+ -+ @ParameterizedTest(name = "[{index}]") // don't include unprintable character in test display-name -+ @MethodSource("testDecode8859OnlyArguments") -+ public void testDecode8859Only(String hexString, char expected) throws Exception -+ { -+ ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(hexString)); -+ String decoded = decode(buffer, buffer.remaining()); -+ assertThat(decoded, equalTo("" + expected)); -+ } -+ -+ public static Stream testEncode8859OnlyArguments() -+ { -+ return Stream.of( -+ Arguments.of((char)128, (char)128), -+ Arguments.of((char)255, (char)255), -+ Arguments.of((char)0, null), -+ Arguments.of('\r', null), -+ Arguments.of('\n', null), -+ Arguments.of((char)456, null), -+ Arguments.of((char)256, null), -+ Arguments.of((char)-1, null), -+ Arguments.of((char)(' ' - 1), null) -+ ); -+ } -+ -+ @ParameterizedTest(name = "[{index}]") // don't include unprintable character in test display-name -+ @MethodSource("testEncode8859OnlyArguments") -+ public void testEncode8859Only(char value, Character expectedValue) throws Exception -+ { -+ String s = "value = '" + value + "'"; -+ -+ // If expected is null we should not be able to encode. -+ if (expectedValue == null) -+ { -+ assertThat(HuffmanEncoder.octetsNeeded(s), equalTo(-1)); -+ assertThrows(Throwable.class, () -> encode(s)); -+ return; -+ } -+ -+ String expected = "value = '" + expectedValue + "'"; -+ assertThat(HuffmanEncoder.octetsNeeded(s), greaterThan(0)); -+ ByteBuffer buffer = encode(s); -+ String decode = decode(buffer); -+ System.err.println("decoded: " + decode); -+ assertThat(decode, equalTo(expected)); -+ } -+ -+ private ByteBuffer encode(String s) -+ { -+ ByteBuffer buffer = BufferUtil.allocate(32); -+ BufferUtil.clearToFill(buffer); -+ HuffmanEncoder.encode(buffer, s); -+ BufferUtil.flipToFlush(buffer, 0); -+ return buffer; -+ } -+ -+ private String decode(ByteBuffer buffer) throws Exception -+ { -+ return decode(buffer, buffer.remaining()); -+ } -+} -diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/NBitIntegerTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/NBitIntegerTest.java -new file mode 100644 -index 0000000..03f7b5f ---- /dev/null -+++ b/jetty-http/src/test/java/org/eclipse/jetty/http/NBitIntegerTest.java -@@ -0,0 +1,207 @@ -+// -+// ======================================================================== -+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -+// ------------------------------------------------------------------------ -+// All rights reserved. This program and the accompanying materials -+// are made available under the terms of the Eclipse Public License v1.0 -+// and Apache License v2.0 which accompanies this distribution. -+// -+// The Eclipse Public License is available at -+// http://www.eclipse.org/legal/epl-v10.html -+// -+// The Apache License v2.0 is available at -+// http://www.opensource.org/licenses/apache2.0.php -+// -+// You may elect to redistribute this code under either of these licenses. -+// ======================================================================== -+// -+ -+package org.eclipse.jetty.http; -+ -+import java.nio.ByteBuffer; -+ -+import org.eclipse.jetty.http.compression.NBitIntegerDecoder; -+import org.eclipse.jetty.http.compression.NBitIntegerEncoder; -+import org.eclipse.jetty.util.BufferUtil; -+import org.eclipse.jetty.util.TypeUtil; -+import org.junit.jupiter.api.Test; -+ -+import static org.junit.jupiter.api.Assertions.assertEquals; -+ -+@SuppressWarnings("PointlessArithmeticExpression") -+public class NBitIntegerTest -+{ -+ private final NBitIntegerDecoder _decoder = new NBitIntegerDecoder(); -+ -+ @Test -+ public void testOctetsNeeded() -+ { -+ assertEquals(1, NBitIntegerEncoder.octetsNeeded(5, 10)); -+ assertEquals(3, NBitIntegerEncoder.octetsNeeded(5, 1337)); -+ assertEquals(1, NBitIntegerEncoder.octetsNeeded(8, 42)); -+ assertEquals(3, NBitIntegerEncoder.octetsNeeded(8, 1337)); -+ -+ assertEquals(1, NBitIntegerEncoder.octetsNeeded(6, 62)); -+ assertEquals(2, NBitIntegerEncoder.octetsNeeded(6, 63)); -+ assertEquals(2, NBitIntegerEncoder.octetsNeeded(6, 64)); -+ assertEquals(3, NBitIntegerEncoder.octetsNeeded(6, 63 + 0x00 + 0x80 * 0x01)); -+ assertEquals(4, NBitIntegerEncoder.octetsNeeded(6, 63 + 0x00 + 0x80 * 0x80)); -+ assertEquals(5, NBitIntegerEncoder.octetsNeeded(6, 63 + 0x00 + 0x80 * 0x80 * 0x80)); -+ } -+ -+ @Test -+ public void testEncode() -+ { -+ testEncode(6, 0, "00"); -+ testEncode(6, 1, "01"); -+ testEncode(6, 62, "3e"); -+ testEncode(6, 63, "3f00"); -+ testEncode(6, 63 + 1, "3f01"); -+ testEncode(6, 63 + 0x7e, "3f7e"); -+ testEncode(6, 63 + 0x7f, "3f7f"); -+ testEncode(6, 63 + 0x00 + 0x80 * 0x01, "3f8001"); -+ testEncode(6, 63 + 0x01 + 0x80 * 0x01, "3f8101"); -+ testEncode(6, 63 + 0x7f + 0x80 * 0x01, "3fFf01"); -+ testEncode(6, 63 + 0x00 + 0x80 * 0x02, "3f8002"); -+ testEncode(6, 63 + 0x01 + 0x80 * 0x02, "3f8102"); -+ testEncode(6, 63 + 0x7f + 0x80 * 0x7f, "3fFf7f"); -+ testEncode(6, 63 + 0x00 + 0x80 * 0x80, "3f808001"); -+ testEncode(6, 63 + 0x7f + 0x80 * 0x80 * 0x7f, "3fFf807f"); -+ testEncode(6, 63 + 0x00 + 0x80 * 0x80 * 0x80, "3f80808001"); -+ -+ testEncode(8, 0, "00"); -+ testEncode(8, 1, "01"); -+ testEncode(8, 128, "80"); -+ testEncode(8, 254, "Fe"); -+ testEncode(8, 255, "Ff00"); -+ testEncode(8, 255 + 1, "Ff01"); -+ testEncode(8, 255 + 0x7e, "Ff7e"); -+ testEncode(8, 255 + 0x7f, "Ff7f"); -+ testEncode(8, 255 + 0x80, "Ff8001"); -+ testEncode(8, 255 + 0x00 + 0x80 * 0x80, "Ff808001"); -+ } -+ -+ public void testEncode(int n, int i, String expected) -+ { -+ ByteBuffer buf = BufferUtil.allocate(16); -+ int p = BufferUtil.flipToFill(buf); -+ if (n < 8) -+ buf.put((byte)0x00); -+ NBitIntegerEncoder.encode(buf, n, i); -+ BufferUtil.flipToFlush(buf, p); -+ String r = TypeUtil.toHexString(BufferUtil.toArray(buf)); -+ assertEquals(expected, r); -+ -+ assertEquals(expected.length() / 2, NBitIntegerEncoder.octetsNeeded(n, i)); -+ } -+ -+ @Test -+ public void testDecode() -+ { -+ testDecode(6, 0, "00"); -+ testDecode(6, 1, "01"); -+ testDecode(6, 62, "3e"); -+ testDecode(6, 63, "3f00"); -+ testDecode(6, 63 + 1, "3f01"); -+ testDecode(6, 63 + 0x7e, "3f7e"); -+ testDecode(6, 63 + 0x7f, "3f7f"); -+ testDecode(6, 63 + 0x80, "3f8001"); -+ testDecode(6, 63 + 0x81, "3f8101"); -+ testDecode(6, 63 + 0x7f + 0x80 * 0x01, "3fFf01"); -+ testDecode(6, 63 + 0x00 + 0x80 * 0x02, "3f8002"); -+ testDecode(6, 63 + 0x01 + 0x80 * 0x02, "3f8102"); -+ testDecode(6, 63 + 0x7f + 0x80 * 0x7f, "3fFf7f"); -+ testDecode(6, 63 + 0x00 + 0x80 * 0x80, "3f808001"); -+ testDecode(6, 63 + 0x7f + 0x80 * 0x80 * 0x7f, "3fFf807f"); -+ testDecode(6, 63 + 0x00 + 0x80 * 0x80 * 0x80, "3f80808001"); -+ -+ testDecode(8, 0, "00"); -+ testDecode(8, 1, "01"); -+ testDecode(8, 128, "80"); -+ testDecode(8, 254, "Fe"); -+ testDecode(8, 255, "Ff00"); -+ testDecode(8, 255 + 1, "Ff01"); -+ testDecode(8, 255 + 0x7e, "Ff7e"); -+ testDecode(8, 255 + 0x7f, "Ff7f"); -+ testDecode(8, 255 + 0x80, "Ff8001"); -+ testDecode(8, 255 + 0x00 + 0x80 * 0x80, "Ff808001"); -+ } -+ -+ public void testDecode(int n, int expected, String encoded) -+ { -+ ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); -+ _decoder.setPrefix(n); -+ assertEquals(expected, _decoder.decodeInt(buf)); -+ } -+ -+ @Test -+ public void testEncodeExampleD11() -+ { -+ ByteBuffer buf = BufferUtil.allocate(16); -+ int p = BufferUtil.flipToFill(buf); -+ buf.put((byte)0x77); -+ buf.put((byte)0xFF); -+ NBitIntegerEncoder.encode(buf, 5, 10); -+ BufferUtil.flipToFlush(buf, p); -+ -+ String r = TypeUtil.toHexString(BufferUtil.toArray(buf)); -+ -+ assertEquals("77Ea", r); -+ } -+ -+ @Test -+ public void testDecodeExampleD11() -+ { -+ ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("77EaFF")); -+ buf.position(1); -+ _decoder.setPrefix(5); -+ assertEquals(10, _decoder.decodeInt(buf)); -+ } -+ -+ @Test -+ public void testEncodeExampleD12() -+ { -+ ByteBuffer buf = BufferUtil.allocate(16); -+ int p = BufferUtil.flipToFill(buf); -+ buf.put((byte)0x88); -+ buf.put((byte)0x00); -+ NBitIntegerEncoder.encode(buf, 5, 1337); -+ BufferUtil.flipToFlush(buf, p); -+ -+ String r = TypeUtil.toHexString(BufferUtil.toArray(buf)); -+ assertEquals("881f9a0a", r); -+ } -+ -+ @Test -+ public void testDecodeExampleD12() -+ { -+ ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("881f9a0aff")); -+ buf.position(1); -+ _decoder.setPrefix(5); -+ assertEquals(1337, _decoder.decodeInt(buf)); -+ } -+ -+ @Test -+ public void testEncodeExampleD13() -+ { -+ ByteBuffer buf = BufferUtil.allocate(16); -+ int p = BufferUtil.flipToFill(buf); -+ buf.put((byte)0x88); -+ buf.put((byte)0xFF); -+ NBitIntegerEncoder.encode(buf, 8, 42); -+ BufferUtil.flipToFlush(buf, p); -+ -+ String r = TypeUtil.toHexString(BufferUtil.toArray(buf)); -+ -+ assertEquals("88Ff2a", r); -+ } -+ -+ @Test -+ public void testDecodeExampleD13() -+ { -+ ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("882aFf")); -+ buf.position(1); -+ _decoder.setPrefix(8); -+ assertEquals(42, _decoder.decodeInt(buf)); -+ } -+} -diff --git a/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java b/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java -index 18de3d7..14a6491 100644 ---- a/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java -+++ b/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java -@@ -36,6 +36,7 @@ import org.eclipse.jetty.http2.FlowControlStrategy; - import org.eclipse.jetty.http2.api.Session; - import org.eclipse.jetty.http2.frames.Frame; - import org.eclipse.jetty.http2.frames.SettingsFrame; -+import org.eclipse.jetty.http2.hpack.HpackContext; - import org.eclipse.jetty.io.ByteBufferPool; - import org.eclipse.jetty.io.ClientConnectionFactory; - import org.eclipse.jetty.io.Connection; -@@ -125,6 +126,7 @@ public class HTTP2Client extends ContainerLifeCycle - private int selectors = 1; - private long idleTimeout = 30000; - private long connectTimeout = 10000; -+ private long streamIdleTimeout; - private boolean connectBlocking; - private SocketAddress bindAddress; - private boolean tcpNoDelay = true; -@@ -132,11 +134,13 @@ public class HTTP2Client extends ContainerLifeCycle - private List protocols = Arrays.asList("h2", "h2-17", "h2-16", "h2-15", "h2-14"); - private int initialSessionRecvWindow = 16 * 1024 * 1024; - private int initialStreamRecvWindow = 8 * 1024 * 1024; -- private int maxFrameLength = Frame.DEFAULT_MAX_LENGTH; -+ private int maxFrameSize = Frame.DEFAULT_MAX_LENGTH; - private int maxConcurrentPushedStreams = 32; - private int maxSettingsKeys = SettingsFrame.DEFAULT_MAX_KEYS; -- private int maxDynamicTableSize = 4096; -+ private int maxDecoderTableCapacity = HpackContext.DEFAULT_MAX_TABLE_CAPACITY; -+ private int maxEncoderTableCapacity = HpackContext.DEFAULT_MAX_TABLE_CAPACITY; - private int maxHeaderBlockFragment = 0; -+ private int maxResponseHeadersSize = 8 * 1024; - private FlowControlStrategy.Factory flowControlStrategyFactory = () -> new BufferingFlowControlStrategy(0.5F); - - @Override -@@ -263,6 +267,17 @@ public class HTTP2Client extends ContainerLifeCycle - this.idleTimeout = idleTimeout; - } - -+ @ManagedAttribute("The stream idle timeout in milliseconds") -+ public long getStreamIdleTimeout() -+ { -+ return streamIdleTimeout; -+ } -+ -+ public void setStreamIdleTimeout(long streamIdleTimeout) -+ { -+ this.streamIdleTimeout = streamIdleTimeout; -+ } -+ - @ManagedAttribute("The connect timeout in milliseconds") - public long getConnectTimeout() - { -@@ -352,15 +367,28 @@ public class HTTP2Client extends ContainerLifeCycle - this.initialStreamRecvWindow = initialStreamRecvWindow; - } - -+ @Deprecated - @ManagedAttribute("The max frame length in bytes") - public int getMaxFrameLength() - { -- return maxFrameLength; -+ return getMaxFrameSize(); - } - -+ @Deprecated - public void setMaxFrameLength(int maxFrameLength) - { -- this.maxFrameLength = maxFrameLength; -+ setMaxFrameSize(maxFrameLength); -+ } -+ -+ @ManagedAttribute("The max frame size in bytes") -+ public int getMaxFrameSize() -+ { -+ return maxFrameSize; -+ } -+ -+ public void setMaxFrameSize(int maxFrameSize) -+ { -+ this.maxFrameSize = maxFrameSize; - } - - @ManagedAttribute("The max number of concurrent pushed streams") -@@ -385,15 +413,45 @@ public class HTTP2Client extends ContainerLifeCycle - this.maxSettingsKeys = maxSettingsKeys; - } - -+ @ManagedAttribute("The HPACK encoder dynamic table maximum capacity") -+ public int getMaxEncoderTableCapacity() -+ { -+ return maxEncoderTableCapacity; -+ } -+ -+ /** -+ *

Sets the limit for the encoder HPACK dynamic table capacity.

-+ *

Setting this value to {@code 0} disables the use of the dynamic table.

-+ * -+ * @param maxEncoderTableCapacity The HPACK encoder dynamic table maximum capacity -+ */ -+ public void setMaxEncoderTableCapacity(int maxEncoderTableCapacity) -+ { -+ this.maxEncoderTableCapacity = maxEncoderTableCapacity; -+ } -+ -+ @ManagedAttribute("The HPACK decoder dynamic table maximum capacity") -+ public int getMaxDecoderTableCapacity() -+ { -+ return maxDecoderTableCapacity; -+ } -+ -+ public void setMaxDecoderTableCapacity(int maxDecoderTableCapacity) -+ { -+ this.maxDecoderTableCapacity = maxDecoderTableCapacity; -+ } -+ -+ @Deprecated - @ManagedAttribute("The HPACK dynamic table maximum size") - public int getMaxDynamicTableSize() - { -- return maxDynamicTableSize; -+ return getMaxDecoderTableCapacity(); - } - -+ @Deprecated - public void setMaxDynamicTableSize(int maxDynamicTableSize) - { -- this.maxDynamicTableSize = maxDynamicTableSize; -+ setMaxDecoderTableCapacity(maxDynamicTableSize); - } - - @ManagedAttribute("The max size of header block fragments") -@@ -407,6 +465,17 @@ public class HTTP2Client extends ContainerLifeCycle - this.maxHeaderBlockFragment = maxHeaderBlockFragment; - } - -+ @ManagedAttribute("The max size of response headers") -+ public int getMaxResponseHeadersSize() -+ { -+ return maxResponseHeadersSize; -+ } -+ -+ public void setMaxResponseHeadersSize(int maxResponseHeadersSize) -+ { -+ this.maxResponseHeadersSize = maxResponseHeadersSize; -+ } -+ - public void connect(InetSocketAddress address, Session.Listener listener, Promise promise) - { - connect(null, address, listener, promise); -diff --git a/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java b/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java -index a721079..de96fd6 100644 ---- a/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java -+++ b/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java -@@ -27,10 +27,12 @@ import org.eclipse.jetty.http2.FlowControlStrategy; - import org.eclipse.jetty.http2.HTTP2Connection; - import org.eclipse.jetty.http2.ISession; - import org.eclipse.jetty.http2.api.Session; -+import org.eclipse.jetty.http2.frames.Frame; - import org.eclipse.jetty.http2.frames.PrefaceFrame; - import org.eclipse.jetty.http2.frames.SettingsFrame; - import org.eclipse.jetty.http2.frames.WindowUpdateFrame; - import org.eclipse.jetty.http2.generator.Generator; -+import org.eclipse.jetty.http2.hpack.HpackContext; - import org.eclipse.jetty.http2.parser.Parser; - import org.eclipse.jetty.io.ByteBufferPool; - import org.eclipse.jetty.io.ClientConnectionFactory; -@@ -56,25 +58,32 @@ public class HTTP2ClientConnectionFactory implements ClientConnectionFactory - public Connection newConnection(EndPoint endPoint, Map context) - { - HTTP2Client client = (HTTP2Client)context.get(CLIENT_CONTEXT_KEY); -- ByteBufferPool byteBufferPool = (ByteBufferPool)context.get(BYTE_BUFFER_POOL_CONTEXT_KEY); -- Executor executor = (Executor)context.get(EXECUTOR_CONTEXT_KEY); -- Scheduler scheduler = (Scheduler)context.get(SCHEDULER_CONTEXT_KEY); -+ ByteBufferPool byteBufferPool = client.getByteBufferPool(); -+ Executor executor = client.getExecutor(); -+ Scheduler scheduler = client.getScheduler(); - Session.Listener listener = (Session.Listener)context.get(SESSION_LISTENER_CONTEXT_KEY); - @SuppressWarnings("unchecked") -- Promise promise = (Promise)context.get(SESSION_PROMISE_CONTEXT_KEY); -+ Promise sessionPromise = (Promise)context.get(SESSION_PROMISE_CONTEXT_KEY); - -- Generator generator = new Generator(byteBufferPool, client.getMaxDynamicTableSize(), client.getMaxHeaderBlockFragment()); -+ Generator generator = new Generator(byteBufferPool, client.getMaxHeaderBlockFragment()); - FlowControlStrategy flowControl = client.getFlowControlStrategyFactory().newFlowControlStrategy(); -- HTTP2ClientSession session = new HTTP2ClientSession(scheduler, endPoint, generator, listener, flowControl); -- session.setMaxRemoteStreams(client.getMaxConcurrentPushedStreams()); - -- Parser parser = new Parser(byteBufferPool, session, 4096, 8192); -- parser.setMaxFrameLength(client.getMaxFrameLength()); -+ Parser parser = new Parser(byteBufferPool, client.getMaxResponseHeadersSize()); -+ parser.setMaxFrameSize(client.getMaxFrameSize()); - parser.setMaxSettingsKeys(client.getMaxSettingsKeys()); - -+ HTTP2ClientSession session = new HTTP2ClientSession(scheduler, endPoint, parser, generator, listener, flowControl); -+ session.setMaxRemoteStreams(client.getMaxConcurrentPushedStreams()); -+ session.setMaxEncoderTableCapacity(client.getMaxEncoderTableCapacity()); -+ long streamIdleTimeout = client.getStreamIdleTimeout(); -+ if (streamIdleTimeout > 0) -+ session.setStreamIdleTimeout(streamIdleTimeout); -+ - HTTP2ClientConnection connection = new HTTP2ClientConnection(client, byteBufferPool, executor, endPoint, -- parser, session, client.getInputBufferSize(), promise, listener); -+ session, client.getInputBufferSize(), sessionPromise, listener); - connection.addListener(connectionListener); -+ parser.init(connection.wrapParserListener(session)); -+ - return customize(connection, context); - } - -@@ -84,9 +93,9 @@ public class HTTP2ClientConnectionFactory implements ClientConnectionFactory - private final Promise promise; - private final Session.Listener listener; - -- private HTTP2ClientConnection(HTTP2Client client, ByteBufferPool byteBufferPool, Executor executor, EndPoint endpoint, Parser parser, ISession session, int bufferSize, Promise promise, Session.Listener listener) -+ private HTTP2ClientConnection(HTTP2Client client, ByteBufferPool byteBufferPool, Executor executor, EndPoint endpoint, ISession session, int bufferSize, Promise promise, Session.Listener listener) - { -- super(byteBufferPool, executor, endpoint, parser, session, bufferSize); -+ super(byteBufferPool, executor, endpoint, session, bufferSize); - this.client = client; - this.promise = promise; - this.listener = listener; -@@ -98,12 +107,52 @@ public class HTTP2ClientConnectionFactory implements ClientConnectionFactory - Map settings = listener.onPreface(getSession()); - if (settings == null) - settings = new HashMap<>(); -- settings.computeIfAbsent(SettingsFrame.INITIAL_WINDOW_SIZE, k -> client.getInitialStreamRecvWindow()); -- settings.computeIfAbsent(SettingsFrame.MAX_CONCURRENT_STREAMS, k -> client.getMaxConcurrentPushedStreams()); - -- Integer maxFrameLength = settings.get(SettingsFrame.MAX_FRAME_SIZE); -- if (maxFrameLength != null) -- getParser().setMaxFrameLength(maxFrameLength); -+ // Below we want to populate any settings to send to the server -+ // that have a different default than what prescribed by the RFC. -+ // Changing the configuration is done when the SETTINGS is sent. -+ -+ settings.compute(SettingsFrame.HEADER_TABLE_SIZE, (k, v) -> -+ { -+ if (v == null) -+ { -+ v = client.getMaxDecoderTableCapacity(); -+ if (v == HpackContext.DEFAULT_MAX_TABLE_CAPACITY) -+ v = null; -+ } -+ return v; -+ }); -+ settings.computeIfAbsent(SettingsFrame.MAX_CONCURRENT_STREAMS, k -> client.getMaxConcurrentPushedStreams()); -+ settings.compute(SettingsFrame.INITIAL_WINDOW_SIZE, (k, v) -> -+ { -+ if (v == null) -+ { -+ v = client.getInitialStreamRecvWindow(); -+ if (v == FlowControlStrategy.DEFAULT_WINDOW_SIZE) -+ v = null; -+ } -+ return v; -+ }); -+ settings.compute(SettingsFrame.MAX_FRAME_SIZE, (k, v) -> -+ { -+ if (v == null) -+ { -+ v = client.getMaxFrameSize(); -+ if (v == Frame.DEFAULT_MAX_LENGTH) -+ v = null; -+ } -+ return v; -+ }); -+ settings.compute(SettingsFrame.MAX_HEADER_LIST_SIZE, (k, v) -> -+ { -+ if (v == null) -+ { -+ v = client.getMaxResponseHeadersSize(); -+ if (v <= 0) -+ v = null; -+ } -+ return v; -+ }); - - PrefaceFrame prefaceFrame = new PrefaceFrame(); - SettingsFrame settingsFrame = new SettingsFrame(settings, false); -diff --git a/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientSession.java b/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientSession.java -index 2092d22..c756a0a 100644 ---- a/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientSession.java -+++ b/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientSession.java -@@ -29,6 +29,7 @@ import org.eclipse.jetty.http2.api.Stream; - import org.eclipse.jetty.http2.frames.HeadersFrame; - import org.eclipse.jetty.http2.frames.PushPromiseFrame; - import org.eclipse.jetty.http2.generator.Generator; -+import org.eclipse.jetty.http2.parser.Parser; - import org.eclipse.jetty.io.EndPoint; - import org.eclipse.jetty.util.Callback; - import org.eclipse.jetty.util.log.Log; -@@ -39,9 +40,16 @@ public class HTTP2ClientSession extends HTTP2Session - { - private static final Logger LOG = Log.getLogger(HTTP2ClientSession.class); - -+ @Deprecated - public HTTP2ClientSession(Scheduler scheduler, EndPoint endPoint, Generator generator, Session.Listener listener, FlowControlStrategy flowControl) - { -- super(scheduler, endPoint, generator, listener, flowControl, 1); -+ this(scheduler, endPoint, null, generator, listener, flowControl); -+ throw new UnsupportedOperationException(); -+ } -+ -+ public HTTP2ClientSession(Scheduler scheduler, EndPoint endPoint, Parser parser, Generator generator, Session.Listener listener, FlowControlStrategy flowControl) -+ { -+ super(scheduler, endPoint, parser, generator, listener, flowControl, 1); - } - - @Override -diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/HTTP2Test.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/HTTP2Test.java -index 6f74337..99e4d65 100644 ---- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/HTTP2Test.java -+++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/HTTP2Test.java -@@ -25,6 +25,7 @@ import java.nio.charset.StandardCharsets; - import java.util.HashMap; - import java.util.Map; - import java.util.Random; -+import java.util.concurrent.CompletableFuture; - import java.util.concurrent.CountDownLatch; - import java.util.concurrent.ExecutionException; - import java.util.concurrent.TimeUnit; -@@ -39,6 +40,7 @@ import org.eclipse.jetty.http.HttpStatus; - import org.eclipse.jetty.http.HttpVersion; - import org.eclipse.jetty.http.MetaData; - import org.eclipse.jetty.http2.ErrorCode; -+import org.eclipse.jetty.http2.HTTP2Session; - import org.eclipse.jetty.http2.api.Session; - import org.eclipse.jetty.http2.api.Stream; - import org.eclipse.jetty.http2.api.server.ServerSessionListener; -@@ -48,10 +50,7 @@ import org.eclipse.jetty.http2.frames.HeadersFrame; - import org.eclipse.jetty.http2.frames.ResetFrame; - import org.eclipse.jetty.http2.frames.SettingsFrame; - import org.eclipse.jetty.http2.hpack.HpackException; --import org.eclipse.jetty.http2.parser.RateControl; --import org.eclipse.jetty.http2.parser.ServerParser; - import org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory; --import org.eclipse.jetty.server.Connector; - import org.eclipse.jetty.server.HttpConfiguration; - import org.eclipse.jetty.util.BufferUtil; - import org.eclipse.jetty.util.Callback; -@@ -59,13 +58,17 @@ import org.eclipse.jetty.util.FuturePromise; - import org.eclipse.jetty.util.IO; - import org.eclipse.jetty.util.Jetty; - import org.eclipse.jetty.util.Promise; -+import org.eclipse.jetty.util.StringUtil; - import org.junit.jupiter.api.Test; - - import static org.hamcrest.MatcherAssert.assertThat; -+import static org.hamcrest.Matchers.containsString; -+import static org.hamcrest.Matchers.equalTo; - import static org.hamcrest.Matchers.instanceOf; - import static org.junit.jupiter.api.Assertions.assertEquals; - import static org.junit.jupiter.api.Assertions.assertFalse; - import static org.junit.jupiter.api.Assertions.assertNotNull; -+import static org.junit.jupiter.api.Assertions.assertNull; - import static org.junit.jupiter.api.Assertions.assertThrows; - import static org.junit.jupiter.api.Assertions.assertTrue; - -@@ -738,6 +741,7 @@ public class HTTP2Test extends AbstractTest - @Test - public void testGoAwayRespondedWithGoAway() throws Exception - { -+ CountDownLatch goAwayLatch = new CountDownLatch(1); - ServerSessionListener.Adapter serverListener = new ServerSessionListener.Adapter() - { - @Override -@@ -749,24 +753,15 @@ public class HTTP2Test extends AbstractTest - stream.getSession().close(ErrorCode.NO_ERROR.code, null, Callback.NOOP); - return null; - } -- }; -- CountDownLatch goAwayLatch = new CountDownLatch(1); -- RawHTTP2ServerConnectionFactory connectionFactory = new RawHTTP2ServerConnectionFactory(new HttpConfiguration(), serverListener) -- { -+ - @Override -- protected ServerParser newServerParser(Connector connector, ServerParser.Listener listener, RateControl rateControl) -+ public void onGoAway(Session session, GoAwayFrame frame) - { -- return super.newServerParser(connector, new ServerParser.Listener.Wrapper(listener) -- { -- @Override -- public void onGoAway(GoAwayFrame frame) -- { -- super.onGoAway(frame); -- goAwayLatch.countDown(); -- } -- }, rateControl); -+ goAwayLatch.countDown(); - } - }; -+ -+ RawHTTP2ServerConnectionFactory connectionFactory = new RawHTTP2ServerConnectionFactory(new HttpConfiguration(), serverListener); - prepareServer(connectionFactory); - server.start(); - -@@ -893,6 +888,150 @@ public class HTTP2Test extends AbstractTest - assertTrue(resetLatch.await(5, TimeUnit.SECONDS)); - } - -+ @Test -+ public void testClientSendsLargeHeader() throws Exception -+ { -+ CountDownLatch settingsLatch = new CountDownLatch(2); -+ -+ CompletableFuture serverFailureFuture = new CompletableFuture<>(); -+ CompletableFuture serverCloseReasonFuture = new CompletableFuture<>(); -+ start(new ServerSessionListener.Adapter() -+ { -+ @Override -+ public void onSettings(Session session, SettingsFrame frame) -+ { -+ settingsLatch.countDown(); -+ } -+ -+ @Override -+ public void onFailure(Session session, Throwable failure) -+ { -+ serverFailureFuture.complete(failure); -+ } -+ -+ @Override -+ public void onClose(Session session, GoAwayFrame frame) -+ { -+ serverCloseReasonFuture.complete(frame.tryConvertPayload()); -+ } -+ }); -+ -+ CompletableFuture clientFailureFuture = new CompletableFuture<>(); -+ CompletableFuture clientCloseReasonFuture = new CompletableFuture<>(); -+ Session.Listener.Adapter listener = new Session.Listener.Adapter() -+ { -+ @Override -+ public void onSettings(Session session, SettingsFrame frame) -+ { -+ settingsLatch.countDown(); -+ } -+ -+ @Override -+ public void onFailure(Session session, Throwable failure) -+ { -+ clientFailureFuture.complete(failure); -+ } -+ -+ @Override -+ public void onClose(Session session, GoAwayFrame frame) -+ { -+ clientCloseReasonFuture.complete(frame.tryConvertPayload()); -+ } -+ }; -+ -+ HTTP2Session session = (HTTP2Session)newClient(listener); -+ assertTrue(settingsLatch.await(5, TimeUnit.SECONDS)); -+ session.getGenerator().getHpackEncoder().setMaxHeaderListSize(1024 * 1024); -+ -+ String value = StringUtil.stringFrom("x", 8 * 1024); -+ HttpFields requestFields = new HttpFields(); -+ requestFields.put("custom", value); -+ MetaData.Request metaData = newRequest("GET", requestFields); -+ HeadersFrame request = new HeadersFrame(metaData, null, true); -+ session.newStream(request, new FuturePromise<>(), new Stream.Listener.Adapter()); -+ -+ // Test failure and close reason on client. -+ String closeReason = clientCloseReasonFuture.get(5, TimeUnit.SECONDS); -+ assertThat(closeReason, equalTo("invalid_hpack_block")); -+ assertNull(clientFailureFuture.getNow(null)); -+ -+ // Test failure and close reason on server. -+ closeReason = serverCloseReasonFuture.get(5, TimeUnit.SECONDS); -+ assertThat(closeReason, equalTo("invalid_hpack_block")); -+ Throwable failure = serverFailureFuture.get(5, TimeUnit.SECONDS); -+ assertThat(failure, instanceOf(IOException.class)); -+ assertThat(failure.getMessage(), containsString("invalid_hpack_block")); -+ } -+ -+ @Test -+ public void testServerSendsLargeHeader() throws Exception -+ { -+ CompletableFuture serverFailureFuture = new CompletableFuture<>(); -+ CompletableFuture serverCloseReasonFuture = new CompletableFuture<>(); -+ start(new ServerSessionListener.Adapter() -+ { -+ @Override -+ public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) -+ { -+ HTTP2Session session = (HTTP2Session)stream.getSession(); -+ session.getGenerator().getHpackEncoder().setMaxHeaderListSize(1024 * 1024); -+ -+ String value = StringUtil.stringFrom("x", 8 * 1024); -+ HttpFields fields = new HttpFields(); -+ fields.put("custom", value); -+ MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, fields); -+ stream.headers(new HeadersFrame(stream.getId(), response, null, true), Callback.NOOP); -+ return null; -+ } -+ -+ @Override -+ public void onFailure(Session session, Throwable failure) -+ { -+ serverFailureFuture.complete(failure); -+ } -+ -+ @Override -+ public void onClose(Session session, GoAwayFrame frame) -+ { -+ serverCloseReasonFuture.complete(frame.tryConvertPayload()); -+ } -+ }); -+ -+ CompletableFuture clientFailureFuture = new CompletableFuture<>(); -+ CompletableFuture clientCloseReasonFuture = new CompletableFuture<>(); -+ Session.Listener.Adapter listener = new Session.Listener.Adapter() -+ { -+ @Override -+ public void onFailure(Session session, Throwable failure) -+ { -+ clientFailureFuture.complete(failure); -+ } -+ -+ @Override -+ public void onClose(Session session, GoAwayFrame frame) -+ { -+ clientCloseReasonFuture.complete(frame.tryConvertPayload()); -+ } -+ }; -+ -+ Session session = newClient(listener); -+ MetaData.Request metaData = newRequest("GET", new HttpFields()); -+ HeadersFrame request = new HeadersFrame(metaData, null, true); -+ session.newStream(request, new FuturePromise<>(), new Stream.Listener.Adapter()); -+ -+ // Test failure and close reason on server. -+ String closeReason = serverCloseReasonFuture.get(5, TimeUnit.SECONDS); -+ assertThat(closeReason, equalTo("invalid_hpack_block")); -+ assertNull(serverFailureFuture.getNow(null)); -+ -+ // Test failure and close reason on client. -+ closeReason = clientCloseReasonFuture.get(5, TimeUnit.SECONDS); -+ assertThat(closeReason, equalTo("invalid_hpack_block")); -+ Throwable failure = clientFailureFuture.get(5, TimeUnit.SECONDS); -+ assertThat(failure, instanceOf(IOException.class)); -+ assertThat(failure.getMessage(), containsString("invalid_hpack_block")); -+ } -+ - private static void sleep(long time) - { - try -diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PrefaceTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PrefaceTest.java -index 60906dd..c877810 100644 ---- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PrefaceTest.java -+++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PrefaceTest.java -@@ -35,7 +35,6 @@ import java.util.concurrent.CountDownLatch; - import java.util.concurrent.TimeUnit; - import java.util.concurrent.atomic.AtomicBoolean; - import java.util.concurrent.atomic.AtomicReference; --import java.util.function.UnaryOperator; - - import org.eclipse.jetty.http.HttpFields; - import org.eclipse.jetty.http.HttpStatus; -@@ -169,15 +168,15 @@ public class PrefaceTest extends AbstractTest - socket.write(buffers.toArray(new ByteBuffer[buffers.size()])); - - Queue settings = new ArrayDeque<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onSettings(SettingsFrame frame) - { - settings.offer(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - ByteBuffer buffer = byteBufferPool.acquire(1024, true); - while (true) -@@ -302,7 +301,8 @@ public class PrefaceTest extends AbstractTest - - CountDownLatch clientSettingsLatch = new CountDownLatch(1); - AtomicBoolean responded = new AtomicBoolean(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onSettings(SettingsFrame frame) -@@ -319,8 +319,7 @@ public class PrefaceTest extends AbstractTest - if (frame.isEndStream()) - responded.set(true); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - // HTTP/2 parsing. - while (true) -diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Connection.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Connection.java -index 4b96925..a414299 100644 ---- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Connection.java -+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Connection.java -@@ -27,6 +27,7 @@ import java.util.concurrent.atomic.AtomicLong; - - import org.eclipse.jetty.http2.frames.DataFrame; - import org.eclipse.jetty.http2.parser.Parser; -+import org.eclipse.jetty.http2.parser.ServerParser; - import org.eclipse.jetty.io.AbstractConnection; - import org.eclipse.jetty.io.ByteBufferPool; - import org.eclipse.jetty.io.EndPoint; -@@ -52,23 +53,26 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher. - private final HTTP2Producer producer = new HTTP2Producer(); - private final AtomicLong bytesIn = new AtomicLong(); - private final ByteBufferPool byteBufferPool; -- private final Parser parser; - private final ISession session; - private final int bufferSize; - private final ExecutionStrategy strategy; - -+ @Deprecated - public HTTP2Connection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, Parser parser, ISession session, int bufferSize) -+ { -+ this(byteBufferPool, executor, endPoint, session, bufferSize); -+ } -+ -+ public HTTP2Connection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, ISession session, int bufferSize) - { - super(endPoint, executor); - this.byteBufferPool = byteBufferPool; -- this.parser = parser; - this.session = session; - this.bufferSize = bufferSize; - if (PEC_MODE) - executor = new TryExecutor.NoTryExecutor(executor); - this.strategy = new EatWhatYouKill(producer, executor); - LifeCycle.start(strategy); -- parser.init(ParserListener::new); - } - - @Override -@@ -104,7 +108,8 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher. - - protected Parser getParser() - { -- return parser; -+ // TODO: can we downcast. -+ return ((HTTP2Session)session).getParser(); - } - - protected void setInputBuffer(ByteBuffer buffer) -@@ -112,6 +117,11 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher. - producer.setInputBuffer(buffer); - } - -+ public Parser.Listener wrapParserListener(Parser.Listener listener) -+ { -+ return new ParserListener(listener); -+ } -+ - @Override - public void onOpen() - { -@@ -258,7 +268,7 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher. - { - while (networkBuffer.hasRemaining()) - { -- parser.parse(networkBuffer.getBuffer()); -+ getParser().parse(networkBuffer.getBuffer()); - if (failed) - return null; - } -@@ -378,7 +388,7 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher. - { - private ParserListener(Parser.Listener listener) - { -- super(listener); -+ super(listener == null ? new ServerParser.Listener.Adapter() : listener); - } - - @Override -diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java -index 3fba40e..a1c5ace 100644 ---- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java -+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java -@@ -55,6 +55,7 @@ import org.eclipse.jetty.http2.frames.SettingsFrame; - import org.eclipse.jetty.http2.frames.StreamFrame; - import org.eclipse.jetty.http2.frames.WindowUpdateFrame; - import org.eclipse.jetty.http2.generator.Generator; -+import org.eclipse.jetty.http2.hpack.HpackEncoder; - import org.eclipse.jetty.http2.hpack.HpackException; - import org.eclipse.jetty.http2.parser.Parser; - import org.eclipse.jetty.io.ByteBufferPool; -@@ -94,6 +95,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio - private final AtomicLong bytesWritten = new AtomicLong(); - private final Scheduler scheduler; - private final EndPoint endPoint; -+ private final Parser parser; - private final Generator generator; - private final Session.Listener listener; - private final FlowControlStrategy flowControl; -@@ -103,12 +105,21 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio - private long streamIdleTimeout; - private int initialSessionRecvWindow; - private int writeThreshold; -+ private int maxEncoderTableCapacity; - private boolean pushEnabled; - -+ @Deprecated - public HTTP2Session(Scheduler scheduler, EndPoint endPoint, Generator generator, Session.Listener listener, FlowControlStrategy flowControl, int initialStreamId) -+ { -+ this(scheduler, endPoint, null, generator, listener, flowControl, initialStreamId); -+ throw new UnsupportedOperationException(); -+ } -+ -+ public HTTP2Session(Scheduler scheduler, EndPoint endPoint, Parser parser, Generator generator, Session.Listener listener, FlowControlStrategy flowControl, int initialStreamId) - { - this.scheduler = scheduler; - this.endPoint = endPoint; -+ this.parser = parser; - this.generator = generator; - this.listener = listener; - this.flowControl = flowControl; -@@ -205,11 +216,27 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio - this.writeThreshold = writeThreshold; - } - -+ @ManagedAttribute("The HPACK encoder dynamic table maximum capacity") -+ public int getMaxEncoderTableCapacity() -+ { -+ return maxEncoderTableCapacity; -+ } -+ -+ public void setMaxEncoderTableCapacity(int maxEncoderTableCapacity) -+ { -+ this.maxEncoderTableCapacity = maxEncoderTableCapacity; -+ } -+ - public EndPoint getEndPoint() - { - return endPoint; - } - -+ public Parser getParser() -+ { -+ return parser; -+ } -+ - public Generator getGenerator() - { - return generator; -@@ -346,8 +373,20 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio - if (frame.isReply()) - return; - -- // Iterate over all settings -- for (Map.Entry entry : frame.getSettings().entrySet()) -+ Map settings = frame.getSettings(); -+ configure(settings, false); -+ notifySettings(this, frame); -+ -+ if (reply) -+ { -+ SettingsFrame replyFrame = new SettingsFrame(Collections.emptyMap(), true); -+ settings(replyFrame, Callback.NOOP); -+ } -+ } -+ -+ private void configure(Map settings, boolean local) -+ { -+ for (Map.Entry entry : settings.entrySet()) - { - int key = entry.getKey(); - int value = entry.getValue(); -@@ -356,8 +395,17 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio - case SettingsFrame.HEADER_TABLE_SIZE: - { - if (LOG.isDebugEnabled()) -- LOG.debug("Updating HPACK header table size to {} for {}", value, this); -- generator.setHeaderTableSize(value); -+ LOG.debug("Updating HPACK {} max table capacity to {} for {}", local ? "decoder" : "encoder", value, this); -+ if (local) -+ { -+ parser.getHpackDecoder().setMaxTableCapacity(value); -+ } -+ else -+ { -+ HpackEncoder hpackEncoder = generator.getHpackEncoder(); -+ hpackEncoder.setMaxTableCapacity(value); -+ hpackEncoder.setTableCapacity(Math.min(value, getMaxEncoderTableCapacity())); -+ } - break; - } - case SettingsFrame.ENABLE_PUSH: -@@ -371,29 +419,38 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio - case SettingsFrame.MAX_CONCURRENT_STREAMS: - { - if (LOG.isDebugEnabled()) -- LOG.debug("Updating max local concurrent streams to {} for {}", value, this); -- maxLocalStreams = value; -+ LOG.debug("Updating max {} concurrent streams to {} for {}", local ? "remote" : "local", value, this); -+ if (local) -+ maxRemoteStreams = value; -+ else -+ maxLocalStreams = value; - break; - } - case SettingsFrame.INITIAL_WINDOW_SIZE: - { - if (LOG.isDebugEnabled()) - LOG.debug("Updating initial stream window size to {} for {}", value, this); -- flowControl.updateInitialStreamWindow(this, value, false); -+ flowControl.updateInitialStreamWindow(this, value, local); - break; - } - case SettingsFrame.MAX_FRAME_SIZE: - { - if (LOG.isDebugEnabled()) -- LOG.debug("Updating max frame size to {} for {}", value, this); -- generator.setMaxFrameSize(value); -+ LOG.debug("Updating {} max frame size to {} for {}", local ? "parser" : "generator", value, this); -+ if (local) -+ parser.setMaxFrameSize(value); -+ else -+ generator.setMaxFrameSize(value); - break; - } - case SettingsFrame.MAX_HEADER_LIST_SIZE: - { - if (LOG.isDebugEnabled()) -- LOG.debug("Updating max header list size to {} for {}", value, this); -- generator.setMaxHeaderListSize(value); -+ LOG.debug("Updating {} max header list size to {} for {}", local ? "decoder" : "encoder", value, this); -+ if (local) -+ parser.getHpackDecoder().setMaxHeaderListSize(value); -+ else -+ generator.getHpackEncoder().setMaxHeaderListSize(value); - break; - } - default: -@@ -404,13 +461,6 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio - } - } - } -- notifySettings(this, frame); -- -- if (reply) -- { -- SettingsFrame replyFrame = new SettingsFrame(Collections.emptyMap(), true); -- settings(replyFrame, Callback.NOOP); -- } - } - - @Override -@@ -486,6 +536,21 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio - } - } - -+ @Override -+ public void onWindowUpdate(IStream stream, WindowUpdateFrame frame) -+ { -+ // WindowUpdateFrames arrive concurrently with writes. -+ // Increasing (or reducing) the window size concurrently -+ // with writes requires coordination with the flusher, that -+ // decides how many frames to write depending on the available -+ // window sizes. If the window sizes vary concurrently, the -+ // flusher may take non-optimal or wrong decisions. -+ // Here, we "queue" window updates to the flusher, so it will -+ // be the only component responsible for window updates, for -+ // both increments and reductions. -+ flusher.window(stream, frame); -+ } -+ - @Override - public void onStreamFailure(int streamId, int error, String reason) - { -@@ -888,21 +953,6 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio - return recvWindow.getAndAdd(delta); - } - -- @Override -- public void onWindowUpdate(IStream stream, WindowUpdateFrame frame) -- { -- // WindowUpdateFrames arrive concurrently with writes. -- // Increasing (or reducing) the window size concurrently -- // with writes requires coordination with the flusher, that -- // decides how many frames to write depending on the available -- // window sizes. If the window sizes vary concurrently, the -- // flusher may take non-optimal or wrong decisions. -- // Here, we "queue" window updates to the flusher, so it will -- // be the only component responsible for window updates, for -- // both increments and reductions. -- flusher.window(stream, frame); -- } -- - @Override - @ManagedAttribute(value = "Whether HTTP/2 push is enabled", readonly = true) - public boolean isPushEnabled() -@@ -1005,7 +1055,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio - return lastRemoteStreamId.get(); - } - -- private void updateLastRemoteStreamId(int streamId) -+ protected void updateLastRemoteStreamId(int streamId) - { - Atomics.updateMax(lastRemoteStreamId, streamId); - } -@@ -1208,9 +1258,8 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio - case SETTINGS: - { - SettingsFrame settingsFrame = (SettingsFrame)frame; -- Integer initialWindow = settingsFrame.getSettings().get(SettingsFrame.INITIAL_WINDOW_SIZE); -- if (initialWindow != null) -- flowControl.updateInitialStreamWindow(HTTP2Session.this, initialWindow, true); -+ if (!settingsFrame.isReply()) -+ configure(settingsFrame.getSettings(), true); - break; - } - default: -@@ -1407,6 +1456,8 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio - @Override - public void failed(Throwable x) - { -+ if (LOG.isDebugEnabled()) -+ LOG.debug("OnReset failed", x); - complete(); - } - -@@ -1424,14 +1475,15 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio - - /** - *

The HTTP/2 specification requires that stream ids are monotonically increasing, -- * see https://tools.ietf.org/html/rfc7540#section-5.1.1.

-+ * see RFC 7540, 5.1.1.

- *

This implementation uses a queue to atomically reserve a stream id and claim - * a slot in the queue; the slot is then assigned the entries to write.

- *

Concurrent threads push slots in the queue but only one thread flushes - * the slots, up to the slot that has a non-null entries to write, therefore - * guaranteeing that frames are sent strictly in their stream id order.

- *

This class also coordinates the creation of streams with the close of -- * the session, see https://tools.ietf.org/html/rfc7540#section-6.8.

-+ * the session, see -+ * RFC 7540, 6.8.

- */ - private class StreamsState - { -@@ -2168,7 +2220,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio - if (flushing == null) - flushing = thread; - else if (flushing != thread) -- return; // another thread is flushing -+ return; // Another thread is flushing. - - Slot slot = slots.peek(); - entries = slot == null ? null : slot.entries; -@@ -2176,7 +2228,8 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio - if (entries == null) - { - flushing = null; -- break; // No more slots or null entries, so we may iterate on the flusher -+ // No more slots or null entries, so we may iterate on the flusher. -+ break; - } - - slots.poll(); -diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/Generator.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/Generator.java -index 97f9aea..b4c3c27 100644 ---- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/Generator.java -+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/Generator.java -@@ -35,15 +35,21 @@ public class Generator - - public Generator(ByteBufferPool byteBufferPool) - { -- this(byteBufferPool, 4096, 0); -+ this(byteBufferPool, 0); - } - -+ @Deprecated - public Generator(ByteBufferPool byteBufferPool, int maxDynamicTableSize, int maxHeaderBlockFragment) -+ { -+ this(byteBufferPool, maxHeaderBlockFragment); -+ } -+ -+ public Generator(ByteBufferPool byteBufferPool, int maxHeaderBlockFragment) - { - this.byteBufferPool = byteBufferPool; - - headerGenerator = new HeaderGenerator(); -- hpackEncoder = new HpackEncoder(maxDynamicTableSize); -+ hpackEncoder = new HpackEncoder(); - - this.generators = new FrameGenerator[FrameType.values().length]; - this.generators[FrameType.HEADERS.getType()] = new HeadersGenerator(headerGenerator, hpackEncoder, maxHeaderBlockFragment); -@@ -66,14 +72,21 @@ public class Generator - return byteBufferPool; - } - -+ public HpackEncoder getHpackEncoder() -+ { -+ return hpackEncoder; -+ } -+ -+ @Deprecated - public void setValidateHpackEncoding(boolean validateEncoding) - { -- hpackEncoder.setValidateEncoding(validateEncoding); -+ getHpackEncoder().setValidateEncoding(validateEncoding); - } - -- public void setHeaderTableSize(int headerTableSize) -+ @Deprecated -+ public void setHeaderTableSize(int maxTableSize) - { -- hpackEncoder.setRemoteMaxDynamicTableSize(headerTableSize); -+ getHpackEncoder().setTableCapacity(maxTableSize); - } - - public void setMaxFrameSize(int maxFrameSize) -@@ -91,8 +104,9 @@ public class Generator - return dataGenerator.generate(lease, frame, maxLength); - } - -+ @Deprecated - public void setMaxHeaderListSize(int value) - { -- hpackEncoder.setMaxHeaderListSize(value); -+ getHpackEncoder().setMaxHeaderListSize(value); - } - } -diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockParser.java -index 48becb1..848864d 100644 ---- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockParser.java -+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockParser.java -@@ -50,6 +50,11 @@ public class HeaderBlockParser - this.notifier = notifier; - } - -+ public int getMaxHeaderListSize() -+ { -+ return hpackDecoder.getMaxHeaderListSize(); -+ } -+ - /** - * Parses @{code blockLength} HPACK bytes from the given {@code buffer}. - * -diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeadersBodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeadersBodyParser.java -index e222420..909d49f 100644 ---- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeadersBodyParser.java -+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeadersBodyParser.java -@@ -194,6 +194,10 @@ public class HeadersBodyParser extends BodyParser - { - if (hasFlag(Flags.END_HEADERS)) - { -+ int maxLength = headerBlockParser.getMaxHeaderListSize(); -+ if (maxLength > 0 && length > maxLength) -+ return connectionFailure(buffer, ErrorCode.REFUSED_STREAM_ERROR.code, "invalid_headers_frame"); -+ - MetaData metaData = headerBlockParser.parse(buffer, length); - if (metaData == HeaderBlockParser.SESSION_FAILURE) - return false; -diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java -index 5e2dfd0..1d727f7 100644 ---- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java -+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java -@@ -49,33 +49,47 @@ public class Parser - private static final Logger LOG = Log.getLogger(Parser.class); - - private final ByteBufferPool byteBufferPool; -- private final Listener listener; - private final HeaderParser headerParser; - private final HpackDecoder hpackDecoder; - private final BodyParser[] bodyParsers; -+ private Listener listener; - private UnknownBodyParser unknownBodyParser; -- private int maxFrameLength = Frame.DEFAULT_MAX_LENGTH; -+ private int maxFrameSize = Frame.DEFAULT_MAX_LENGTH; - private int maxSettingsKeys = SettingsFrame.DEFAULT_MAX_KEYS; - private boolean continuation; - private State state = State.HEADER; - -+ @Deprecated - public Parser(ByteBufferPool byteBufferPool, Listener listener, int maxDynamicTableSize, int maxHeaderSize) - { -- this(byteBufferPool, listener, maxDynamicTableSize, maxHeaderSize, RateControl.NO_RATE_CONTROL); -+ this(byteBufferPool, maxHeaderSize, RateControl.NO_RATE_CONTROL); - } - -- public Parser(ByteBufferPool byteBufferPool, Listener listener, int maxDynamicTableSize, int maxHeaderSize, RateControl rateControl) -+ public Parser(ByteBufferPool byteBufferPool, int maxHeaderSize) -+ { -+ this(byteBufferPool, maxHeaderSize, RateControl.NO_RATE_CONTROL); -+ } -+ -+ public Parser(ByteBufferPool byteBufferPool, int maxHeaderSize, RateControl rateControl) - { - this.byteBufferPool = byteBufferPool; -- this.listener = listener; - this.headerParser = new HeaderParser(rateControl == null ? RateControl.NO_RATE_CONTROL : rateControl); -- this.hpackDecoder = new HpackDecoder(maxDynamicTableSize, maxHeaderSize); -+ this.hpackDecoder = new HpackDecoder(maxHeaderSize); - this.bodyParsers = new BodyParser[FrameType.values().length]; - } - -+ @Deprecated - public void init(UnaryOperator wrapper) - { -- Listener listener = wrapper.apply(this.listener); -+ Listener listener = wrapper.apply(new Listener.Adapter()); -+ init(listener); -+ } -+ -+ public void init(Listener listener) -+ { -+ if (this.listener != null) -+ throw new IllegalStateException("Invalid parser initialization"); -+ this.listener = listener; - unknownBodyParser = new UnknownBodyParser(headerParser, listener); - HeaderBlockParser headerBlockParser = new HeaderBlockParser(headerParser, byteBufferPool, hpackDecoder, unknownBodyParser); - HeaderBlockFragments headerBlockFragments = new HeaderBlockFragments(hpackDecoder.getMaxHeaderListSize()); -@@ -91,6 +105,16 @@ public class Parser - bodyParsers[FrameType.CONTINUATION.getType()] = new ContinuationBodyParser(headerParser, listener, headerBlockParser, headerBlockFragments); - } - -+ protected Listener getListener() -+ { -+ return listener; -+ } -+ -+ public HpackDecoder getHpackDecoder() -+ { -+ return hpackDecoder; -+ } -+ - private void reset() - { - headerParser.reset(); -@@ -151,7 +175,7 @@ public class Parser - if (LOG.isDebugEnabled()) - LOG.debug("Parsed {} frame header from {}@{}", headerParser, buffer, Integer.toHexString(buffer.hashCode())); - -- if (headerParser.getLength() > getMaxFrameLength()) -+ if (headerParser.getLength() > getMaxFrameSize()) - return connectionFailure(buffer, ErrorCode.FRAME_SIZE_ERROR, "invalid_frame_length"); - - FrameType frameType = FrameType.from(getFrameType()); -@@ -219,14 +243,26 @@ public class Parser - return headerParser.hasFlag(bit); - } - -+ @Deprecated - public int getMaxFrameLength() - { -- return maxFrameLength; -+ return getMaxFrameSize(); -+ } -+ -+ @Deprecated -+ public void setMaxFrameLength(int maxFrameSize) -+ { -+ setMaxFrameSize(maxFrameSize); -+ } -+ -+ public int getMaxFrameSize() -+ { -+ return maxFrameSize; - } - -- public void setMaxFrameLength(int maxFrameLength) -+ public void setMaxFrameSize(int maxFrameSize) - { -- this.maxFrameLength = maxFrameLength; -+ this.maxFrameSize = maxFrameSize; - } - - public int getMaxSettingsKeys() -diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PushPromiseBodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PushPromiseBodyParser.java -index f02107d..7049e03 100644 ---- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PushPromiseBodyParser.java -+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PushPromiseBodyParser.java -@@ -121,6 +121,10 @@ public class PushPromiseBodyParser extends BodyParser - } - case HEADERS: - { -+ int maxLength = headerBlockParser.getMaxHeaderListSize(); -+ if (maxLength > 0 && length > maxLength) -+ return connectionFailure(buffer, ErrorCode.REFUSED_STREAM_ERROR.code, "invalid_headers_frame"); -+ - MetaData metaData = headerBlockParser.parse(buffer, length); - if (metaData == HeaderBlockParser.SESSION_FAILURE) - return false; -diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ServerParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ServerParser.java -index c38d69b..e5743a7 100644 ---- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ServerParser.java -+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ServerParser.java -@@ -32,15 +32,30 @@ public class ServerParser extends Parser - { - private static final Logger LOG = Log.getLogger(ServerParser.class); - -- private final Listener listener; -- private final PrefaceParser prefaceParser; -+ private PrefaceParser prefaceParser; - private State state = State.PREFACE; - private boolean notifyPreface = true; - -+ @Deprecated - public ServerParser(ByteBufferPool byteBufferPool, Listener listener, int maxDynamicTableSize, int maxHeaderSize, RateControl rateControl) - { -- super(byteBufferPool, listener, maxDynamicTableSize, maxHeaderSize, rateControl); -- this.listener = listener; -+ this(byteBufferPool, maxHeaderSize, rateControl); -+ } -+ -+ public ServerParser(ByteBufferPool byteBufferPool, int maxHeaderSize) -+ { -+ super(byteBufferPool, maxHeaderSize); -+ } -+ -+ public ServerParser(ByteBufferPool byteBufferPool, int maxHeaderSize, RateControl rateControl) -+ { -+ super(byteBufferPool, maxHeaderSize, rateControl); -+ } -+ -+ @Override -+ public void init(Parser.Listener listener) -+ { -+ super.init(listener); - this.prefaceParser = new PrefaceParser(listener); - } - -@@ -137,9 +152,23 @@ public class ServerParser extends Parser - - private void notifyPreface() - { -+ Parser.Listener listener = getListener(); - try - { -- listener.onPreface(); -+ while (true) -+ { -+ if (listener instanceof ServerParser.Listener) -+ { -+ ((ServerParser.Listener)listener).onPreface(); -+ break; -+ } -+ -+ // Unwrap to try and find a ServerParser.Listener. -+ if (listener instanceof Parser.Listener.Wrapper) -+ listener = ((Parser.Listener.Wrapper)listener).getParserListener(); -+ else -+ break; -+ } - } - catch (Throwable x) - { -diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java -index 54a7cde..10fac90 100644 ---- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java -+++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java -@@ -21,7 +21,6 @@ package org.eclipse.jetty.http2.frames; - import java.nio.ByteBuffer; - import java.util.ArrayList; - import java.util.List; --import java.util.function.UnaryOperator; - import java.util.concurrent.atomic.AtomicBoolean; - import java.util.stream.IntStream; - -@@ -55,7 +54,8 @@ public class ContinuationParseTest - HeadersGenerator generator = new HeadersGenerator(new HeaderGenerator(), new HpackEncoder()); - - final List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onHeaders(HeadersFrame frame) -@@ -68,8 +68,7 @@ public class ContinuationParseTest - { - frames.add(new HeadersFrame(null, null, false)); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - // Iterate a few times to be sure the parser is properly reset. - for (int i = 0; i < 2; ++i) -diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/DataGenerateParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/DataGenerateParseTest.java -index 87f8ffa..78a6a5e 100644 ---- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/DataGenerateParseTest.java -+++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/DataGenerateParseTest.java -@@ -22,7 +22,6 @@ import java.nio.ByteBuffer; - import java.util.ArrayList; - import java.util.List; - import java.util.Random; --import java.util.function.UnaryOperator; - - import org.eclipse.jetty.http2.generator.DataGenerator; - import org.eclipse.jetty.http2.generator.HeaderGenerator; -@@ -93,15 +92,15 @@ public class DataGenerateParseTest - DataGenerator generator = new DataGenerator(new HeaderGenerator()); - - final List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onData(DataFrame frame) - { - frames.add(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - // Iterate a few times to be sure generator and parser are properly reset. - for (int i = 0; i < 2; ++i) -@@ -133,15 +132,15 @@ public class DataGenerateParseTest - DataGenerator generator = new DataGenerator(new HeaderGenerator()); - - final List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onData(DataFrame frame) - { - frames.add(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - // Iterate a few times to be sure generator and parser are properly reset. - for (int i = 0; i < 2; ++i) -diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java -index 2a1b187..613259b 100644 ---- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java -+++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java -@@ -21,7 +21,6 @@ package org.eclipse.jetty.http2.frames; - import java.nio.ByteBuffer; - import java.time.Duration; - import java.util.concurrent.atomic.AtomicBoolean; --import java.util.function.UnaryOperator; - - import org.eclipse.jetty.http.HttpVersion; - import org.eclipse.jetty.http.MetaData; -@@ -153,15 +152,15 @@ public class FrameFloodTest - private void testFrameFlood(byte[] preamble, byte[] bytes) - { - AtomicBoolean failed = new AtomicBoolean(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096, new WindowRateControl(8, Duration.ofSeconds(1))); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onConnectionFailure(int error, String reason) - { - failed.set(true); - } -- }, 4096, 8192, new WindowRateControl(8, Duration.ofSeconds(1))); -- parser.init(UnaryOperator.identity()); -+ }); - - if (preamble != null) - { -diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/GoAwayGenerateParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/GoAwayGenerateParseTest.java -index 115a4d1..da88cd9 100644 ---- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/GoAwayGenerateParseTest.java -+++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/GoAwayGenerateParseTest.java -@@ -22,7 +22,6 @@ import java.nio.ByteBuffer; - import java.util.ArrayList; - import java.util.List; - import java.util.Random; --import java.util.function.UnaryOperator; - - import org.eclipse.jetty.http2.generator.GoAwayGenerator; - import org.eclipse.jetty.http2.generator.HeaderGenerator; -@@ -45,15 +44,15 @@ public class GoAwayGenerateParseTest - GoAwayGenerator generator = new GoAwayGenerator(new HeaderGenerator()); - - final List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onGoAway(GoAwayFrame frame) - { - frames.add(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - int lastStreamId = 13; - int error = 17; -@@ -87,15 +86,15 @@ public class GoAwayGenerateParseTest - GoAwayGenerator generator = new GoAwayGenerator(new HeaderGenerator()); - - final List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onGoAway(GoAwayFrame frame) - { - frames.add(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - int lastStreamId = 13; - int error = 17; -diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersGenerateParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersGenerateParseTest.java -index 83f3c45..65a12d6 100644 ---- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersGenerateParseTest.java -+++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersGenerateParseTest.java -@@ -21,7 +21,6 @@ package org.eclipse.jetty.http2.frames; - import java.nio.ByteBuffer; - import java.util.ArrayList; - import java.util.List; --import java.util.function.UnaryOperator; - - import org.eclipse.jetty.http.HostPortHttpField; - import org.eclipse.jetty.http.HttpField; -@@ -57,15 +56,15 @@ public class HeadersGenerateParseTest - MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP, new HostPortHttpField("localhost:8080"), "/path", HttpVersion.HTTP_2, fields); - - final List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onHeaders(HeadersFrame frame) - { - frames.add(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - // Iterate a few times to be sure generator and parser are properly reset. - for (int i = 0; i < 2; ++i) -@@ -110,15 +109,15 @@ public class HeadersGenerateParseTest - HeadersGenerator generator = new HeadersGenerator(new HeaderGenerator(), new HpackEncoder()); - - final List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onHeaders(HeadersFrame frame) - { - frames.add(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - // Iterate a few times to be sure generator and parser are properly reset. - for (int i = 0; i < 2; ++i) -diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/MaxFrameSizeParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/MaxFrameSizeParseTest.java -index 61da49d..3d2ae30 100644 ---- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/MaxFrameSizeParseTest.java -+++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/MaxFrameSizeParseTest.java -@@ -20,7 +20,6 @@ package org.eclipse.jetty.http2.frames; - - import java.nio.ByteBuffer; - import java.util.concurrent.atomic.AtomicInteger; --import java.util.function.UnaryOperator; - - import org.eclipse.jetty.http2.ErrorCode; - import org.eclipse.jetty.http2.parser.Parser; -@@ -40,16 +39,16 @@ public class MaxFrameSizeParseTest - int maxFrameLength = Frame.DEFAULT_MAX_LENGTH + 16; - - AtomicInteger failure = new AtomicInteger(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.setMaxFrameSize(maxFrameLength); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onConnectionFailure(int error, String reason) - { - failure.set(error); - } -- }, 4096, 8192); -- parser.setMaxFrameLength(maxFrameLength); -- parser.init(UnaryOperator.identity()); -+ }); - - // Iterate a few times to be sure the parser is properly reset. - for (int i = 0; i < 2; ++i) -diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PingGenerateParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PingGenerateParseTest.java -index b11d391..4db9267 100644 ---- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PingGenerateParseTest.java -+++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PingGenerateParseTest.java -@@ -22,7 +22,6 @@ import java.nio.ByteBuffer; - import java.util.ArrayList; - import java.util.List; - import java.util.Random; --import java.util.function.UnaryOperator; - - import org.eclipse.jetty.http2.generator.HeaderGenerator; - import org.eclipse.jetty.http2.generator.PingGenerator; -@@ -45,15 +44,15 @@ public class PingGenerateParseTest - PingGenerator generator = new PingGenerator(new HeaderGenerator()); - - final List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onPing(PingFrame frame) - { - frames.add(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - byte[] payload = new byte[8]; - new Random().nextBytes(payload); -@@ -86,15 +85,15 @@ public class PingGenerateParseTest - PingGenerator generator = new PingGenerator(new HeaderGenerator()); - - final List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onPing(PingFrame frame) - { - frames.add(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - byte[] payload = new byte[8]; - new Random().nextBytes(payload); -@@ -127,15 +126,15 @@ public class PingGenerateParseTest - PingGenerator generator = new PingGenerator(new HeaderGenerator()); - - final List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onPing(PingFrame frame) - { - frames.add(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool); - PingFrame ping = new PingFrame(System.nanoTime(), true); -diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PriorityGenerateParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PriorityGenerateParseTest.java -index 2aee4eb..5bc2de8 100644 ---- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PriorityGenerateParseTest.java -+++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PriorityGenerateParseTest.java -@@ -21,7 +21,6 @@ package org.eclipse.jetty.http2.frames; - import java.nio.ByteBuffer; - import java.util.ArrayList; - import java.util.List; --import java.util.function.UnaryOperator; - - import org.eclipse.jetty.http2.generator.HeaderGenerator; - import org.eclipse.jetty.http2.generator.PriorityGenerator; -@@ -42,15 +41,15 @@ public class PriorityGenerateParseTest - PriorityGenerator generator = new PriorityGenerator(new HeaderGenerator()); - - final List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onPriority(PriorityFrame frame) - { - frames.add(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - int streamId = 13; - int parentStreamId = 17; -@@ -87,15 +86,15 @@ public class PriorityGenerateParseTest - PriorityGenerator generator = new PriorityGenerator(new HeaderGenerator()); - - final List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onPriority(PriorityFrame frame) - { - frames.add(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - int streamId = 13; - int parentStreamId = 17; -diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PushPromiseGenerateParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PushPromiseGenerateParseTest.java -index cb2323e..27e772e 100644 ---- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PushPromiseGenerateParseTest.java -+++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PushPromiseGenerateParseTest.java -@@ -21,7 +21,6 @@ package org.eclipse.jetty.http2.frames; - import java.nio.ByteBuffer; - import java.util.ArrayList; - import java.util.List; --import java.util.function.UnaryOperator; - - import org.eclipse.jetty.http.HostPortHttpField; - import org.eclipse.jetty.http.HttpField; -@@ -50,15 +49,15 @@ public class PushPromiseGenerateParseTest - PushPromiseGenerator generator = new PushPromiseGenerator(new HeaderGenerator(), new HpackEncoder()); - - final List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onPushPromise(PushPromiseFrame frame) - { - frames.add(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - int streamId = 13; - int promisedStreamId = 17; -@@ -103,15 +102,15 @@ public class PushPromiseGenerateParseTest - PushPromiseGenerator generator = new PushPromiseGenerator(new HeaderGenerator(), new HpackEncoder()); - - final List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onPushPromise(PushPromiseFrame frame) - { - frames.add(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - int streamId = 13; - int promisedStreamId = 17; -diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ResetGenerateParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ResetGenerateParseTest.java -index fca126e..6318a18 100644 ---- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ResetGenerateParseTest.java -+++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ResetGenerateParseTest.java -@@ -21,7 +21,6 @@ package org.eclipse.jetty.http2.frames; - import java.nio.ByteBuffer; - import java.util.ArrayList; - import java.util.List; --import java.util.function.UnaryOperator; - - import org.eclipse.jetty.http2.generator.HeaderGenerator; - import org.eclipse.jetty.http2.generator.ResetGenerator; -@@ -42,15 +41,15 @@ public class ResetGenerateParseTest - ResetGenerator generator = new ResetGenerator(new HeaderGenerator()); - - final List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onReset(ResetFrame frame) - { - frames.add(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - int streamId = 13; - int error = 17; -@@ -83,15 +82,15 @@ public class ResetGenerateParseTest - ResetGenerator generator = new ResetGenerator(new HeaderGenerator()); - - final List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onReset(ResetFrame frame) - { - frames.add(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - int streamId = 13; - int error = 17; -diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java -index 4cc6a45..30455b1 100644 ---- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java -+++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java -@@ -25,7 +25,6 @@ import java.util.HashMap; - import java.util.List; - import java.util.Map; - import java.util.concurrent.atomic.AtomicInteger; --import java.util.function.UnaryOperator; - - import org.eclipse.jetty.http2.ErrorCode; - import org.eclipse.jetty.http2.generator.HeaderGenerator; -@@ -77,15 +76,15 @@ public class SettingsGenerateParseTest - SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator()); - - List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onSettings(SettingsFrame frame) - { - frames.add(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - // Iterate a few times to be sure generator and parser are properly reset. - for (int i = 0; i < 2; ++i) -@@ -112,15 +111,15 @@ public class SettingsGenerateParseTest - SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator()); - - AtomicInteger errorRef = new AtomicInteger(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onConnectionFailure(int error, String reason) - { - errorRef.set(error); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - Map settings1 = new HashMap<>(); - settings1.put(13, 17); -@@ -147,15 +146,15 @@ public class SettingsGenerateParseTest - SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator()); - - List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onSettings(SettingsFrame frame) - { - frames.add(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - Map settings1 = new HashMap<>(); - int key = 13; -@@ -192,17 +191,17 @@ public class SettingsGenerateParseTest - SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator()); - - AtomicInteger errorRef = new AtomicInteger(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ int maxSettingsKeys = 32; -+ parser.setMaxSettingsKeys(maxSettingsKeys); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onConnectionFailure(int error, String reason) - { - errorRef.set(error); - } -- }, 4096, 8192); -- int maxSettingsKeys = 32; -- parser.setMaxSettingsKeys(maxSettingsKeys); -- parser.init(UnaryOperator.identity()); -+ }); - - Map settings = new HashMap<>(); - for (int i = 0; i < maxSettingsKeys + 1; ++i) -@@ -232,10 +231,10 @@ public class SettingsGenerateParseTest - int maxSettingsKeys = pairs / 2; - - AtomicInteger errorRef = new AtomicInteger(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter(), 4096, 8192); -+ Parser parser = new Parser(byteBufferPool, 4096); - parser.setMaxSettingsKeys(maxSettingsKeys); -- parser.setMaxFrameLength(Frame.DEFAULT_MAX_LENGTH); -- parser.init(listener -> new Parser.Listener.Wrapper(listener) -+ parser.setMaxFrameSize(Frame.DEFAULT_MAX_LENGTH); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onConnectionFailure(int error, String reason) -@@ -273,17 +272,17 @@ public class SettingsGenerateParseTest - SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator()); - - AtomicInteger errorRef = new AtomicInteger(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ int maxSettingsKeys = 32; -+ parser.setMaxSettingsKeys(maxSettingsKeys); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onConnectionFailure(int error, String reason) - { - errorRef.set(error); - } -- }, 4096, 8192); -- int maxSettingsKeys = 32; -- parser.setMaxSettingsKeys(maxSettingsKeys); -- parser.init(UnaryOperator.identity()); -+ }); - - Map settings = new HashMap<>(); - settings.put(13, 17); -diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/UnknownParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/UnknownParseTest.java -index a19abf2..0c1079c 100644 ---- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/UnknownParseTest.java -+++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/UnknownParseTest.java -@@ -22,7 +22,6 @@ import java.nio.ByteBuffer; - import java.util.concurrent.atomic.AtomicBoolean; - import java.util.concurrent.atomic.AtomicInteger; - import java.util.function.Function; --import java.util.function.UnaryOperator; - - import org.eclipse.jetty.http2.ErrorCode; - import org.eclipse.jetty.http2.parser.Parser; -@@ -53,8 +52,8 @@ public class UnknownParseTest - public void testInvalidFrameSize() - { - AtomicInteger failure = new AtomicInteger(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter(), 4096, 8192); -- parser.init(listener -> new Parser.Listener.Wrapper(listener) -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onConnectionFailure(int error, String reason) -@@ -62,7 +61,7 @@ public class UnknownParseTest - failure.set(error); - } - }); -- parser.setMaxFrameLength(Frame.DEFAULT_MAX_LENGTH); -+ parser.setMaxFrameSize(Frame.DEFAULT_MAX_LENGTH); - - // 0x4001 == 16385 which is > Frame.DEFAULT_MAX_LENGTH. - byte[] bytes = new byte[]{0, 0x40, 0x01, 64, 0, 0, 0, 0, 0}; -@@ -78,15 +77,15 @@ public class UnknownParseTest - private void testParse(Function fn) - { - AtomicBoolean failure = new AtomicBoolean(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onConnectionFailure(int error, String reason) - { - failure.set(true); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - // Iterate a few times to be sure the parser is properly reset. - for (int i = 0; i < 2; ++i) -diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/WindowUpdateGenerateParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/WindowUpdateGenerateParseTest.java -index ab3a39d..905603f 100644 ---- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/WindowUpdateGenerateParseTest.java -+++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/WindowUpdateGenerateParseTest.java -@@ -21,7 +21,6 @@ package org.eclipse.jetty.http2.frames; - import java.nio.ByteBuffer; - import java.util.ArrayList; - import java.util.List; --import java.util.function.UnaryOperator; - - import org.eclipse.jetty.http2.generator.HeaderGenerator; - import org.eclipse.jetty.http2.generator.WindowUpdateGenerator; -@@ -42,15 +41,15 @@ public class WindowUpdateGenerateParseTest - WindowUpdateGenerator generator = new WindowUpdateGenerator(new HeaderGenerator()); - - final List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onWindowUpdate(WindowUpdateFrame frame) - { - frames.add(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - int streamId = 13; - int windowUpdate = 17; -@@ -83,15 +82,15 @@ public class WindowUpdateGenerateParseTest - WindowUpdateGenerator generator = new WindowUpdateGenerator(new HeaderGenerator()); - - final List frames = new ArrayList<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onWindowUpdate(WindowUpdateFrame frame) - { - frames.add(frame); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - int streamId = 13; - int windowUpdate = 17; -diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java -index ea6b584..77734a1 100644 ---- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java -+++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java -@@ -29,6 +29,8 @@ import org.eclipse.jetty.http.HttpField; - import org.eclipse.jetty.http.HttpHeader; - import org.eclipse.jetty.http.HttpMethod; - import org.eclipse.jetty.http.HttpScheme; -+import org.eclipse.jetty.http.compression.HuffmanEncoder; -+import org.eclipse.jetty.http.compression.NBitIntegerEncoder; - import org.eclipse.jetty.util.ArrayTernaryTrie; - import org.eclipse.jetty.util.StringUtil; - import org.eclipse.jetty.util.Trie; -@@ -118,6 +120,7 @@ public class HpackContext - private static final StaticEntry[] __staticTableByHeader = new StaticEntry[HttpHeader.UNKNOWN.ordinal()]; - private static final StaticEntry[] __staticTable = new StaticEntry[STATIC_TABLE.length]; - public static final int STATIC_SIZE = STATIC_TABLE.length - 1; -+ public static final int DEFAULT_MAX_TABLE_CAPACITY = 4096; - - static - { -@@ -153,7 +156,7 @@ public class HpackContext - - case C_STATUS: - { -- entry = new StaticEntry(i, new StaticTableHttpField(header, name, value, Integer.valueOf(value))); -+ entry = new StaticEntry(i, new StaticTableHttpField(header, name, value, value)); - break; - } - -@@ -187,26 +190,26 @@ public class HpackContext - } - } - -- private int _maxDynamicTableSizeInBytes; -- private int _dynamicTableSizeInBytes; - private final DynamicTable _dynamicTable; - private final Map _fieldMap = new HashMap<>(); - private final Map _nameMap = new HashMap<>(); -+ private int _maxTableSize; -+ private int _tableSize; - -- HpackContext(int maxDynamicTableSize) -+ HpackContext(int maxTableSize) - { -- _maxDynamicTableSizeInBytes = maxDynamicTableSize; -- int guesstimateEntries = 10 + maxDynamicTableSize / (32 + 10 + 10); -+ _maxTableSize = maxTableSize; -+ int guesstimateEntries = 10 + maxTableSize / (32 + 10 + 10); - _dynamicTable = new DynamicTable(guesstimateEntries); - if (LOG.isDebugEnabled()) -- LOG.debug(String.format("HdrTbl[%x] created max=%d", hashCode(), maxDynamicTableSize)); -+ LOG.debug(String.format("HdrTbl[%x] created max=%d", hashCode(), maxTableSize)); - } - - public void resize(int newMaxDynamicTableSize) - { - if (LOG.isDebugEnabled()) -- LOG.debug(String.format("HdrTbl[%x] resized max=%d->%d", hashCode(), _maxDynamicTableSizeInBytes, newMaxDynamicTableSize)); -- _maxDynamicTableSizeInBytes = newMaxDynamicTableSize; -+ LOG.debug(String.format("HdrTbl[%x] resized max=%d->%d", hashCode(), _maxTableSize, newMaxDynamicTableSize)); -+ _maxTableSize = newMaxDynamicTableSize; - _dynamicTable.evict(); - } - -@@ -251,14 +254,14 @@ public class HpackContext - { - Entry entry = new Entry(field); - int size = entry.getSize(); -- if (size > _maxDynamicTableSizeInBytes) -+ if (size > _maxTableSize) - { - if (LOG.isDebugEnabled()) -- LOG.debug(String.format("HdrTbl[%x] !added size %d>%d", hashCode(), size, _maxDynamicTableSizeInBytes)); -+ LOG.debug(String.format("HdrTbl[%x] !added size %d>%d", hashCode(), size, _maxTableSize)); - _dynamicTable.evictAll(); - return null; - } -- _dynamicTableSizeInBytes += size; -+ _tableSize += size; - _dynamicTable.add(entry); - _fieldMap.put(field, entry); - _nameMap.put(field.getLowerCaseName(), entry); -@@ -282,7 +285,7 @@ public class HpackContext - */ - public int getDynamicTableSize() - { -- return _dynamicTableSizeInBytes; -+ return _tableSize; - } - - /** -@@ -290,7 +293,7 @@ public class HpackContext - */ - public int getMaxDynamicTableSize() - { -- return _maxDynamicTableSizeInBytes; -+ return _maxTableSize; - } - - public int index(Entry entry) -@@ -316,15 +319,15 @@ public class HpackContext - @Override - public String toString() - { -- return String.format("HpackContext@%x{entries=%d,size=%d,max=%d}", hashCode(), _dynamicTable.size(), _dynamicTableSizeInBytes, _maxDynamicTableSizeInBytes); -+ return String.format("HpackContext@%x{entries=%d,size=%d,max=%d}", hashCode(), _dynamicTable.size(), _tableSize, _maxTableSize); - } - - private class DynamicTable - { -- Entry[] _entries; -- int _size; -- int _offset; -- int _growby; -+ private Entry[] _entries; -+ private final int _growby; -+ private int _size; -+ private int _offset; - - private DynamicTable(int initCapacity) - { -@@ -372,7 +375,7 @@ public class HpackContext - - private void evict() - { -- while (_dynamicTableSizeInBytes > _maxDynamicTableSizeInBytes) -+ while (_tableSize > _maxTableSize) - { - Entry entry = _entries[_offset]; - _entries[_offset] = null; -@@ -380,7 +383,7 @@ public class HpackContext - _size--; - if (LOG.isDebugEnabled()) - LOG.debug(String.format("HdrTbl[%x] evict %s", HpackContext.this.hashCode(), entry)); -- _dynamicTableSizeInBytes -= entry.getSize(); -+ _tableSize -= entry.getSize(); - entry._slot = -1; - _fieldMap.remove(entry.getHttpField()); - String lc = entry.getHttpField().getLowerCaseName(); -@@ -388,7 +391,7 @@ public class HpackContext - _nameMap.remove(lc); - } - if (LOG.isDebugEnabled()) -- LOG.debug(String.format("HdrTbl[%x] entries=%d, size=%d, max=%d", HpackContext.this.hashCode(), _dynamicTable.size(), _dynamicTableSizeInBytes, _maxDynamicTableSizeInBytes)); -+ LOG.debug(String.format("HdrTbl[%x] entries=%d, size=%d, max=%d", HpackContext.this.hashCode(), _dynamicTable.size(), _tableSize, _maxTableSize)); - } - - private void evictAll() -@@ -401,7 +404,7 @@ public class HpackContext - _nameMap.clear(); - _offset = 0; - _size = 0; -- _dynamicTableSizeInBytes = 0; -+ _tableSize = 0; - Arrays.fill(_entries, null); - } - } -@@ -461,21 +464,21 @@ public class HpackContext - super(field); - _slot = index; - String value = field.getValue(); -- if (value != null && value.length() > 0) -+ if (value != null && !value.isEmpty()) - { -- int huffmanLen = Huffman.octetsNeeded(value); -+ int huffmanLen = HuffmanEncoder.octetsNeeded(value); - if (huffmanLen < 0) - throw new IllegalStateException("bad value"); -- int lenLen = NBitInteger.octectsNeeded(7, huffmanLen); -- _huffmanValue = new byte[1 + lenLen + huffmanLen]; -+ int lenLen = NBitIntegerEncoder.octetsNeeded(7, huffmanLen); -+ _huffmanValue = new byte[lenLen + huffmanLen]; - ByteBuffer buffer = ByteBuffer.wrap(_huffmanValue); - - // Indicate Huffman - buffer.put((byte)0x80); - // Add huffman length -- NBitInteger.encode(buffer, 7, huffmanLen); -+ NBitIntegerEncoder.encode(buffer, 7, huffmanLen); - // Encode value -- Huffman.encode(buffer, value); -+ HuffmanEncoder.encode(buffer, value); - } - else - _huffmanValue = null; -diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java -index 493b4f4..5bae260 100644 ---- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java -+++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java -@@ -24,8 +24,12 @@ import org.eclipse.jetty.http.HttpField; - import org.eclipse.jetty.http.HttpHeader; - import org.eclipse.jetty.http.HttpTokens; - import org.eclipse.jetty.http.MetaData; -+import org.eclipse.jetty.http.compression.EncodingException; -+import org.eclipse.jetty.http.compression.HuffmanDecoder; -+import org.eclipse.jetty.http.compression.NBitIntegerDecoder; - import org.eclipse.jetty.http2.hpack.HpackContext.Entry; --import org.eclipse.jetty.util.TypeUtil; -+import org.eclipse.jetty.util.BufferUtil; -+import org.eclipse.jetty.util.CharsetStringBuilder; - import org.eclipse.jetty.util.log.Log; - import org.eclipse.jetty.util.log.Logger; - -@@ -41,17 +45,27 @@ public class HpackDecoder - - private final HpackContext _context; - private final MetaDataBuilder _builder; -- private int _localMaxDynamicTableSize; -+ private final HuffmanDecoder _huffmanDecoder; -+ private final NBitIntegerDecoder _integerDecoder; -+ private int _maxTableCapacity; -+ -+ @Deprecated -+ public HpackDecoder(int localMaxDynamicTableSize, int maxHeaderSize) -+ { -+ this(maxHeaderSize); -+ } - - /** -- * @param localMaxDynamicTableSize The maximum allowed size of the local dynamic header field table. -- * @param maxHeaderSize The maximum allowed size of a headers block, expressed as total of all name and value characters, plus 32 per field -+ * @param maxHeaderSize The maximum allowed size of a decoded headers block, -+ * expressed as total of all name and value bytes, plus 32 bytes per field - */ -- public HpackDecoder(int localMaxDynamicTableSize, int maxHeaderSize) -+ public HpackDecoder(int maxHeaderSize) - { -- _context = new HpackContext(localMaxDynamicTableSize); -- _localMaxDynamicTableSize = localMaxDynamicTableSize; -+ _context = new HpackContext(HpackContext.DEFAULT_MAX_TABLE_CAPACITY); - _builder = new MetaDataBuilder(maxHeaderSize); -+ _huffmanDecoder = new HuffmanDecoder(); -+ _integerDecoder = new NBitIntegerDecoder(); -+ setMaxTableCapacity(HpackContext.DEFAULT_MAX_TABLE_CAPACITY); - } - - public HpackContext getHpackContext() -@@ -59,9 +73,44 @@ public class HpackDecoder - return _context; - } - -- public void setLocalMaxDynamicTableSize(int localMaxdynamciTableSize) -+ public int getMaxTableCapacity() -+ { -+ return _maxTableCapacity; -+ } -+ -+ /** -+ *

Sets the limit for the capacity of the dynamic header table.

-+ *

This value acts as a limit for the values received from the -+ * remote peer via the HPACK dynamic table size update instruction.

-+ *

After calling this method, a SETTINGS frame must be sent to the other -+ * peer, containing the {@code SETTINGS_HEADER_TABLE_SIZE} setting with -+ * the value passed as argument to this method.

-+ * -+ * @param maxTableCapacity the limit for capacity of the dynamic header table -+ */ -+ public void setMaxTableCapacity(int maxTableCapacity) -+ { -+ _maxTableCapacity = maxTableCapacity; -+ } -+ -+ /** -+ * @param maxTableSizeLimit the local dynamic table max size -+ * @deprecated use {@link #setMaxTableCapacity(int)} instead -+ */ -+ @Deprecated -+ public void setLocalMaxDynamicTableSize(int maxTableSizeLimit) -+ { -+ setMaxTableCapacity(maxTableSizeLimit); -+ } -+ -+ public int getMaxHeaderListSize() -+ { -+ return _builder.getMaxSize(); -+ } -+ -+ public void setMaxHeaderListSize(int maxHeaderListSize) - { -- _localMaxDynamicTableSize = localMaxdynamciTableSize; -+ _builder.setMaxSize(maxHeaderListSize); - } - - public MetaData decode(ByteBuffer buffer) throws HpackException.SessionException, HpackException.StreamException -@@ -69,27 +118,22 @@ public class HpackDecoder - if (LOG.isDebugEnabled()) - LOG.debug(String.format("CtxTbl[%x] decoding %d octets", _context.hashCode(), buffer.remaining())); - -- // If the buffer is big, don't even think about decoding it -- if (buffer.remaining() > _builder.getMaxSize()) -- throw new HpackException.SessionException("431 Request Header Fields too large"); -+ // If the buffer is larger than the max headers size, don't even start decoding it. -+ int maxSize = _builder.getMaxSize(); -+ if (maxSize > 0 && buffer.remaining() > maxSize) -+ throw new HpackException.SessionException("Header fields size too large"); - - boolean emitted = false; -- - while (buffer.hasRemaining()) - { -- if (LOG.isDebugEnabled() && buffer.hasArray()) -- { -- int l = Math.min(buffer.remaining(), 32); -- LOG.debug("decode {}{}", -- TypeUtil.toHexString(buffer.array(), buffer.arrayOffset() + buffer.position(), l), -- l < buffer.remaining() ? "..." : ""); -- } -+ if (LOG.isDebugEnabled()) -+ LOG.debug("decode {}", BufferUtil.toHexString(buffer)); - - byte b = buffer.get(); - if (b < 0) - { - // 7.1 indexed if the high bit is set -- int index = NBitInteger.decode(buffer, 7); -+ int index = integerDecode(buffer, 7); - Entry entry = _context.get(index); - if (entry == null) - throw new HpackException.SessionException("Unknown index %d", index); -@@ -130,11 +174,11 @@ public class HpackDecoder - case 2: // 7.3 - case 3: // 7.3 - // change table size -- int size = NBitInteger.decode(buffer, 5); -+ int size = integerDecode(buffer, 5); - if (LOG.isDebugEnabled()) -- LOG.debug("decode resize=" + size); -- if (size > _localMaxDynamicTableSize) -- throw new IllegalArgumentException(); -+ LOG.debug("decode resize={}", size); -+ if (size > getMaxTableCapacity()) -+ throw new HpackException.CompressionException("Dynamic table resize exceeded max limit"); - if (emitted) - throw new HpackException.CompressionException("Dynamic table resize after fields"); - _context.resize(size); -@@ -143,7 +187,7 @@ public class HpackDecoder - case 0: // 7.2.2 - case 1: // 7.2.3 - indexed = false; -- nameIndex = NBitInteger.decode(buffer, 4); -+ nameIndex = integerDecode(buffer, 4); - break; - - case 4: // 7.2.1 -@@ -151,7 +195,7 @@ public class HpackDecoder - case 6: // 7.2.1 - case 7: // 7.2.1 - indexed = true; -- nameIndex = NBitInteger.decode(buffer, 6); -+ nameIndex = integerDecode(buffer, 6); - break; - - default: -@@ -170,12 +214,11 @@ public class HpackDecoder - else - { - huffmanName = (buffer.get() & 0x80) == 0x80; -- int length = NBitInteger.decode(buffer, 7); -- _builder.checkSize(length, huffmanName); -+ int length = integerDecode(buffer, 7); - if (huffmanName) -- name = Huffman.decode(buffer, length); -+ name = huffmanDecode(buffer, length); - else -- name = toASCIIString(buffer, length); -+ name = toISO88591String(buffer, length); - check: - for (int i = name.length(); i-- > 0; ) - { -@@ -211,12 +254,11 @@ public class HpackDecoder - - // decode the value - boolean huffmanValue = (buffer.get() & 0x80) == 0x80; -- int length = NBitInteger.decode(buffer, 7); -- _builder.checkSize(length, huffmanValue); -+ int length = integerDecode(buffer, 7); - if (huffmanValue) -- value = Huffman.decode(buffer, length); -+ value = huffmanDecode(buffer, length); - else -- value = toASCIIString(buffer, length); -+ value = toISO88591String(buffer, length); - - // Make the new field - HttpField field; -@@ -277,19 +319,61 @@ public class HpackDecoder - return _builder.build(); - } - -- public static String toASCIIString(ByteBuffer buffer, int length) -+ private int integerDecode(ByteBuffer buffer, int prefix) throws HpackException.CompressionException -+ { -+ try -+ { -+ if (prefix != 8) -+ buffer.position(buffer.position() - 1); -+ -+ _integerDecoder.setPrefix(prefix); -+ int decodedInt = _integerDecoder.decodeInt(buffer); -+ if (decodedInt < 0) -+ throw new EncodingException("invalid integer encoding"); -+ return decodedInt; -+ } -+ catch (EncodingException e) -+ { -+ HpackException.CompressionException compressionException = new HpackException.CompressionException(e.getMessage()); -+ compressionException.initCause(e); -+ throw compressionException; -+ } -+ finally -+ { -+ _integerDecoder.reset(); -+ } -+ } -+ -+ private String huffmanDecode(ByteBuffer buffer, int length) throws HpackException.CompressionException -+ { -+ try -+ { -+ _huffmanDecoder.setLength(length); -+ String decoded = _huffmanDecoder.decode(buffer); -+ if (decoded == null) -+ throw new HpackException.CompressionException("invalid string encoding"); -+ return decoded; -+ } -+ catch (EncodingException e) -+ { -+ HpackException.CompressionException compressionException = new HpackException.CompressionException(e.getMessage()); -+ compressionException.initCause(e); -+ throw compressionException; -+ } -+ finally -+ { -+ _huffmanDecoder.reset(); -+ } -+ } -+ -+ public static String toISO88591String(ByteBuffer buffer, int length) - { -- StringBuilder builder = new StringBuilder(length); -- int position = buffer.position(); -- int start = buffer.arrayOffset() + position; -- int end = start + length; -- buffer.position(position + length); -- byte[] array = buffer.array(); -- for (int i = start; i < end; i++) -+ CharsetStringBuilder.Iso88591StringBuilder builder = new CharsetStringBuilder.Iso88591StringBuilder(); -+ for (int i = 0; i < length; ++i) - { -- builder.append((char)(0x7f & array[i])); -+ builder.append(HttpTokens.sanitizeFieldVchar((char)buffer.get())); - } -- return builder.toString(); -+ return builder.build(); - } - - @Override -diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackEncoder.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackEncoder.java -index 1011252..cb68bad 100644 ---- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackEncoder.java -+++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackEncoder.java -@@ -19,7 +19,6 @@ - package org.eclipse.jetty.http2.hpack; - - import java.nio.ByteBuffer; --import java.nio.charset.StandardCharsets; - import java.util.EnumMap; - import java.util.EnumSet; - import java.util.HashSet; -@@ -34,10 +33,13 @@ import org.eclipse.jetty.http.HttpStatus; - import org.eclipse.jetty.http.HttpVersion; - import org.eclipse.jetty.http.MetaData; - import org.eclipse.jetty.http.PreEncodedHttpField; -+import org.eclipse.jetty.http.compression.HuffmanEncoder; -+import org.eclipse.jetty.http.compression.NBitIntegerEncoder; -+import org.eclipse.jetty.http.compression.NBitStringEncoder; - import org.eclipse.jetty.http2.hpack.HpackContext.Entry; - import org.eclipse.jetty.http2.hpack.HpackContext.StaticEntry; -+import org.eclipse.jetty.util.BufferUtil; - 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; - -@@ -97,34 +99,78 @@ public class HpackEncoder - - private final HpackContext _context; - private final boolean _debug; -- private int _remoteMaxDynamicTableSize; -- private int _localMaxDynamicTableSize; -+ private int _maxTableCapacity; -+ private int _tableCapacity; - private int _maxHeaderListSize; - private int _headerListSize; - private boolean _validateEncoding = true; - -- public HpackEncoder() -- { -- this(4096, 4096, -1); -- } -- -+ @Deprecated - public HpackEncoder(int localMaxDynamicTableSize) - { - this(localMaxDynamicTableSize, 4096, -1); - } - -+ @Deprecated - public HpackEncoder(int localMaxDynamicTableSize, int remoteMaxDynamicTableSize) - { - this(localMaxDynamicTableSize, remoteMaxDynamicTableSize, -1); - } - -+ @Deprecated - public HpackEncoder(int localMaxDynamicTableSize, int remoteMaxDynamicTableSize, int maxHeaderListSize) - { -- _context = new HpackContext(remoteMaxDynamicTableSize); -- _remoteMaxDynamicTableSize = remoteMaxDynamicTableSize; -- _localMaxDynamicTableSize = localMaxDynamicTableSize; -- _maxHeaderListSize = maxHeaderListSize; -+ this(); -+ setLocalMaxDynamicTableSize(localMaxDynamicTableSize); -+ setRemoteMaxDynamicTableSize(remoteMaxDynamicTableSize); -+ setMaxHeaderListSize(maxHeaderListSize); -+ } -+ -+ public HpackEncoder() -+ { -+ _context = new HpackContext(0); - _debug = LOG.isDebugEnabled(); -+ setMaxTableCapacity(HpackContext.DEFAULT_MAX_TABLE_CAPACITY); -+ setTableCapacity(HpackContext.DEFAULT_MAX_TABLE_CAPACITY); -+ } -+ -+ public int getMaxTableCapacity() -+ { -+ return _maxTableCapacity; -+ } -+ -+ /** -+ *

Sets the limit for the capacity of the dynamic header table.

-+ *

This value is set by the remote peer via the -+ * {@code SETTINGS_HEADER_TABLE_SIZE} setting.

-+ * -+ * @param maxTableSizeLimit the limit for capacity of the dynamic header table -+ */ -+ public void setMaxTableCapacity(int maxTableSizeLimit) -+ { -+ _maxTableCapacity = maxTableSizeLimit; -+ } -+ -+ public int getTableCapacity() -+ { -+ return _tableCapacity; -+ } -+ -+ /** -+ *

Sets the capacity of the dynamic header table.

-+ *

The value of the capacity may be changed from {@code 0} -+ * up to {@link #getMaxTableCapacity()}. -+ * An HPACK instruction with the new capacity value will -+ * be sent to the decoder when the next call to -+ * {@link #encode(ByteBuffer, MetaData)} is made.

-+ * -+ * @param tableCapacity the capacity of the dynamic header table -+ */ -+ public void setTableCapacity(int tableCapacity) -+ { -+ if (tableCapacity > getMaxTableCapacity()) -+ throw new IllegalArgumentException("Max table capacity exceeded"); -+ _tableCapacity = tableCapacity; - } - - public int getMaxHeaderListSize() -@@ -142,14 +188,16 @@ public class HpackEncoder - return _context; - } - -- public void setRemoteMaxDynamicTableSize(int remoteMaxDynamicTableSize) -+ @Deprecated -+ public void setRemoteMaxDynamicTableSize(int maxTableSize) - { -- _remoteMaxDynamicTableSize = remoteMaxDynamicTableSize; -+ setTableCapacity(maxTableSize); - } - -- public void setLocalMaxDynamicTableSize(int localMaxDynamicTableSize) -+ @Deprecated -+ public void setLocalMaxDynamicTableSize(int maxTableSizeLimit) - { -- _localMaxDynamicTableSize = localMaxDynamicTableSize; -+ setMaxTableCapacity(maxTableSizeLimit); - } - - public boolean isValidateEncoding() -@@ -185,10 +233,10 @@ public class HpackEncoder - _headerListSize = 0; - int pos = buffer.position(); - -- // Check the dynamic table sizes! -- int maxDynamicTableSize = Math.min(_remoteMaxDynamicTableSize, _localMaxDynamicTableSize); -- if (maxDynamicTableSize != _context.getMaxDynamicTableSize()) -- encodeMaxDynamicTableSize(buffer, maxDynamicTableSize); -+ // If max table size changed, send the correspondent instruction. -+ int tableCapacity = getTableCapacity(); -+ if (tableCapacity != _context.getMaxDynamicTableSize()) -+ encodeMaxDynamicTableSize(buffer, tableCapacity); - - // Add Request/response meta fields - if (metadata.isRequest()) -@@ -255,13 +303,9 @@ public class HpackEncoder - } - } - -- // Check size -- if (_maxHeaderListSize > 0 && _headerListSize > _maxHeaderListSize) -- { -- LOG.warn("Header list size too large {} > {} for {}", _headerListSize, _maxHeaderListSize); -- if (LOG.isDebugEnabled()) -- LOG.debug("metadata={}", metadata); -- } -+ int maxHeaderListSize = getMaxHeaderListSize(); -+ if (maxHeaderListSize > 0 && _headerListSize > maxHeaderListSize) -+ throw new HpackException.SessionException("Header size %d > %d", _headerListSize, maxHeaderListSize); - - if (LOG.isDebugEnabled()) - LOG.debug(String.format("CtxTbl[%x] encoded %d octets", _context.hashCode(), buffer.position() - pos)); -@@ -278,13 +322,11 @@ public class HpackEncoder - } - } - -- public void encodeMaxDynamicTableSize(ByteBuffer buffer, int maxDynamicTableSize) -+ public void encodeMaxDynamicTableSize(ByteBuffer buffer, int maxTableSize) - { -- if (maxDynamicTableSize > _remoteMaxDynamicTableSize) -- throw new IllegalArgumentException(); - buffer.put((byte)0x20); -- NBitInteger.encode(buffer, 5, maxDynamicTableSize); -- _context.resize(maxDynamicTableSize); -+ NBitIntegerEncoder.encode(buffer, 5, maxTableSize); -+ _context.resize(maxTableSize); - } - - public void encode(ByteBuffer buffer, HttpField field) -@@ -295,8 +337,6 @@ public class HpackEncoder - int fieldSize = field.getName().length() + field.getValue().length(); - _headerListSize += fieldSize + 32; - -- final int p = _debug ? buffer.position() : -1; -- - String encoding = null; - - // Is there an index entry for the field? -@@ -314,9 +354,9 @@ public class HpackEncoder - { - int index = _context.index(entry); - buffer.put((byte)0x80); -- NBitInteger.encode(buffer, 7, index); -+ NBitIntegerEncoder.encode(buffer, 7, index); - if (_debug) -- encoding = "IdxField" + (entry.isStatic() ? "S" : "") + (1 + NBitInteger.octectsNeeded(7, index)); -+ encoding = "IdxField" + (entry.isStatic() ? "S" : "") + NBitIntegerEncoder.octetsNeeded(7, index); - } - } - else -@@ -390,19 +430,19 @@ public class HpackEncoder - - if (_debug) - encoding = "Lit" + -- ((name == null) ? "HuffN" : ("IdxN" + (name.isStatic() ? "S" : "") + (1 + NBitInteger.octectsNeeded(4, _context.index(name))))) + -+ ((name == null) ? "HuffN" : ("IdxN" + (name.isStatic() ? "S" : "") + (1 + NBitIntegerEncoder.octetsNeeded(4, _context.index(name))))) + - (huffman ? "HuffV" : "LitV") + - (neverIndex ? "!!Idx" : "!Idx"); - } - else if (fieldSize >= _context.getMaxDynamicTableSize() || header == HttpHeader.CONTENT_LENGTH && !"0".equals(field.getValue())) - { -- // The field is too large or a non zero content length, so do not index. -+ // The field is too large or a non-zero content length, so do not index. - indexed = false; - encodeName(buffer, (byte)0x00, 4, header.asString(), name); - encodeValue(buffer, true, field.getValue()); - if (_debug) - encoding = "Lit" + -- ((name == null) ? "HuffN" : "IdxNS" + (1 + NBitInteger.octectsNeeded(4, _context.index(name)))) + -+ ((name == null) ? "HuffN" : "IdxNS" + (1 + NBitIntegerEncoder.octetsNeeded(4, _context.index(name)))) + - "HuffV!Idx"; - } - else -@@ -413,7 +453,7 @@ public class HpackEncoder - encodeName(buffer, (byte)0x40, 6, header.asString(), name); - encodeValue(buffer, huffman, field.getValue()); - if (_debug) -- encoding = ((name == null) ? "LitHuffN" : ("LitIdxN" + (name.isStatic() ? "S" : "") + (1 + NBitInteger.octectsNeeded(6, _context.index(name))))) + -+ encoding = ((name == null) ? "LitHuffN" : ("LitIdxN" + (name.isStatic() ? "S" : "") + (1 + NBitIntegerEncoder.octetsNeeded(6, _context.index(name))))) + - (huffman ? "HuffVIdx" : "LitVIdx"); - } - } -@@ -425,10 +465,8 @@ public class HpackEncoder - - if (_debug) - { -- byte[] bytes = new byte[buffer.position() - p]; -- buffer.position(p); -- buffer.get(bytes); -- LOG.debug("encode {}:'{}' to '{}'", encoding, field, TypeUtil.toHexString(bytes)); -+ if (LOG.isDebugEnabled()) -+ LOG.debug("encode {}:'{}' to '{}'", encoding, field, BufferUtil.toHexString((ByteBuffer)buffer.duplicate().flip())); - } - } - -@@ -440,55 +478,17 @@ public class HpackEncoder - // leave name index bits as 0 - // Encode the name always with lowercase huffman - buffer.put((byte)0x80); -- NBitInteger.encode(buffer, 7, Huffman.octetsNeededLC(name)); -- Huffman.encodeLC(buffer, name); -+ NBitIntegerEncoder.encode(buffer, 7, HuffmanEncoder.octetsNeededLowerCase(name)); -+ HuffmanEncoder.encodeLowerCase(buffer, name); - } - else - { -- NBitInteger.encode(buffer, bits, _context.index(entry)); -+ NBitIntegerEncoder.encode(buffer, bits, _context.index(entry)); - } - } - - static void encodeValue(ByteBuffer buffer, boolean huffman, String value) - { -- if (huffman) -- { -- // huffman literal value -- buffer.put((byte)0x80); -- -- int needed = Huffman.octetsNeeded(value); -- if (needed >= 0) -- { -- NBitInteger.encode(buffer, 7, needed); -- Huffman.encode(buffer, value); -- } -- else -- { -- // Not iso_8859_1 -- byte[] bytes = value.getBytes(StandardCharsets.UTF_8); -- NBitInteger.encode(buffer, 7, Huffman.octetsNeeded(bytes)); -- Huffman.encode(buffer, bytes); -- } -- } -- else -- { -- // add literal assuming iso_8859_1 -- buffer.put((byte)0x00).mark(); -- NBitInteger.encode(buffer, 7, value.length()); -- for (int i = 0; i < value.length(); i++) -- { -- char c = value.charAt(i); -- if (c < ' ' || c > 127) -- { -- // Not iso_8859_1, so re-encode as UTF-8 -- buffer.reset(); -- byte[] bytes = value.getBytes(StandardCharsets.UTF_8); -- NBitInteger.encode(buffer, 7, bytes.length); -- buffer.put(bytes, 0, bytes.length); -- return; -- } -- buffer.put((byte)c); -- } -- } -+ NBitStringEncoder.encode(buffer, 8, value, huffman); - } - } -diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackException.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackException.java -index 2aad122..df89d80 100644 ---- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackException.java -+++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackException.java -@@ -18,7 +18,6 @@ - - package org.eclipse.jetty.http2.hpack; - --@SuppressWarnings("serial") - public abstract class HpackException extends Exception - { - HpackException(String messageFormat, Object... args) -@@ -35,7 +34,7 @@ public abstract class HpackException extends Exception - */ - public static class StreamException extends HpackException - { -- StreamException(String messageFormat, Object... args) -+ public StreamException(String messageFormat, Object... args) - { - super(messageFormat, args); - } -@@ -48,7 +47,7 @@ public abstract class HpackException extends Exception - */ - public static class SessionException extends HpackException - { -- SessionException(String messageFormat, Object... args) -+ public SessionException(String messageFormat, Object... args) - { - super(messageFormat, args); - } -diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackFieldPreEncoder.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackFieldPreEncoder.java -index 769819d..629ef2c 100644 ---- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackFieldPreEncoder.java -+++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackFieldPreEncoder.java -@@ -23,6 +23,8 @@ import java.nio.ByteBuffer; - import org.eclipse.jetty.http.HttpFieldPreEncoder; - import org.eclipse.jetty.http.HttpHeader; - import org.eclipse.jetty.http.HttpVersion; -+import org.eclipse.jetty.http.compression.HuffmanEncoder; -+import org.eclipse.jetty.http.compression.NBitIntegerEncoder; - import org.eclipse.jetty.util.BufferUtil; - - /** -@@ -31,18 +33,12 @@ import org.eclipse.jetty.util.BufferUtil; - public class HpackFieldPreEncoder implements HttpFieldPreEncoder - { - -- /** -- * @see org.eclipse.jetty.http.HttpFieldPreEncoder#getHttpVersion() -- */ - @Override - public HttpVersion getHttpVersion() - { - return HttpVersion.HTTP_2; - } - -- /** -- * @see org.eclipse.jetty.http.HttpFieldPreEncoder#getEncodedField(org.eclipse.jetty.http.HttpHeader, java.lang.String, java.lang.String) -- */ - @Override - public byte[] getEncodedField(HttpHeader header, String name, String value) - { -@@ -78,12 +74,12 @@ public class HpackFieldPreEncoder implements HttpFieldPreEncoder - - int nameIdx = HpackContext.staticIndex(header); - if (nameIdx > 0) -- NBitInteger.encode(buffer, bits, nameIdx); -+ NBitIntegerEncoder.encode(buffer, bits, nameIdx); - else - { - buffer.put((byte)0x80); -- NBitInteger.encode(buffer, 7, Huffman.octetsNeededLC(name)); -- Huffman.encodeLC(buffer, name); -+ NBitIntegerEncoder.encode(buffer, 7, HuffmanEncoder.octetsNeededLowerCase(name)); -+ HuffmanEncoder.encodeLowerCase(buffer, name); - } - - HpackEncoder.encodeValue(buffer, huffman, value); -diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/Huffman.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/Huffman.java -deleted file mode 100644 -index 26e948b..0000000 ---- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/Huffman.java -+++ /dev/null -@@ -1,551 +0,0 @@ --// --// ======================================================================== --// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. --// ------------------------------------------------------------------------ --// 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.http2.hpack; -- --import java.nio.ByteBuffer; -- --import org.eclipse.jetty.util.Utf8StringBuilder; -- --public class Huffman --{ -- -- // Appendix C: Huffman Codes -- // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-12#appendix-C -- static final int[][] CODES = -- { -- /* ( 0) |11111111|11000 */ {0x1ff8, 13}, -- /* ( 1) |11111111|11111111|1011000 */ {0x7fffd8, 23}, -- /* ( 2) |11111111|11111111|11111110|0010 */ {0xfffffe2, 28}, -- /* ( 3) |11111111|11111111|11111110|0011 */ {0xfffffe3, 28}, -- /* ( 4) |11111111|11111111|11111110|0100 */ {0xfffffe4, 28}, -- /* ( 5) |11111111|11111111|11111110|0101 */ {0xfffffe5, 28}, -- /* ( 6) |11111111|11111111|11111110|0110 */ {0xfffffe6, 28}, -- /* ( 7) |11111111|11111111|11111110|0111 */ {0xfffffe7, 28}, -- /* ( 8) |11111111|11111111|11111110|1000 */ {0xfffffe8, 28}, -- /* ( 9) |11111111|11111111|11101010 */ {0xffffea, 24}, -- /* ( 10) |11111111|11111111|11111111|111100 */ {0x3ffffffc, 30}, -- /* ( 11) |11111111|11111111|11111110|1001 */ {0xfffffe9, 28}, -- /* ( 12) |11111111|11111111|11111110|1010 */ {0xfffffea, 28}, -- /* ( 13) |11111111|11111111|11111111|111101 */ {0x3ffffffd, 30}, -- /* ( 14) |11111111|11111111|11111110|1011 */ {0xfffffeb, 28}, -- /* ( 15) |11111111|11111111|11111110|1100 */ {0xfffffec, 28}, -- /* ( 16) |11111111|11111111|11111110|1101 */ {0xfffffed, 28}, -- /* ( 17) |11111111|11111111|11111110|1110 */ {0xfffffee, 28}, -- /* ( 18) |11111111|11111111|11111110|1111 */ {0xfffffef, 28}, -- /* ( 19) |11111111|11111111|11111111|0000 */ {0xffffff0, 28}, -- /* ( 20) |11111111|11111111|11111111|0001 */ {0xffffff1, 28}, -- /* ( 21) |11111111|11111111|11111111|0010 */ {0xffffff2, 28}, -- /* ( 22) |11111111|11111111|11111111|111110 */ {0x3ffffffe, 30}, -- /* ( 23) |11111111|11111111|11111111|0011 */ {0xffffff3, 28}, -- /* ( 24) |11111111|11111111|11111111|0100 */ {0xffffff4, 28}, -- /* ( 25) |11111111|11111111|11111111|0101 */ {0xffffff5, 28}, -- /* ( 26) |11111111|11111111|11111111|0110 */ {0xffffff6, 28}, -- /* ( 27) |11111111|11111111|11111111|0111 */ {0xffffff7, 28}, -- /* ( 28) |11111111|11111111|11111111|1000 */ {0xffffff8, 28}, -- /* ( 29) |11111111|11111111|11111111|1001 */ {0xffffff9, 28}, -- /* ( 30) |11111111|11111111|11111111|1010 */ {0xffffffa, 28}, -- /* ( 31) |11111111|11111111|11111111|1011 */ {0xffffffb, 28}, -- /*' ' ( 32) |010100 */ {0x14, 6}, -- /*'!' ( 33) |11111110|00 */ {0x3f8, 10}, -- /*'"' ( 34) |11111110|01 */ {0x3f9, 10}, -- /*'#' ( 35) |11111111|1010 */ {0xffa, 12}, -- /*'$' ( 36) |11111111|11001 */ {0x1ff9, 13}, -- /*'%' ( 37) |010101 */ {0x15, 6}, -- /*'&' ( 38) |11111000 */ {0xf8, 8}, -- /*''' ( 39) |11111111|010 */ {0x7fa, 11}, -- /*'(' ( 40) |11111110|10 */ {0x3fa, 10}, -- /*')' ( 41) |11111110|11 */ {0x3fb, 10}, -- /*'*' ( 42) |11111001 */ {0xf9, 8}, -- /*'+' ( 43) |11111111|011 */ {0x7fb, 11}, -- /*',' ( 44) |11111010 */ {0xfa, 8}, -- /*'-' ( 45) |010110 */ {0x16, 6}, -- /*'.' ( 46) |010111 */ {0x17, 6}, -- /*'/' ( 47) |011000 */ {0x18, 6}, -- /*'0' ( 48) |00000 */ {0x0, 5}, -- /*'1' ( 49) |00001 */ {0x1, 5}, -- /*'2' ( 50) |00010 */ {0x2, 5}, -- /*'3' ( 51) |011001 */ {0x19, 6}, -- /*'4' ( 52) |011010 */ {0x1a, 6}, -- /*'5' ( 53) |011011 */ {0x1b, 6}, -- /*'6' ( 54) |011100 */ {0x1c, 6}, -- /*'7' ( 55) |011101 */ {0x1d, 6}, -- /*'8' ( 56) |011110 */ {0x1e, 6}, -- /*'9' ( 57) |011111 */ {0x1f, 6}, -- /*':' ( 58) |1011100 */ {0x5c, 7}, -- /*';' ( 59) |11111011 */ {0xfb, 8}, -- /*'<' ( 60) |11111111|1111100 */ {0x7ffc, 15}, -- /*'=' ( 61) |100000 */ {0x20, 6}, -- /*'>' ( 62) |11111111|1011 */ {0xffb, 12}, -- /*'?' ( 63) |11111111|00 */ {0x3fc, 10}, -- /*'@' ( 64) |11111111|11010 */ {0x1ffa, 13}, -- /*'A' ( 65) |100001 */ {0x21, 6}, -- /*'B' ( 66) |1011101 */ {0x5d, 7}, -- /*'C' ( 67) |1011110 */ {0x5e, 7}, -- /*'D' ( 68) |1011111 */ {0x5f, 7}, -- /*'E' ( 69) |1100000 */ {0x60, 7}, -- /*'F' ( 70) |1100001 */ {0x61, 7}, -- /*'G' ( 71) |1100010 */ {0x62, 7}, -- /*'H' ( 72) |1100011 */ {0x63, 7}, -- /*'I' ( 73) |1100100 */ {0x64, 7}, -- /*'J' ( 74) |1100101 */ {0x65, 7}, -- /*'K' ( 75) |1100110 */ {0x66, 7}, -- /*'L' ( 76) |1100111 */ {0x67, 7}, -- /*'M' ( 77) |1101000 */ {0x68, 7}, -- /*'N' ( 78) |1101001 */ {0x69, 7}, -- /*'O' ( 79) |1101010 */ {0x6a, 7}, -- /*'P' ( 80) |1101011 */ {0x6b, 7}, -- /*'Q' ( 81) |1101100 */ {0x6c, 7}, -- /*'R' ( 82) |1101101 */ {0x6d, 7}, -- /*'S' ( 83) |1101110 */ {0x6e, 7}, -- /*'T' ( 84) |1101111 */ {0x6f, 7}, -- /*'U' ( 85) |1110000 */ {0x70, 7}, -- /*'V' ( 86) |1110001 */ {0x71, 7}, -- /*'W' ( 87) |1110010 */ {0x72, 7}, -- /*'X' ( 88) |11111100 */ {0xfc, 8}, -- /*'Y' ( 89) |1110011 */ {0x73, 7}, -- /*'Z' ( 90) |11111101 */ {0xfd, 8}, -- /*'[' ( 91) |11111111|11011 */ {0x1ffb, 13}, -- /*'\' ( 92) |11111111|11111110|000 */ {0x7fff0, 19}, -- /*']' ( 93) |11111111|11100 */ {0x1ffc, 13}, -- /*'^' ( 94) |11111111|111100 */ {0x3ffc, 14}, -- /*'_' ( 95) |100010 */ {0x22, 6}, -- /*'`' ( 96) |11111111|1111101 */ {0x7ffd, 15}, -- /*'a' ( 97) |00011 */ {0x3, 5}, -- /*'b' ( 98) |100011 */ {0x23, 6}, -- /*'c' ( 99) |00100 */ {0x4, 5}, -- /*'d' (100) |100100 */ {0x24, 6}, -- /*'e' (101) |00101 */ {0x5, 5}, -- /*'f' (102) |100101 */ {0x25, 6}, -- /*'g' (103) |100110 */ {0x26, 6}, -- /*'h' (104) |100111 */ {0x27, 6}, -- /*'i' (105) |00110 */ {0x6, 5}, -- /*'j' (106) |1110100 */ {0x74, 7}, -- /*'k' (107) |1110101 */ {0x75, 7}, -- /*'l' (108) |101000 */ {0x28, 6}, -- /*'m' (109) |101001 */ {0x29, 6}, -- /*'n' (110) |101010 */ {0x2a, 6}, -- /*'o' (111) |00111 */ {0x7, 5}, -- /*'p' (112) |101011 */ {0x2b, 6}, -- /*'q' (113) |1110110 */ {0x76, 7}, -- /*'r' (114) |101100 */ {0x2c, 6}, -- /*'s' (115) |01000 */ {0x8, 5}, -- /*'t' (116) |01001 */ {0x9, 5}, -- /*'u' (117) |101101 */ {0x2d, 6}, -- /*'v' (118) |1110111 */ {0x77, 7}, -- /*'w' (119) |1111000 */ {0x78, 7}, -- /*'x' (120) |1111001 */ {0x79, 7}, -- /*'y' (121) |1111010 */ {0x7a, 7}, -- /*'z' (122) |1111011 */ {0x7b, 7}, -- /*'{' (123) |11111111|1111110 */ {0x7ffe, 15}, -- /*'|' (124) |11111111|100 */ {0x7fc, 11}, -- /*'}' (125) |11111111|111101 */ {0x3ffd, 14}, -- /*'~' (126) |11111111|11101 */ {0x1ffd, 13}, -- /* (127) |11111111|11111111|11111111|1100 */ {0xffffffc, 28}, -- /* (128) |11111111|11111110|0110 */ {0xfffe6, 20}, -- /* (129) |11111111|11111111|010010 */ {0x3fffd2, 22}, -- /* (130) |11111111|11111110|0111 */ {0xfffe7, 20}, -- /* (131) |11111111|11111110|1000 */ {0xfffe8, 20}, -- /* (132) |11111111|11111111|010011 */ {0x3fffd3, 22}, -- /* (133) |11111111|11111111|010100 */ {0x3fffd4, 22}, -- /* (134) |11111111|11111111|010101 */ {0x3fffd5, 22}, -- /* (135) |11111111|11111111|1011001 */ {0x7fffd9, 23}, -- /* (136) |11111111|11111111|010110 */ {0x3fffd6, 22}, -- /* (137) |11111111|11111111|1011010 */ {0x7fffda, 23}, -- /* (138) |11111111|11111111|1011011 */ {0x7fffdb, 23}, -- /* (139) |11111111|11111111|1011100 */ {0x7fffdc, 23}, -- /* (140) |11111111|11111111|1011101 */ {0x7fffdd, 23}, -- /* (141) |11111111|11111111|1011110 */ {0x7fffde, 23}, -- /* (142) |11111111|11111111|11101011 */ {0xffffeb, 24}, -- /* (143) |11111111|11111111|1011111 */ {0x7fffdf, 23}, -- /* (144) |11111111|11111111|11101100 */ {0xffffec, 24}, -- /* (145) |11111111|11111111|11101101 */ {0xffffed, 24}, -- /* (146) |11111111|11111111|010111 */ {0x3fffd7, 22}, -- /* (147) |11111111|11111111|1100000 */ {0x7fffe0, 23}, -- /* (148) |11111111|11111111|11101110 */ {0xffffee, 24}, -- /* (149) |11111111|11111111|1100001 */ {0x7fffe1, 23}, -- /* (150) |11111111|11111111|1100010 */ {0x7fffe2, 23}, -- /* (151) |11111111|11111111|1100011 */ {0x7fffe3, 23}, -- /* (152) |11111111|11111111|1100100 */ {0x7fffe4, 23}, -- /* (153) |11111111|11111110|11100 */ {0x1fffdc, 21}, -- /* (154) |11111111|11111111|011000 */ {0x3fffd8, 22}, -- /* (155) |11111111|11111111|1100101 */ {0x7fffe5, 23}, -- /* (156) |11111111|11111111|011001 */ {0x3fffd9, 22}, -- /* (157) |11111111|11111111|1100110 */ {0x7fffe6, 23}, -- /* (158) |11111111|11111111|1100111 */ {0x7fffe7, 23}, -- /* (159) |11111111|11111111|11101111 */ {0xffffef, 24}, -- /* (160) |11111111|11111111|011010 */ {0x3fffda, 22}, -- /* (161) |11111111|11111110|11101 */ {0x1fffdd, 21}, -- /* (162) |11111111|11111110|1001 */ {0xfffe9, 20}, -- /* (163) |11111111|11111111|011011 */ {0x3fffdb, 22}, -- /* (164) |11111111|11111111|011100 */ {0x3fffdc, 22}, -- /* (165) |11111111|11111111|1101000 */ {0x7fffe8, 23}, -- /* (166) |11111111|11111111|1101001 */ {0x7fffe9, 23}, -- /* (167) |11111111|11111110|11110 */ {0x1fffde, 21}, -- /* (168) |11111111|11111111|1101010 */ {0x7fffea, 23}, -- /* (169) |11111111|11111111|011101 */ {0x3fffdd, 22}, -- /* (170) |11111111|11111111|011110 */ {0x3fffde, 22}, -- /* (171) |11111111|11111111|11110000 */ {0xfffff0, 24}, -- /* (172) |11111111|11111110|11111 */ {0x1fffdf, 21}, -- /* (173) |11111111|11111111|011111 */ {0x3fffdf, 22}, -- /* (174) |11111111|11111111|1101011 */ {0x7fffeb, 23}, -- /* (175) |11111111|11111111|1101100 */ {0x7fffec, 23}, -- /* (176) |11111111|11111111|00000 */ {0x1fffe0, 21}, -- /* (177) |11111111|11111111|00001 */ {0x1fffe1, 21}, -- /* (178) |11111111|11111111|100000 */ {0x3fffe0, 22}, -- /* (179) |11111111|11111111|00010 */ {0x1fffe2, 21}, -- /* (180) |11111111|11111111|1101101 */ {0x7fffed, 23}, -- /* (181) |11111111|11111111|100001 */ {0x3fffe1, 22}, -- /* (182) |11111111|11111111|1101110 */ {0x7fffee, 23}, -- /* (183) |11111111|11111111|1101111 */ {0x7fffef, 23}, -- /* (184) |11111111|11111110|1010 */ {0xfffea, 20}, -- /* (185) |11111111|11111111|100010 */ {0x3fffe2, 22}, -- /* (186) |11111111|11111111|100011 */ {0x3fffe3, 22}, -- /* (187) |11111111|11111111|100100 */ {0x3fffe4, 22}, -- /* (188) |11111111|11111111|1110000 */ {0x7ffff0, 23}, -- /* (189) |11111111|11111111|100101 */ {0x3fffe5, 22}, -- /* (190) |11111111|11111111|100110 */ {0x3fffe6, 22}, -- /* (191) |11111111|11111111|1110001 */ {0x7ffff1, 23}, -- /* (192) |11111111|11111111|11111000|00 */ {0x3ffffe0, 26}, -- /* (193) |11111111|11111111|11111000|01 */ {0x3ffffe1, 26}, -- /* (194) |11111111|11111110|1011 */ {0xfffeb, 20}, -- /* (195) |11111111|11111110|001 */ {0x7fff1, 19}, -- /* (196) |11111111|11111111|100111 */ {0x3fffe7, 22}, -- /* (197) |11111111|11111111|1110010 */ {0x7ffff2, 23}, -- /* (198) |11111111|11111111|101000 */ {0x3fffe8, 22}, -- /* (199) |11111111|11111111|11110110|0 */ {0x1ffffec, 25}, -- /* (200) |11111111|11111111|11111000|10 */ {0x3ffffe2, 26}, -- /* (201) |11111111|11111111|11111000|11 */ {0x3ffffe3, 26}, -- /* (202) |11111111|11111111|11111001|00 */ {0x3ffffe4, 26}, -- /* (203) |11111111|11111111|11111011|110 */ {0x7ffffde, 27}, -- /* (204) |11111111|11111111|11111011|111 */ {0x7ffffdf, 27}, -- /* (205) |11111111|11111111|11111001|01 */ {0x3ffffe5, 26}, -- /* (206) |11111111|11111111|11110001 */ {0xfffff1, 24}, -- /* (207) |11111111|11111111|11110110|1 */ {0x1ffffed, 25}, -- /* (208) |11111111|11111110|010 */ {0x7fff2, 19}, -- /* (209) |11111111|11111111|00011 */ {0x1fffe3, 21}, -- /* (210) |11111111|11111111|11111001|10 */ {0x3ffffe6, 26}, -- /* (211) |11111111|11111111|11111100|000 */ {0x7ffffe0, 27}, -- /* (212) |11111111|11111111|11111100|001 */ {0x7ffffe1, 27}, -- /* (213) |11111111|11111111|11111001|11 */ {0x3ffffe7, 26}, -- /* (214) |11111111|11111111|11111100|010 */ {0x7ffffe2, 27}, -- /* (215) |11111111|11111111|11110010 */ {0xfffff2, 24}, -- /* (216) |11111111|11111111|00100 */ {0x1fffe4, 21}, -- /* (217) |11111111|11111111|00101 */ {0x1fffe5, 21}, -- /* (218) |11111111|11111111|11111010|00 */ {0x3ffffe8, 26}, -- /* (219) |11111111|11111111|11111010|01 */ {0x3ffffe9, 26}, -- /* (220) |11111111|11111111|11111111|1101 */ {0xffffffd, 28}, -- /* (221) |11111111|11111111|11111100|011 */ {0x7ffffe3, 27}, -- /* (222) |11111111|11111111|11111100|100 */ {0x7ffffe4, 27}, -- /* (223) |11111111|11111111|11111100|101 */ {0x7ffffe5, 27}, -- /* (224) |11111111|11111110|1100 */ {0xfffec, 20}, -- /* (225) |11111111|11111111|11110011 */ {0xfffff3, 24}, -- /* (226) |11111111|11111110|1101 */ {0xfffed, 20}, -- /* (227) |11111111|11111111|00110 */ {0x1fffe6, 21}, -- /* (228) |11111111|11111111|101001 */ {0x3fffe9, 22}, -- /* (229) |11111111|11111111|00111 */ {0x1fffe7, 21}, -- /* (230) |11111111|11111111|01000 */ {0x1fffe8, 21}, -- /* (231) |11111111|11111111|1110011 */ {0x7ffff3, 23}, -- /* (232) |11111111|11111111|101010 */ {0x3fffea, 22}, -- /* (233) |11111111|11111111|101011 */ {0x3fffeb, 22}, -- /* (234) |11111111|11111111|11110111|0 */ {0x1ffffee, 25}, -- /* (235) |11111111|11111111|11110111|1 */ {0x1ffffef, 25}, -- /* (236) |11111111|11111111|11110100 */ {0xfffff4, 24}, -- /* (237) |11111111|11111111|11110101 */ {0xfffff5, 24}, -- /* (238) |11111111|11111111|11111010|10 */ {0x3ffffea, 26}, -- /* (239) |11111111|11111111|1110100 */ {0x7ffff4, 23}, -- /* (240) |11111111|11111111|11111010|11 */ {0x3ffffeb, 26}, -- /* (241) |11111111|11111111|11111100|110 */ {0x7ffffe6, 27}, -- /* (242) |11111111|11111111|11111011|00 */ {0x3ffffec, 26}, -- /* (243) |11111111|11111111|11111011|01 */ {0x3ffffed, 26}, -- /* (244) |11111111|11111111|11111100|111 */ {0x7ffffe7, 27}, -- /* (245) |11111111|11111111|11111101|000 */ {0x7ffffe8, 27}, -- /* (246) |11111111|11111111|11111101|001 */ {0x7ffffe9, 27}, -- /* (247) |11111111|11111111|11111101|010 */ {0x7ffffea, 27}, -- /* (248) |11111111|11111111|11111101|011 */ {0x7ffffeb, 27}, -- /* (249) |11111111|11111111|11111111|1110 */ {0xffffffe, 28}, -- /* (250) |11111111|11111111|11111101|100 */ {0x7ffffec, 27}, -- /* (251) |11111111|11111111|11111101|101 */ {0x7ffffed, 27}, -- /* (252) |11111111|11111111|11111101|110 */ {0x7ffffee, 27}, -- /* (253) |11111111|11111111|11111101|111 */ {0x7ffffef, 27}, -- /* (254) |11111111|11111111|11111110|000 */ {0x7fffff0, 27}, -- /* (255) |11111111|11111111|11111011|10 */ {0x3ffffee, 26}, -- /*EOS (256) |11111111|11111111|11111111|111111 */ {0x3fffffff, 30} -- }; -- -- static final int[][] LCCODES = new int[CODES.length][]; -- static final char EOS = 256; -- -- // Huffman decode tree stored in a flattened char array for good -- // locality of reference. -- static final char[] tree; -- static final char[] rowsym; -- static final byte[] rowbits; -- -- // Build the Huffman lookup tree and LC TABLE -- static -- { -- System.arraycopy(CODES, 0, LCCODES, 0, CODES.length); -- for (int i = 'A'; i <= 'Z'; i++) -- { -- LCCODES[i] = LCCODES['a' + i - 'A']; -- } -- -- int r = 0; -- for (int i = 0; i < CODES.length; i++) -- { -- r += (CODES[i][1] + 7) / 8; -- } -- tree = new char[r * 256]; -- rowsym = new char[r]; -- rowbits = new byte[r]; -- -- r = 0; -- for (int sym = 0; sym < CODES.length; sym++) -- { -- int code = CODES[sym][0]; -- int len = CODES[sym][1]; -- -- int current = 0; -- -- while (len > 8) -- { -- len -= 8; -- int i = ((code >>> len) & 0xFF); -- -- int t = current * 256 + i; -- current = tree[t]; -- if (current == 0) -- { -- tree[t] = (char)++r; -- current = r; -- } -- } -- -- int terminal = ++r; -- rowsym[r] = (char)sym; -- int b = len & 0x07; -- int terminalBits = b == 0 ? 8 : b; -- -- rowbits[r] = (byte)terminalBits; -- int shift = 8 - len; -- int start = current * 256 + ((code << shift) & 0xFF); -- int end = start + (1 << shift); -- for (int i = start; i < end; i++) -- { -- tree[i] = (char)terminal; -- } -- } -- } -- -- public static String decode(ByteBuffer buffer) throws HpackException.CompressionException -- { -- return decode(buffer, buffer.remaining()); -- } -- -- public static String decode(ByteBuffer buffer, int length) throws HpackException.CompressionException -- { -- Utf8StringBuilder utf8 = new Utf8StringBuilder(length * 2); -- int node = 0; -- int current = 0; -- int bits = 0; -- -- for (int i = 0; i < length; i++) -- { -- int b = buffer.get() & 0xFF; -- current = (current << 8) | b; -- bits += 8; -- while (bits >= 8) -- { -- int c = (current >>> (bits - 8)) & 0xFF; -- node = tree[node * 256 + c]; -- if (rowbits[node] != 0) -- { -- if (rowsym[node] == EOS) -- throw new HpackException.CompressionException("EOS in content"); -- -- // terminal node -- utf8.append((byte)(0xFF & rowsym[node])); -- bits -= rowbits[node]; -- node = 0; -- } -- else -- { -- // non-terminal node -- bits -= 8; -- } -- } -- } -- -- while (bits > 0) -- { -- int c = (current << (8 - bits)) & 0xFF; -- int lastNode = node; -- node = tree[node * 256 + c]; -- -- if (rowbits[node] == 0 || rowbits[node] > bits) -- { -- int requiredPadding = 0; -- for (int i = 0; i < bits; i++) -- { -- requiredPadding = (requiredPadding << 1) | 1; -- } -- -- if ((c >> (8 - bits)) != requiredPadding) -- throw new HpackException.CompressionException("Incorrect padding"); -- -- node = lastNode; -- break; -- } -- -- utf8.append((byte)(0xFF & rowsym[node])); -- bits -= rowbits[node]; -- node = 0; -- } -- -- if (node != 0) -- throw new HpackException.CompressionException("Bad termination"); -- -- return utf8.toString(); -- } -- -- public static int octetsNeeded(String s) -- { -- return octetsNeeded(CODES, s); -- } -- -- public static int octetsNeeded(byte[] b) -- { -- return octetsNeeded(CODES, b); -- } -- -- public static void encode(ByteBuffer buffer, String s) -- { -- encode(CODES, buffer, s); -- } -- -- public static void encode(ByteBuffer buffer, byte[] b) -- { -- encode(CODES, buffer, b); -- } -- -- public static int octetsNeededLC(String s) -- { -- return octetsNeeded(LCCODES, s); -- } -- -- public static void encodeLC(ByteBuffer buffer, String s) -- { -- encode(LCCODES, buffer, s); -- } -- -- private static int octetsNeeded(final int[][] table, String s) -- { -- int needed = 0; -- int len = s.length(); -- for (int i = 0; i < len; i++) -- { -- char c = s.charAt(i); -- if (c >= 128 || c < ' ') -- return -1; -- needed += table[c][1]; -- } -- -- return (needed + 7) / 8; -- } -- -- private static int octetsNeeded(final int[][] table, byte[] b) -- { -- int needed = 0; -- int len = b.length; -- for (int i = 0; i < len; i++) -- { -- int c = 0xFF & b[i]; -- needed += table[c][1]; -- } -- return (needed + 7) / 8; -- } -- -- /** -- * @param table The table to encode by -- * @param buffer The buffer to encode to -- * @param s The string to encode -- */ -- private static void encode(final int[][] table, ByteBuffer buffer, String s) -- { -- long current = 0; -- int n = 0; -- int len = s.length(); -- for (int i = 0; i < len; i++) -- { -- char c = s.charAt(i); -- if (c >= 128 || c < ' ') -- throw new IllegalArgumentException(); -- int code = table[c][0]; -- int bits = table[c][1]; -- -- current <<= bits; -- current |= code; -- n += bits; -- -- while (n >= 8) -- { -- n -= 8; -- buffer.put((byte)(current >> n)); -- } -- } -- -- if (n > 0) -- { -- current <<= (8 - n); -- current |= (0xFF >>> n); -- buffer.put((byte)(current)); -- } -- } -- -- private static void encode(final int[][] table, ByteBuffer buffer, byte[] b) -- { -- long current = 0; -- int n = 0; -- -- int len = b.length; -- for (int i = 0; i < len; i++) -- { -- int c = 0xFF & b[i]; -- int code = table[c][0]; -- int bits = table[c][1]; -- -- current <<= bits; -- current |= code; -- n += bits; -- -- while (n >= 8) -- { -- n -= 8; -- buffer.put((byte)(current >> n)); -- } -- } -- -- if (n > 0) -- { -- current <<= (8 - n); -- current |= (0xFF >>> n); -- buffer.put((byte)(current)); -- } -- } --} -diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java -index df45309..9ed7253 100644 ---- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java -+++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java -@@ -29,7 +29,7 @@ import org.eclipse.jetty.http2.hpack.HpackException.SessionException; - - public class MetaDataBuilder - { -- private final int _maxSize; -+ private int _maxSize; - private int _size; - private Integer _status; - private String _method; -@@ -60,6 +60,11 @@ public class MetaDataBuilder - return _maxSize; - } - -+ public void setMaxSize(int maxSize) -+ { -+ _maxSize = maxSize; -+ } -+ - /** - * Get the size. - * -@@ -70,17 +75,18 @@ public class MetaDataBuilder - return _size; - } - -- public void emit(HttpField field) throws HpackException.SessionException -+ public void emit(HttpField field) throws SessionException - { - HttpHeader header = field.getHeader(); - String name = field.getName(); -- if (name == null || name.length() == 0) -- throw new HpackException.SessionException("Header size 0"); -+ if (name == null || name.isEmpty()) -+ throw new SessionException("Header size 0"); - String value = field.getValue(); - int fieldSize = name.length() + (value == null ? 0 : value.length()); - _size += fieldSize + 32; -- if (_size > _maxSize) -- throw new HpackException.SessionException("Header size %d > %d", _size, _maxSize); -+ int maxSize = getMaxSize(); -+ if (maxSize > 0 && _size > maxSize) -+ throw new SessionException("Header size %d > %d", _size, maxSize); - - if (field instanceof StaticTableHttpField) - { -@@ -89,7 +95,7 @@ public class MetaDataBuilder - { - case C_STATUS: - if (checkPseudoHeader(header, _status)) -- _status = (Integer)staticField.getStaticValue(); -+ _status = staticField.getIntValue(); - _response = true; - break; - -@@ -157,7 +163,7 @@ public class MetaDataBuilder - case C_PATH: - if (checkPseudoHeader(header, _path)) - { -- if (value != null && value.length() > 0) -+ if (value != null && !value.isEmpty()) - _path = value; - else - streamException("No Path"); -@@ -201,7 +207,7 @@ public class MetaDataBuilder - } - } - -- protected void streamException(String messageFormat, Object... args) -+ public void streamException(String messageFormat, Object... args) - { - HpackException.StreamException stream = new HpackException.StreamException(messageFormat, args); - if (_streamException == null) -@@ -267,23 +273,7 @@ public class MetaDataBuilder - _authority = null; - _path = null; - _size = 0; -- _contentLength = Long.MIN_VALUE; -+ _contentLength = -1; - } - } -- -- /** -- * Check that the max size will not be exceeded. -- * -- * @param length the length -- * @param huffman the huffman name -- * @throws SessionException in case of size errors -- */ -- public void checkSize(int length, boolean huffman) throws SessionException -- { -- // Apply a huffman fudge factor -- if (huffman) -- length = (length * 4) / 3; -- if ((_size + length) > _maxSize) -- throw new HpackException.SessionException("Header too large %d > %d", _size + length, _maxSize); -- } - } -diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/NBitInteger.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/NBitInteger.java -deleted file mode 100644 -index bab61bb..0000000 ---- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/NBitInteger.java -+++ /dev/null -@@ -1,151 +0,0 @@ --// --// ======================================================================== --// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. --// ------------------------------------------------------------------------ --// 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.http2.hpack; -- --import java.nio.ByteBuffer; -- --public class NBitInteger --{ -- public static int octectsNeeded(int n, int i) -- { -- if (n == 8) -- { -- int nbits = 0xFF; -- i = i - nbits; -- if (i < 0) -- return 1; -- if (i == 0) -- return 2; -- int lz = Integer.numberOfLeadingZeros(i); -- int log = 32 - lz; -- return 1 + (log + 6) / 7; -- } -- -- int nbits = 0xFF >>> (8 - n); -- i = i - nbits; -- if (i < 0) -- return 0; -- if (i == 0) -- return 1; -- int lz = Integer.numberOfLeadingZeros(i); -- int log = 32 - lz; -- return (log + 6) / 7; -- } -- -- public static void encode(ByteBuffer buf, int n, int i) -- { -- if (n == 8) -- { -- if (i < 0xFF) -- { -- buf.put((byte)i); -- } -- else -- { -- buf.put((byte)0xFF); -- -- int length = i - 0xFF; -- while (true) -- { -- if ((length & ~0x7F) == 0) -- { -- buf.put((byte)length); -- return; -- } -- else -- { -- buf.put((byte)((length & 0x7F) | 0x80)); -- length >>>= 7; -- } -- } -- } -- } -- else -- { -- int p = buf.position() - 1; -- int bits = 0xFF >>> (8 - n); -- -- if (i < bits) -- { -- buf.put(p, (byte)((buf.get(p) & ~bits) | i)); -- } -- else -- { -- buf.put(p, (byte)(buf.get(p) | bits)); -- -- int length = i - bits; -- while (true) -- { -- if ((length & ~0x7F) == 0) -- { -- buf.put((byte)length); -- return; -- } -- else -- { -- buf.put((byte)((length & 0x7F) | 0x80)); -- length >>>= 7; -- } -- } -- } -- } -- } -- -- public static int decode(ByteBuffer buffer, int n) -- { -- if (n == 8) -- { -- int nbits = 0xFF; -- -- int i = buffer.get() & 0xff; -- -- if (i == nbits) -- { -- int m = 1; -- int b; -- do -- { -- b = 0xff & buffer.get(); -- i = i + (b & 127) * m; -- m = m * 128; -- } -- while ((b & 128) == 128); -- } -- return i; -- } -- -- int nbits = 0xFF >>> (8 - n); -- -- int i = buffer.get(buffer.position() - 1) & nbits; -- -- if (i == nbits) -- { -- int m = 1; -- int b; -- do -- { -- b = 0xff & buffer.get(); -- i = i + (b & 127) * m; -- m = m * 128; -- } -- while ((b & 128) == 128); -- } -- return i; -- } --} -diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackContextTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackContextTest.java -index ed0d914..a767a51 100644 ---- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackContextTest.java -+++ b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackContextTest.java -@@ -21,6 +21,9 @@ package org.eclipse.jetty.http2.hpack; - import java.nio.ByteBuffer; - - import org.eclipse.jetty.http.HttpField; -+import org.eclipse.jetty.http.compression.EncodingException; -+import org.eclipse.jetty.http.compression.HuffmanDecoder; -+import org.eclipse.jetty.http.compression.NBitIntegerDecoder; - import org.eclipse.jetty.http2.hpack.HpackContext.Entry; - import org.hamcrest.Matchers; - import org.junit.jupiter.api.Test; -@@ -37,6 +40,32 @@ import static org.junit.jupiter.api.Assertions.assertTrue; - */ - public class HpackContextTest - { -+ public static String decode(ByteBuffer buffer, int length) throws EncodingException -+ { -+ HuffmanDecoder huffmanDecoder = new HuffmanDecoder(); -+ huffmanDecoder.setLength(length); -+ String decoded = huffmanDecoder.decode(buffer); -+ if (decoded == null) -+ throw new EncodingException("invalid string encoding"); -+ -+ huffmanDecoder.reset(); -+ return decoded; -+ } -+ -+ public static int decodeInt(ByteBuffer buffer, int prefix) throws EncodingException -+ { -+ // This is a fix for HPACK as it already takes the first byte of the encoded integer. -+ if (prefix != 8) -+ buffer.position(buffer.position() - 1); -+ -+ NBitIntegerDecoder decoder = new NBitIntegerDecoder(); -+ decoder.setPrefix(prefix); -+ int decodedInt = decoder.decodeInt(buffer); -+ if (decodedInt < 0) -+ throw new EncodingException("invalid integer encoding"); -+ decoder.reset(); -+ return decodedInt; -+ } - - @Test - public void testStaticName() -@@ -428,10 +457,10 @@ public class HpackContextTest - int huff = 0xff & buffer.get(); - assertTrue((0x80 & huff) == 0x80); - -- int len = NBitInteger.decode(buffer, 7); -+ int len = decodeInt(buffer, 7); - - assertEquals(len, buffer.remaining()); -- String value = Huffman.decode(buffer); -+ String value = decode(buffer, buffer.remaining()); - - assertEquals(entry.getHttpField().getValue(), value); - } -diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java -index 4cc50c5..4d1c347 100644 ---- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java -+++ b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java -@@ -62,7 +62,7 @@ public class HpackDecoderTest - @Test - public void testDecodeD3() throws Exception - { -- HpackDecoder decoder = new HpackDecoder(4096, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); - - // First request - String encoded = "828684410f7777772e6578616d706c652e636f6d"; -@@ -110,7 +110,7 @@ public class HpackDecoderTest - @Test - public void testDecodeD4() throws Exception - { -- HpackDecoder decoder = new HpackDecoder(4096, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); - - // First request - String encoded = "828684418cf1e3c2e5f23a6ba0ab90f4ff"; -@@ -145,7 +145,7 @@ public class HpackDecoderTest - { - String value = "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="; - -- HpackDecoder decoder = new HpackDecoder(4096, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); - String encoded = "8682418cF1E3C2E5F23a6bA0Ab90F4Ff841f0822426173696320515778685a475270626a70766347567549484e6c633246745a513d3d"; - byte[] bytes = TypeUtil.fromHexString(encoded); - byte[] array = new byte[bytes.length + 1]; -@@ -167,7 +167,7 @@ public class HpackDecoderTest - @Test - public void testDecodeHuffmanWithArrayOffset() throws Exception - { -- HpackDecoder decoder = new HpackDecoder(4096, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); - - String encoded = "8286418cf1e3c2e5f23a6ba0ab90f4ff84"; - byte[] bytes = TypeUtil.fromHexString(encoded); -@@ -191,7 +191,7 @@ public class HpackDecoderTest - String encoded = "886196C361Be940b6a65B6850400B8A00571972e080a62D1Bf5f87497cA589D34d1f9a0f0d0234327690Aa69D29aFcA954D3A5358980Ae112e0f7c880aE152A9A74a6bF3"; - ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); - -- HpackDecoder decoder = new HpackDecoder(4096, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); - MetaData.Response response = (MetaData.Response)decoder.decode(buffer); - - assertThat(response.getStatus(), is(200)); -@@ -209,7 +209,7 @@ public class HpackDecoderTest - { - String encoded = "203f136687A0E41d139d090760881c6490B2Cd39Ba7f"; - ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); -- HpackDecoder decoder = new HpackDecoder(4096, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); - MetaData metaData = decoder.decode(buffer); - assertThat(metaData.getFields().get(HttpHeader.HOST), is("localhost0")); - assertThat(metaData.getFields().get(HttpHeader.COOKIE), is("abcdefghij")); -@@ -231,7 +231,7 @@ public class HpackDecoderTest - - String encoded = "203f136687A0E41d139d090760881c6490B2Cd39Ba7f20"; - ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); -- HpackDecoder decoder = new HpackDecoder(4096, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); - try - { - decoder.decode(buffer); -@@ -249,7 +249,8 @@ public class HpackDecoderTest - String encoded = "3f610f17FfEc02Df3990A190A0D4Ee5b3d2940Ec98Aa4a62D127D29e273a0aA20dEcAa190a503b262d8a2671D4A2672a927aA874988a2471D05510750c951139EdA2452a3a548cAa1aA90bE4B228342864A9E0D450A5474a92992a1aA513395448E3A0Aa17B96cFe3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f14E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F353F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F54f"; - ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); - -- HpackDecoder decoder = new HpackDecoder(128, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); -+ decoder.setMaxTableCapacity(128); - MetaData metaData = decoder.decode(buffer); - - assertThat(decoder.getHpackContext().getDynamicTableSize(), is(0)); -@@ -262,7 +263,8 @@ public class HpackDecoderTest - String encoded = "BE"; - ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); - -- HpackDecoder decoder = new HpackDecoder(128, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); -+ decoder.setMaxTableCapacity(128); - - try - { -@@ -447,7 +449,7 @@ public class HpackDecoderTest - @Test - public void testHuffmanEncodedStandard() throws Exception - { -- HpackDecoder decoder = new HpackDecoder(4096, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); - - String encoded = "82868441" + "83" + "49509F"; - ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); -@@ -465,68 +467,68 @@ public class HpackDecoderTest - @Test - public void testHuffmanEncodedExtraPadding() - { -- HpackDecoder decoder = new HpackDecoder(4096, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); - - String encoded = "82868441" + "84" + "49509FFF"; - ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); - CompressionException ex = assertThrows(CompressionException.class, () -> decoder.decode(buffer)); -- assertThat(ex.getMessage(), Matchers.containsString("Bad termination")); -+ assertThat(ex.getMessage(), Matchers.containsString("bad_termination")); - } - - /* 5.2.2: Sends a Huffman-encoded string literal representation padded by zero */ - @Test - public void testHuffmanEncodedZeroPadding() - { -- HpackDecoder decoder = new HpackDecoder(4096, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); - - String encoded = "82868441" + "83" + "495090"; - ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); - - CompressionException ex = assertThrows(CompressionException.class, () -> decoder.decode(buffer)); -- assertThat(ex.getMessage(), Matchers.containsString("Incorrect padding")); -+ assertThat(ex.getMessage(), Matchers.containsString("incorrect_padding")); - } - - /* 5.2.3: Sends a Huffman-encoded string literal representation containing the EOS symbol */ - @Test - public void testHuffmanEncodedWithEOS() - { -- HpackDecoder decoder = new HpackDecoder(4096, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); - - String encoded = "82868441" + "87" + "497FFFFFFF427F"; - ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); - - CompressionException ex = assertThrows(CompressionException.class, () -> decoder.decode(buffer)); -- assertThat(ex.getMessage(), Matchers.containsString("EOS in content")); -+ assertThat(ex.getMessage(), Matchers.containsString("eos_in_content")); - } - - @Test - public void testHuffmanEncodedOneIncompleteOctet() - { -- HpackDecoder decoder = new HpackDecoder(4096, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); - - String encoded = "82868441" + "81" + "FE"; - ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); - - CompressionException ex = assertThrows(CompressionException.class, () -> decoder.decode(buffer)); -- assertThat(ex.getMessage(), Matchers.containsString("Bad termination")); -+ assertThat(ex.getMessage(), Matchers.containsString("bad_termination")); - } - - @Test - public void testHuffmanEncodedTwoIncompleteOctet() - { -- HpackDecoder decoder = new HpackDecoder(4096, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); - - String encoded = "82868441" + "82" + "FFFE"; - ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); - - CompressionException ex = assertThrows(CompressionException.class, () -> decoder.decode(buffer)); -- assertThat(ex.getMessage(), Matchers.containsString("Bad termination")); -+ assertThat(ex.getMessage(), Matchers.containsString("bad_termination")); - } - - @Test - public void testZeroLengthName() - { -- HpackDecoder decoder = new HpackDecoder(4096, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); - - String encoded = "00000130"; - ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); -@@ -537,7 +539,7 @@ public class HpackDecoderTest - @Test - public void testZeroLengthValue() throws Exception - { -- HpackDecoder decoder = new HpackDecoder(4096, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); - - String encoded = "00016800"; - ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); -@@ -549,7 +551,7 @@ public class HpackDecoderTest - @Test - public void testUpperCaseName() - { -- HpackDecoder decoder = new HpackDecoder(4096, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); - - String encoded = "0001480130"; - ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); -@@ -560,7 +562,7 @@ public class HpackDecoderTest - @Test - public void testWhiteSpaceName() - { -- HpackDecoder decoder = new HpackDecoder(4096, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); - - String encoded = "0001200130"; - ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); -diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackEncoderTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackEncoderTest.java -index a46f297..d99a20d 100644 ---- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackEncoderTest.java -+++ b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackEncoderTest.java -@@ -38,7 +38,7 @@ public class HpackEncoderTest - @Test - public void testUnknownFieldsContextManagement() throws Exception - { -- HpackEncoder encoder = new HpackEncoder(38 * 5); -+ HpackEncoder encoder = newHpackEncoder(38 * 5); - HttpFields fields = new HttpFields(); - - HttpField[] field = -@@ -149,8 +149,9 @@ public class HpackEncoderTest - @Test - public void testLargeFieldsNotIndexed() - { -- HpackEncoder encoder = new HpackEncoder(38 * 5); -+ HpackEncoder encoder = newHpackEncoder(38 * 5); - HpackContext ctx = encoder.getHpackContext(); -+ ctx.resize(encoder.getMaxTableCapacity()); - - ByteBuffer buffer = BufferUtil.allocate(4096); - -@@ -175,8 +176,9 @@ public class HpackEncoderTest - @Test - public void testIndexContentLength() - { -- HpackEncoder encoder = new HpackEncoder(38 * 5); -+ HpackEncoder encoder = newHpackEncoder(38 * 5); - HpackContext ctx = encoder.getHpackContext(); -+ ctx.resize(encoder.getMaxTableCapacity()); - - ByteBuffer buffer = BufferUtil.allocate(4096); - -@@ -197,7 +199,7 @@ public class HpackEncoderTest - @Test - public void testNeverIndexSetCookie() throws Exception - { -- HpackEncoder encoder = new HpackEncoder(38 * 5); -+ HpackEncoder encoder = newHpackEncoder(38 * 5); - ByteBuffer buffer = BufferUtil.allocate(4096); - - HttpFields fields = new HttpFields(); -@@ -231,20 +233,20 @@ public class HpackEncoderTest - { - HttpFields fields = new HttpFields(); - -- HpackEncoder encoder = new HpackEncoder(128); -+ HpackEncoder encoder = newHpackEncoder(128); - ByteBuffer buffer0 = BufferUtil.allocate(4096); - int pos = BufferUtil.flipToFill(buffer0); - encoder.encode(buffer0, new MetaData(HttpVersion.HTTP_2, fields)); - BufferUtil.flipToFlush(buffer0, pos); - -- encoder = new HpackEncoder(128); -+ encoder = newHpackEncoder(128); - fields.add(new HttpField("user-agent", "jetty/test")); - ByteBuffer buffer1 = BufferUtil.allocate(4096); - pos = BufferUtil.flipToFill(buffer1); - encoder.encode(buffer1, new MetaData(HttpVersion.HTTP_2, fields)); - BufferUtil.flipToFlush(buffer1, pos); - -- encoder = new HpackEncoder(128); -+ encoder = newHpackEncoder(128); - encoder.setValidateEncoding(false); - fields.add(new HttpField(":path", - "This is a very large field, whose size is larger than the dynamic table so it should not be indexed as it will not fit in the table ever!" + -@@ -256,7 +258,7 @@ public class HpackEncoderTest - encoder.encode(buffer2, new MetaData(HttpVersion.HTTP_2, fields)); - BufferUtil.flipToFlush(buffer2, pos); - -- encoder = new HpackEncoder(128); -+ encoder = newHpackEncoder(128); - encoder.setValidateEncoding(false); - fields.add(new HttpField("host", "somehost")); - ByteBuffer buffer = BufferUtil.allocate(4096); -@@ -297,12 +299,12 @@ public class HpackEncoderTest - fields.add("host", "localhost0"); - fields.add("cookie", "abcdefghij"); - -- HpackEncoder encoder = new HpackEncoder(4096); -+ HpackEncoder encoder = newHpackEncoder(4096); - - ByteBuffer buffer = BufferUtil.allocate(4096); - int pos = BufferUtil.flipToFill(buffer); - encoder.encodeMaxDynamicTableSize(buffer, 0); -- encoder.setRemoteMaxDynamicTableSize(50); -+ encoder.setTableCapacity(50); - encoder.encode(buffer, new MetaData(HttpVersion.HTTP_2, fields)); - BufferUtil.flipToFlush(buffer, pos); - -@@ -311,4 +313,12 @@ public class HpackEncoderTest - assertThat(context.getMaxDynamicTableSize(), Matchers.is(50)); - assertThat(context.size(), Matchers.is(1)); - } -+ -+ private static HpackEncoder newHpackEncoder(int tableCapacity) -+ { -+ HpackEncoder encoder = new HpackEncoder(); -+ encoder.setMaxTableCapacity(tableCapacity); -+ encoder.setTableCapacity(tableCapacity); -+ return encoder; -+ } - } -diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackPerfTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackPerfTest.java -index e31f5bf..dd51b4b 100644 ---- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackPerfTest.java -+++ b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackPerfTest.java -@@ -37,7 +37,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; - - public class HpackPerfTest - { -- int _maxDynamicTableSize = 4 * 1024; -+ int _tableCapacity = 4 * 1024; - int _unencodedSize; - int _encodedSize; - -@@ -51,7 +51,7 @@ public class HpackPerfTest - @AfterEach - public void after() - { -- System.err.printf("dynamictable=%d unencoded=%d encoded=%d p=%3.1f%%%n", _maxDynamicTableSize, _unencodedSize, _encodedSize, 100.0 * _encodedSize / _unencodedSize); -+ System.err.printf("dynamictable=%d unencoded=%d encoded=%d p=%3.1f%%%n", _tableCapacity, _unencodedSize, _encodedSize, 100.0 * _encodedSize / _unencodedSize); - } - - @Test -@@ -68,11 +68,14 @@ public class HpackPerfTest - assertNotNull(files); - - // Parse JSON -- Map[] stories = new Map[files.length]; -+ @SuppressWarnings("unchecked") -+ Map[] stories = new Map[files.length]; - int i = 0; -- for (String story : files) -+ for (String file : files) - { -- stories[i++] = (Map)JSON.parse(new FileReader(new File(data, story))); -+ @SuppressWarnings("unchecked") -+ Map story = (Map)JSON.parse(new FileReader(new File(data, file))); -+ stories[i++] = story; - } - - ByteBuffer buffer = BufferUtil.allocate(256 * 1024); -@@ -88,27 +91,29 @@ public class HpackPerfTest - encodeStories(buffer, stories, "response"); - } - -- private void encodeStories(ByteBuffer buffer, Map[] stories, String type) throws Exception -+ private void encodeStories(ByteBuffer buffer, Map[] stories, String type) throws Exception - { -- for (Map story : stories) -+ for (Map story : stories) - { - if (type.equals(story.get("context"))) - { -- HpackEncoder encoder = new HpackEncoder(_maxDynamicTableSize, _maxDynamicTableSize); -+ HpackEncoder encoder = new HpackEncoder(); -+ encoder.setMaxTableCapacity(_tableCapacity); -+ encoder.setTableCapacity(_tableCapacity); - encoder.setValidateEncoding(false); - -- // System.err.println(story); - Object[] cases = (Object[])story.get("cases"); - for (Object c : cases) - { -- // System.err.println(" "+c); -- Object[] headers = (Object[])((Map)c).get("headers"); -+ @SuppressWarnings("unchecked") -+ Map kase = (Map)c; -+ Object[] headers = (Object[])kase.get("headers"); - // System.err.println(" "+headers); - HttpFields fields = new HttpFields(); - for (Object header : headers) - { - @SuppressWarnings("unchecked") -- Map h = (Map)header; -+ Map h = (Map)header; - Map.Entry e = h.entrySet().iterator().next(); - fields.add(e.getKey(), e.getValue()); - _unencodedSize += e.getKey().length() + e.getValue().length(); -diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackTest.java -index 72155e5..b6115c6 100644 ---- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackTest.java -+++ b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackTest.java -@@ -19,7 +19,6 @@ - package org.eclipse.jetty.http2.hpack; - - import java.nio.ByteBuffer; --import java.util.concurrent.TimeUnit; - - import org.eclipse.jetty.http.DateGenerator; - import org.eclipse.jetty.http.HttpField; -@@ -43,13 +42,13 @@ public class HpackTest - { - static final HttpField ServerJetty = new PreEncodedHttpField(HttpHeader.SERVER, "jetty"); - static final HttpField XPowerJetty = new PreEncodedHttpField(HttpHeader.X_POWERED_BY, "jetty"); -- static final HttpField Date = new PreEncodedHttpField(HttpHeader.DATE, DateGenerator.formatDate(TimeUnit.NANOSECONDS.toMillis(System.nanoTime()))); -+ static final HttpField Date = new PreEncodedHttpField(HttpHeader.DATE, DateGenerator.formatDate(System.currentTimeMillis())); - - @Test - public void encodeDecodeResponseTest() throws Exception - { - HpackEncoder encoder = new HpackEncoder(); -- HpackDecoder decoder = new HpackDecoder(4096, 8192); -+ HpackDecoder decoder = new HpackDecoder(8192); - ByteBuffer buffer = BufferUtil.allocateDirect(16 * 1024); - - HttpFields fields0 = new HttpFields(); -@@ -102,7 +101,7 @@ public class HpackTest - public void encodeDecodeTooLargeTest() throws Exception - { - HpackEncoder encoder = new HpackEncoder(); -- HpackDecoder decoder = new HpackDecoder(4096, 164); -+ HpackDecoder decoder = new HpackDecoder(164); - ByteBuffer buffer = BufferUtil.allocateDirect(16 * 1024); - - HttpFields fields0 = new HttpFields(); -@@ -133,36 +132,40 @@ public class HpackTest - } - catch (HpackException.SessionException e) - { -- assertThat(e.getMessage(), containsString("Header too large")); -+ assertThat(e.getMessage(), containsString("Header size 198 > 164")); - } - } - - @Test -- public void encodeDecodeNonAscii() throws Exception -+ public void encodeNonAscii() throws Exception - { - HpackEncoder encoder = new HpackEncoder(); -- HpackDecoder decoder = new HpackDecoder(4096, 8192); - ByteBuffer buffer = BufferUtil.allocate(16 * 1024); - - HttpFields fields0 = new HttpFields(); -- // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck -+ // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck - fields0.add("Cookie", "[\uD842\uDF9F]"); - fields0.add("custom-key", "[\uD842\uDF9F]"); - Response original0 = new MetaData.Response(HttpVersion.HTTP_2, 200, fields0); - -- BufferUtil.clearToFill(buffer); -- encoder.encode(buffer, original0); -- BufferUtil.flipToFlush(buffer, 0); -- Response decoded0 = (Response)decoder.decode(buffer); -+ HpackException.SessionException throwable = assertThrows(HpackException.SessionException.class, () -> -+ { -+ BufferUtil.clearToFill(buffer); -+ encoder.encode(buffer, original0); -+ BufferUtil.flipToFlush(buffer, 0); -+ }); - -- assertMetaDataSame(original0, decoded0); -+ assertThat(throwable.getMessage(), containsString("Could not hpack encode")); - } -- -+ - @Test - public void evictReferencedFieldTest() throws Exception - { -- HpackEncoder encoder = new HpackEncoder(200, 200); -- HpackDecoder decoder = new HpackDecoder(200, 1024); -+ HpackDecoder decoder = new HpackDecoder(1024); -+ decoder.setMaxTableCapacity(200); -+ HpackEncoder encoder = new HpackEncoder(); -+ encoder.setMaxTableCapacity(decoder.getMaxTableCapacity()); -+ encoder.setTableCapacity(decoder.getMaxTableCapacity()); - ByteBuffer buffer = BufferUtil.allocateDirect(16 * 1024); - - String longEnoughToBeEvicted = "012345678901234567890123456789012345678901234567890"; -@@ -205,7 +208,7 @@ public class HpackTest - public void testHopHeadersAreRemoved() throws Exception - { - HpackEncoder encoder = new HpackEncoder(); -- HpackDecoder decoder = new HpackDecoder(4096, 16384); -+ HpackDecoder decoder = new HpackDecoder(16384); - - HttpFields input = new HttpFields(); - input.put(HttpHeader.ACCEPT, "*"); -@@ -232,14 +235,14 @@ public class HpackTest - public void testTETrailers() throws Exception - { - HpackEncoder encoder = new HpackEncoder(); -- HpackDecoder decoder = new HpackDecoder(4096, 16384); -+ HpackDecoder decoder = new HpackDecoder(16384); - -- HttpFields input = new HttpFields(); -- input.put(HttpHeader.CONNECTION, "TE"); - String teValue = "trailers"; -- input.put(HttpHeader.TE, teValue); - String trailerValue = "Custom"; -- input.put(HttpHeader.TRAILER, trailerValue); -+ HttpFields input = new HttpFields(); -+ input.add(HttpHeader.CONNECTION, "TE"); -+ input.add(HttpHeader.TE, teValue); -+ input.add(HttpHeader.TRAILER, trailerValue); - - ByteBuffer buffer = BufferUtil.allocate(2048); - BufferUtil.clearToFill(buffer); -@@ -257,7 +260,7 @@ public class HpackTest - public void testColonHeaders() throws Exception - { - HpackEncoder encoder = new HpackEncoder(); -- HpackDecoder decoder = new HpackDecoder(4096, 16384); -+ HpackDecoder decoder = new HpackDecoder(16384); - - HttpFields input = new HttpFields(); - input.put(":status", "200"); -diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java -deleted file mode 100644 -index 1b62829..0000000 ---- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java -+++ /dev/null -@@ -1,87 +0,0 @@ --// --// ======================================================================== --// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. --// ------------------------------------------------------------------------ --// 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.http2.hpack; -- --import java.nio.BufferOverflowException; --import java.nio.ByteBuffer; --import java.util.Locale; --import java.util.stream.Stream; -- --import org.eclipse.jetty.util.BufferUtil; --import org.eclipse.jetty.util.TypeUtil; --import org.hamcrest.Matchers; --import org.junit.jupiter.params.ParameterizedTest; --import org.junit.jupiter.params.provider.Arguments; --import org.junit.jupiter.params.provider.MethodSource; --import org.junit.jupiter.params.provider.ValueSource; -- --import static org.hamcrest.MatcherAssert.assertThat; --import static org.junit.jupiter.api.Assertions.assertEquals; --import static org.junit.jupiter.api.Assertions.assertThrows; -- --public class HuffmanTest --{ -- public static Stream data() -- { -- return Stream.of( -- new String[][]{ -- {"D.4.1", "f1e3c2e5f23a6ba0ab90f4ff", "www.example.com"}, -- {"D.4.2", "a8eb10649cbf", "no-cache"}, -- {"D.6.1k", "6402", "302"}, -- {"D.6.1v", "aec3771a4b", "private"}, -- {"D.6.1d", "d07abe941054d444a8200595040b8166e082a62d1bff", "Mon, 21 Oct 2013 20:13:21 GMT"}, -- {"D.6.1l", "9d29ad171863c78f0b97c8e9ae82ae43d3", "https://www.example.com"}, -- {"D.6.2te", "640cff", "303"}, -- }).map(Arguments::of); -- } -- -- @ParameterizedTest(name = "[{index}] spec={0}") -- @MethodSource("data") -- public void testDecode(String specSection, String hex, String expected) throws Exception -- { -- byte[] encoded = TypeUtil.fromHexString(hex); -- String decoded = Huffman.decode(ByteBuffer.wrap(encoded)); -- assertEquals(expected, decoded, specSection); -- } -- -- @ParameterizedTest(name = "[{index}] spec={0}") -- @MethodSource("data") -- public void testEncode(String specSection, String hex, String expected) -- { -- ByteBuffer buf = BufferUtil.allocate(1024); -- int pos = BufferUtil.flipToFill(buf); -- Huffman.encode(buf, expected); -- BufferUtil.flipToFlush(buf, pos); -- String encoded = TypeUtil.toHexString(BufferUtil.toArray(buf)).toLowerCase(Locale.ENGLISH); -- assertEquals(hex, encoded, specSection); -- assertEquals(hex.length() / 2, Huffman.octetsNeeded(expected)); -- } -- -- @ParameterizedTest(name = "[{index}]") // don't include unprintable character in test display-name -- @ValueSource(chars = {(char)128, (char)0, (char)-1, ' ' - 1}) -- public void testEncode8859Only(char bad) -- { -- String s = "bad '" + bad + "'"; -- -- assertThat(Huffman.octetsNeeded(s), Matchers.is(-1)); -- -- assertThrows(BufferOverflowException.class, -- () -> Huffman.encode(BufferUtil.allocate(32), s)); -- } --} -diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/NBitIntegerTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/NBitIntegerTest.java -deleted file mode 100644 -index 8435311..0000000 ---- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/NBitIntegerTest.java -+++ /dev/null -@@ -1,204 +0,0 @@ --// --// ======================================================================== --// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. --// ------------------------------------------------------------------------ --// 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.http2.hpack; -- --import java.nio.ByteBuffer; -- --import org.eclipse.jetty.util.BufferUtil; --import org.eclipse.jetty.util.TypeUtil; --import org.junit.jupiter.api.Test; -- --import static org.junit.jupiter.api.Assertions.assertEquals; -- --public class NBitIntegerTest --{ -- -- @Test -- public void testOctetsNeeded() -- { -- assertEquals(0, NBitInteger.octectsNeeded(5, 10)); -- assertEquals(2, NBitInteger.octectsNeeded(5, 1337)); -- assertEquals(1, NBitInteger.octectsNeeded(8, 42)); -- assertEquals(3, NBitInteger.octectsNeeded(8, 1337)); -- -- assertEquals(0, NBitInteger.octectsNeeded(6, 62)); -- assertEquals(1, NBitInteger.octectsNeeded(6, 63)); -- assertEquals(1, NBitInteger.octectsNeeded(6, 64)); -- assertEquals(2, NBitInteger.octectsNeeded(6, 63 + 0x00 + 0x80 * 0x01)); -- assertEquals(3, NBitInteger.octectsNeeded(6, 63 + 0x00 + 0x80 * 0x80)); -- assertEquals(4, NBitInteger.octectsNeeded(6, 63 + 0x00 + 0x80 * 0x80 * 0x80)); -- } -- -- @Test -- public void testEncode() -- { -- testEncode(6, 0, "00"); -- testEncode(6, 1, "01"); -- testEncode(6, 62, "3e"); -- testEncode(6, 63, "3f00"); -- testEncode(6, 63 + 1, "3f01"); -- testEncode(6, 63 + 0x7e, "3f7e"); -- testEncode(6, 63 + 0x7f, "3f7f"); -- testEncode(6, 63 + 0x00 + 0x80 * 0x01, "3f8001"); -- testEncode(6, 63 + 0x01 + 0x80 * 0x01, "3f8101"); -- testEncode(6, 63 + 0x7f + 0x80 * 0x01, "3fFf01"); -- testEncode(6, 63 + 0x00 + 0x80 * 0x02, "3f8002"); -- testEncode(6, 63 + 0x01 + 0x80 * 0x02, "3f8102"); -- testEncode(6, 63 + 0x7f + 0x80 * 0x7f, "3fFf7f"); -- testEncode(6, 63 + 0x00 + 0x80 * 0x80, "3f808001"); -- testEncode(6, 63 + 0x7f + 0x80 * 0x80 * 0x7f, "3fFf807f"); -- testEncode(6, 63 + 0x00 + 0x80 * 0x80 * 0x80, "3f80808001"); -- -- testEncode(8, 0, "00"); -- testEncode(8, 1, "01"); -- testEncode(8, 128, "80"); -- testEncode(8, 254, "Fe"); -- testEncode(8, 255, "Ff00"); -- testEncode(8, 255 + 1, "Ff01"); -- testEncode(8, 255 + 0x7e, "Ff7e"); -- testEncode(8, 255 + 0x7f, "Ff7f"); -- testEncode(8, 255 + 0x80, "Ff8001"); -- testEncode(8, 255 + 0x00 + 0x80 * 0x80, "Ff808001"); -- } -- -- public void testEncode(int n, int i, String expected) -- { -- ByteBuffer buf = BufferUtil.allocate(16); -- int p = BufferUtil.flipToFill(buf); -- if (n < 8) -- buf.put((byte)0x00); -- NBitInteger.encode(buf, n, i); -- BufferUtil.flipToFlush(buf, p); -- String r = TypeUtil.toHexString(BufferUtil.toArray(buf)); -- assertEquals(expected, r); -- -- assertEquals(expected.length() / 2, (n < 8 ? 1 : 0) + NBitInteger.octectsNeeded(n, i)); -- } -- -- @Test -- public void testDecode() -- { -- testDecode(6, 0, "00"); -- testDecode(6, 1, "01"); -- testDecode(6, 62, "3e"); -- testDecode(6, 63, "3f00"); -- testDecode(6, 63 + 1, "3f01"); -- testDecode(6, 63 + 0x7e, "3f7e"); -- testDecode(6, 63 + 0x7f, "3f7f"); -- testDecode(6, 63 + 0x80, "3f8001"); -- testDecode(6, 63 + 0x81, "3f8101"); -- testDecode(6, 63 + 0x7f + 0x80 * 0x01, "3fFf01"); -- testDecode(6, 63 + 0x00 + 0x80 * 0x02, "3f8002"); -- testDecode(6, 63 + 0x01 + 0x80 * 0x02, "3f8102"); -- testDecode(6, 63 + 0x7f + 0x80 * 0x7f, "3fFf7f"); -- testDecode(6, 63 + 0x00 + 0x80 * 0x80, "3f808001"); -- testDecode(6, 63 + 0x7f + 0x80 * 0x80 * 0x7f, "3fFf807f"); -- testDecode(6, 63 + 0x00 + 0x80 * 0x80 * 0x80, "3f80808001"); -- -- testDecode(8, 0, "00"); -- testDecode(8, 1, "01"); -- testDecode(8, 128, "80"); -- testDecode(8, 254, "Fe"); -- testDecode(8, 255, "Ff00"); -- testDecode(8, 255 + 1, "Ff01"); -- testDecode(8, 255 + 0x7e, "Ff7e"); -- testDecode(8, 255 + 0x7f, "Ff7f"); -- testDecode(8, 255 + 0x80, "Ff8001"); -- testDecode(8, 255 + 0x00 + 0x80 * 0x80, "Ff808001"); -- } -- -- public void testDecode(int n, int expected, String encoded) -- { -- ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); -- buf.position(n == 8 ? 0 : 1); -- assertEquals(expected, NBitInteger.decode(buf, n)); -- } -- -- @Test -- public void testEncodeExampleD11() -- { -- ByteBuffer buf = BufferUtil.allocate(16); -- int p = BufferUtil.flipToFill(buf); -- buf.put((byte)0x77); -- buf.put((byte)0xFF); -- NBitInteger.encode(buf, 5, 10); -- BufferUtil.flipToFlush(buf, p); -- -- String r = TypeUtil.toHexString(BufferUtil.toArray(buf)); -- -- assertEquals("77Ea", r); -- } -- -- @Test -- public void testDecodeExampleD11() -- { -- ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("77EaFF")); -- buf.position(2); -- -- assertEquals(10, NBitInteger.decode(buf, 5)); -- } -- -- @Test -- public void testEncodeExampleD12() -- { -- ByteBuffer buf = BufferUtil.allocate(16); -- int p = BufferUtil.flipToFill(buf); -- buf.put((byte)0x88); -- buf.put((byte)0x00); -- NBitInteger.encode(buf, 5, 1337); -- BufferUtil.flipToFlush(buf, p); -- -- String r = TypeUtil.toHexString(BufferUtil.toArray(buf)); -- -- assertEquals("881f9a0a", r); -- } -- -- @Test -- public void testDecodeExampleD12() -- { -- ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("881f9a0aff")); -- buf.position(2); -- -- assertEquals(1337, NBitInteger.decode(buf, 5)); -- } -- -- @Test -- public void testEncodeExampleD13() -- { -- ByteBuffer buf = BufferUtil.allocate(16); -- int p = BufferUtil.flipToFill(buf); -- buf.put((byte)0x88); -- buf.put((byte)0xFF); -- NBitInteger.encode(buf, 8, 42); -- BufferUtil.flipToFlush(buf, p); -- -- String r = TypeUtil.toHexString(BufferUtil.toArray(buf)); -- -- assertEquals("88Ff2a", r); -- } -- -- @Test -- public void testDecodeExampleD13() -- { -- ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("882aFf")); -- buf.position(1); -- -- assertEquals(42, NBitInteger.decode(buf, 8)); -- } --} -diff --git a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java -index c596873..e7fd5e1 100644 ---- a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java -+++ b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java -@@ -36,7 +36,6 @@ import java.util.concurrent.TimeUnit; - import java.util.concurrent.TimeoutException; - import java.util.concurrent.atomic.AtomicInteger; - import java.util.concurrent.atomic.AtomicReference; --import java.util.function.UnaryOperator; - import javax.servlet.http.HttpServletRequest; - import javax.servlet.http.HttpServletResponse; - -@@ -62,7 +61,6 @@ import org.eclipse.jetty.http2.frames.ResetFrame; - import org.eclipse.jetty.http2.frames.SettingsFrame; - import org.eclipse.jetty.http2.generator.Generator; - import org.eclipse.jetty.http2.hpack.HpackException; --import org.eclipse.jetty.http2.parser.RateControl; - import org.eclipse.jetty.http2.parser.ServerParser; - import org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory; - import org.eclipse.jetty.io.ByteBufferPool; -@@ -456,7 +454,8 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest - OutputStream output = socket.getOutputStream(); - InputStream input = socket.getInputStream(); - -- ServerParser parser = new ServerParser(byteBufferPool, new ServerParser.Listener.Adapter() -+ ServerParser parser = new ServerParser(byteBufferPool, 4096); -+ parser.init(new ServerParser.Listener.Adapter() - { - @Override - public void onPreface() -@@ -508,8 +507,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest - x.printStackTrace(); - } - } -- }, 4096, 8192, RateControl.NO_RATE_CONTROL); -- parser.init(UnaryOperator.identity()); -+ }); - - byte[] bytes = new byte[1024]; - while (true) -diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java -index 554ecfd..5ac9cc5 100644 ---- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java -+++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java -@@ -34,6 +34,7 @@ import org.eclipse.jetty.http2.api.server.ServerSessionListener; - import org.eclipse.jetty.http2.frames.Frame; - import org.eclipse.jetty.http2.frames.SettingsFrame; - import org.eclipse.jetty.http2.generator.Generator; -+import org.eclipse.jetty.http2.hpack.HpackContext; - import org.eclipse.jetty.http2.parser.RateControl; - import org.eclipse.jetty.http2.parser.ServerParser; - import org.eclipse.jetty.http2.parser.WindowRateControl; -@@ -53,12 +54,13 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne - { - private final HTTP2SessionContainer sessionContainer = new HTTP2SessionContainer(); - private final HttpConfiguration httpConfiguration; -- private int maxDynamicTableSize = 4096; -+ private int maxDecoderTableCapacity = HpackContext.DEFAULT_MAX_TABLE_CAPACITY; -+ private int maxEncoderTableCapacity = HpackContext.DEFAULT_MAX_TABLE_CAPACITY; - private int initialSessionRecvWindow = 1024 * 1024; - private int initialStreamRecvWindow = 512 * 1024; - private int maxConcurrentStreams = 128; - private int maxHeaderBlockFragment = 0; -- private int maxFrameLength = Frame.DEFAULT_MAX_LENGTH; -+ private int maxFrameSize = Frame.DEFAULT_MAX_LENGTH; - private int maxSettingsKeys = SettingsFrame.DEFAULT_MAX_KEYS; - private RateControl.Factory rateControlFactory = new WindowRateControl.Factory(128); - private FlowControlStrategy.Factory flowControlStrategyFactory = () -> new BufferingFlowControlStrategy(0.5F); -@@ -83,15 +85,45 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne - setInputBufferSize(Frame.DEFAULT_MAX_LENGTH + Frame.HEADER_LENGTH); - } - -+ @Deprecated - @ManagedAttribute("The HPACK dynamic table maximum size") - public int getMaxDynamicTableSize() - { -- return maxDynamicTableSize; -+ return getMaxDecoderTableCapacity(); - } - -+ @Deprecated - public void setMaxDynamicTableSize(int maxDynamicTableSize) - { -- this.maxDynamicTableSize = maxDynamicTableSize; -+ setMaxDecoderTableCapacity(maxDynamicTableSize); -+ } -+ -+ @ManagedAttribute("The HPACK encoder dynamic table maximum capacity") -+ public int getMaxEncoderTableCapacity() -+ { -+ return maxEncoderTableCapacity; -+ } -+ -+ /** -+ *

Sets the limit for the encoder HPACK dynamic table capacity.

-+ *

Setting this value to {@code 0} disables the use of the dynamic table.

-+ * -+ * @param maxEncoderTableCapacity The HPACK encoder dynamic table maximum capacity -+ */ -+ public void setMaxEncoderTableCapacity(int maxEncoderTableCapacity) -+ { -+ this.maxEncoderTableCapacity = maxEncoderTableCapacity; -+ } -+ -+ @ManagedAttribute("The HPACK decoder dynamic table maximum capacity") -+ public int getMaxDecoderTableCapacity() -+ { -+ return maxDecoderTableCapacity; -+ } -+ -+ public void setMaxDecoderTableCapacity(int maxDecoderTableCapacity) -+ { -+ this.maxDecoderTableCapacity = maxDecoderTableCapacity; - } - - @ManagedAttribute("The initial size of session's flow control receive window") -@@ -159,15 +191,28 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne - this.streamIdleTimeout = streamIdleTimeout; - } - -+ @Deprecated - @ManagedAttribute("The max frame length in bytes") - public int getMaxFrameLength() - { -- return maxFrameLength; -+ return getMaxFrameSize(); - } - -+ @Deprecated - public void setMaxFrameLength(int maxFrameLength) - { -- this.maxFrameLength = maxFrameLength; -+ setMaxFrameSize(maxFrameLength); -+ } -+ -+ @ManagedAttribute("The max frame size in bytes") -+ public int getMaxFrameSize() -+ { -+ return maxFrameSize; -+ } -+ -+ public void setMaxFrameSize(int maxFrameSize) -+ { -+ this.maxFrameSize = maxFrameSize; - } - - @ManagedAttribute("The max number of keys in all SETTINGS frames") -@@ -267,37 +312,47 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne - { - ServerSessionListener listener = newSessionListener(connector, endPoint); - -- Generator generator = new Generator(connector.getByteBufferPool(), getMaxDynamicTableSize(), getMaxHeaderBlockFragment()); -+ Generator generator = new Generator(connector.getByteBufferPool(), getMaxHeaderBlockFragment()); - FlowControlStrategy flowControl = getFlowControlStrategyFactory().newFlowControlStrategy(); -- HTTP2ServerSession session = new HTTP2ServerSession(connector.getScheduler(), endPoint, generator, listener, flowControl); -+ -+ ServerParser parser = newServerParser(connector, getRateControlFactory().newRateControl(endPoint)); -+ parser.setMaxFrameSize(getMaxFrameSize()); -+ parser.setMaxSettingsKeys(getMaxSettingsKeys()); -+ -+ HTTP2ServerSession session = new HTTP2ServerSession(connector.getScheduler(), endPoint, parser, generator, listener, flowControl); - session.setMaxLocalStreams(getMaxConcurrentStreams()); - session.setMaxRemoteStreams(getMaxConcurrentStreams()); -+ session.setMaxEncoderTableCapacity(getMaxEncoderTableCapacity()); - // For a single stream in a connection, there will be a race between - // the stream idle timeout and the connection idle timeout. However, - // the typical case is that the connection will be busier and the - // stream idle timeout will expire earlier than the connection's. - long streamIdleTimeout = getStreamIdleTimeout(); -- if (streamIdleTimeout <= 0) -+ if (streamIdleTimeout == 0) - streamIdleTimeout = endPoint.getIdleTimeout(); - session.setStreamIdleTimeout(streamIdleTimeout); - session.setInitialSessionRecvWindow(getInitialSessionRecvWindow()); - session.setWriteThreshold(getHttpConfiguration().getOutputBufferSize()); - -- ServerParser parser = newServerParser(connector, session, getRateControlFactory().newRateControl(endPoint)); -- parser.setMaxFrameLength(getMaxFrameLength()); -- parser.setMaxSettingsKeys(getMaxSettingsKeys()); -- - HTTP2Connection connection = new HTTP2ServerConnection(connector.getByteBufferPool(), connector.getExecutor(), -- endPoint, httpConfiguration, parser, session, getInputBufferSize(), listener); -+ endPoint, httpConfiguration, session, getInputBufferSize(), listener); - connection.addListener(sessionContainer); -+ parser.init(connection.wrapParserListener(session)); -+ - return configure(connection, connector, endPoint); - } - - protected abstract ServerSessionListener newSessionListener(Connector connector, EndPoint endPoint); - -+ @Deprecated - protected ServerParser newServerParser(Connector connector, ServerParser.Listener listener, RateControl rateControl) - { -- return new ServerParser(connector.getByteBufferPool(), listener, getMaxDynamicTableSize(), getHttpConfiguration().getRequestHeaderSize(), rateControl); -+ return newServerParser(connector, rateControl); -+ } -+ -+ protected ServerParser newServerParser(Connector connector, RateControl rateControl) -+ { -+ return new ServerParser(connector.getByteBufferPool(), getHttpConfiguration().getRequestHeaderSize(), rateControl); - } - - @ManagedObject("The container of HTTP/2 sessions") -diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java -index 3974ee6..11c68d4 100644 ---- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java -+++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java -@@ -89,9 +89,15 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection - private final HttpConfiguration httpConfig; - private boolean recycleHttpChannels = true; - -+ @Deprecated - public HTTP2ServerConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, HttpConfiguration httpConfig, ServerParser parser, ISession session, int inputBufferSize, ServerSessionListener listener) - { -- super(byteBufferPool, executor, endPoint, parser, session, inputBufferSize); -+ this(byteBufferPool, executor, endPoint, httpConfig, session, inputBufferSize, listener); -+ } -+ -+ public HTTP2ServerConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, HttpConfiguration httpConfig, ISession session, int inputBufferSize, ServerSessionListener listener) -+ { -+ super(byteBufferPool, executor, endPoint, session, inputBufferSize); - this.listener = listener; - this.httpConfig = httpConfig; - } -diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerSession.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerSession.java -index c0f24d6..8e405b9 100644 ---- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerSession.java -+++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerSession.java -@@ -37,6 +37,7 @@ import org.eclipse.jetty.http2.frames.PushPromiseFrame; - import org.eclipse.jetty.http2.frames.SettingsFrame; - import org.eclipse.jetty.http2.frames.WindowUpdateFrame; - import org.eclipse.jetty.http2.generator.Generator; -+import org.eclipse.jetty.http2.parser.Parser; - import org.eclipse.jetty.http2.parser.ServerParser; - import org.eclipse.jetty.io.EndPoint; - import org.eclipse.jetty.util.Callback; -@@ -50,9 +51,16 @@ public class HTTP2ServerSession extends HTTP2Session implements ServerParser.Lis - - private final ServerSessionListener listener; - -+ @Deprecated - public HTTP2ServerSession(Scheduler scheduler, EndPoint endPoint, Generator generator, ServerSessionListener listener, FlowControlStrategy flowControl) - { -- super(scheduler, endPoint, generator, listener, flowControl, 2); -+ this(scheduler, endPoint, null, generator, listener, flowControl); -+ throw new UnsupportedOperationException(); -+ } -+ -+ public HTTP2ServerSession(Scheduler scheduler, EndPoint endPoint, Parser parser, Generator generator, ServerSessionListener listener, FlowControlStrategy flowControl) -+ { -+ super(scheduler, endPoint, parser, generator, listener, flowControl, 2); - this.listener = listener; - } - -diff --git a/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/CloseTest.java b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/CloseTest.java -index 04b8a28..41321c0 100644 ---- a/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/CloseTest.java -+++ b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/CloseTest.java -@@ -26,7 +26,6 @@ import java.util.HashMap; - import java.util.concurrent.CountDownLatch; - import java.util.concurrent.TimeUnit; - import java.util.concurrent.atomic.AtomicReference; --import java.util.function.UnaryOperator; - - import org.eclipse.jetty.http.HttpFields; - import org.eclipse.jetty.http.HttpVersion; -@@ -92,7 +91,8 @@ public class CloseTest extends AbstractServerTest - output.write(BufferUtil.toArray(buffer)); - } - -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onHeaders(HeadersFrame frame) -@@ -109,8 +109,7 @@ public class CloseTest extends AbstractServerTest - throw new RuntimeIOException(x); - } - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - parseResponse(client, parser); - -@@ -157,7 +156,8 @@ public class CloseTest extends AbstractServerTest - // Don't close the connection; the server should close. - - final CountDownLatch responseLatch = new CountDownLatch(1); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onHeaders(HeadersFrame frame) -@@ -166,8 +166,7 @@ public class CloseTest extends AbstractServerTest - // HEADERS, the server is able to send us the response. - responseLatch.countDown(); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - parseResponse(client, parser); - -@@ -222,7 +221,8 @@ public class CloseTest extends AbstractServerTest - - final CountDownLatch responseLatch = new CountDownLatch(1); - final CountDownLatch closeLatch = new CountDownLatch(1); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onHeaders(HeadersFrame frame) -@@ -235,8 +235,7 @@ public class CloseTest extends AbstractServerTest - { - closeLatch.countDown(); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - parseResponse(client, parser); - -diff --git a/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2CServerTest.java b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2CServerTest.java -index e4853d7..d1d3e72 100644 ---- a/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2CServerTest.java -+++ b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2CServerTest.java -@@ -30,7 +30,6 @@ import java.util.concurrent.CountDownLatch; - import java.util.concurrent.TimeUnit; - import java.util.concurrent.atomic.AtomicLong; - import java.util.concurrent.atomic.AtomicReference; --import java.util.function.UnaryOperator; - - import org.eclipse.jetty.http.HostPortHttpField; - import org.eclipse.jetty.http.HttpFields; -@@ -152,7 +151,8 @@ public class HTTP2CServerTest extends AbstractServerTest - final AtomicReference headersRef = new AtomicReference<>(); - final AtomicReference dataRef = new AtomicReference<>(); - final AtomicReference latchRef = new AtomicReference<>(new CountDownLatch(2)); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onHeaders(HeadersFrame frame) -@@ -167,8 +167,7 @@ public class HTTP2CServerTest extends AbstractServerTest - dataRef.set(frame); - latchRef.get().countDown(); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - parseResponse(client, parser); - -@@ -246,7 +245,8 @@ public class HTTP2CServerTest extends AbstractServerTest - - final AtomicReference headersRef = new AtomicReference<>(); - final AtomicReference dataRef = new AtomicReference<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onSettings(SettingsFrame frame) -@@ -267,8 +267,7 @@ public class HTTP2CServerTest extends AbstractServerTest - dataRef.set(frame); - latch.countDown(); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - parseResponse(client, parser); - -diff --git a/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2ServerTest.java b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2ServerTest.java -index 2cada2f..c86a915 100644 ---- a/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2ServerTest.java -+++ b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2ServerTest.java -@@ -33,7 +33,6 @@ import java.util.concurrent.CountDownLatch; - import java.util.concurrent.TimeUnit; - import java.util.concurrent.atomic.AtomicBoolean; - import java.util.concurrent.atomic.AtomicReference; --import java.util.function.UnaryOperator; - import javax.servlet.ServletException; - import javax.servlet.http.HttpServlet; - import javax.servlet.http.HttpServletRequest; -@@ -95,15 +94,15 @@ public class HTTP2ServerTest extends AbstractServerTest - } - - final CountDownLatch latch = new CountDownLatch(1); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onGoAway(GoAwayFrame frame) - { - latch.countDown(); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - parseResponse(client, parser); - -@@ -139,7 +138,8 @@ public class HTTP2ServerTest extends AbstractServerTest - } - - final AtomicReference frameRef = new AtomicReference<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onSettings(SettingsFrame frame) -@@ -153,8 +153,7 @@ public class HTTP2ServerTest extends AbstractServerTest - frameRef.set(frame); - latch.countDown(); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - parseResponse(client, parser); - -@@ -198,7 +197,8 @@ public class HTTP2ServerTest extends AbstractServerTest - - final AtomicReference headersRef = new AtomicReference<>(); - final AtomicReference dataRef = new AtomicReference<>(); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onSettings(SettingsFrame frame) -@@ -219,8 +219,7 @@ public class HTTP2ServerTest extends AbstractServerTest - dataRef.set(frame); - latch.countDown(); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - parseResponse(client, parser); - -@@ -258,7 +257,8 @@ public class HTTP2ServerTest extends AbstractServerTest - output.write(BufferUtil.toArray(buffer)); - } - -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onGoAway(GoAwayFrame frame) -@@ -266,8 +266,7 @@ public class HTTP2ServerTest extends AbstractServerTest - assertEquals(ErrorCode.FRAME_SIZE_ERROR.code, frame.getError()); - latch.countDown(); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - parseResponse(client, parser); - -@@ -296,7 +295,8 @@ public class HTTP2ServerTest extends AbstractServerTest - output.write(BufferUtil.toArray(buffer)); - } - -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onGoAway(GoAwayFrame frame) -@@ -304,8 +304,7 @@ public class HTTP2ServerTest extends AbstractServerTest - assertEquals(ErrorCode.PROTOCOL_ERROR.code, frame.getError()); - latch.countDown(); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - - parseResponse(client, parser); - -@@ -373,8 +372,8 @@ public class HTTP2ServerTest extends AbstractServerTest - - // The server will close the connection abruptly since it - // cannot write and therefore cannot even send the GO_AWAY. -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter(), 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter()); - boolean closed = parseResponse(client, parser, 2 * delay); - assertTrue(closed); - } -@@ -411,8 +410,8 @@ public class HTTP2ServerTest extends AbstractServerTest - } - output.flush(); - -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter(), 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter()); - boolean closed = parseResponse(client, parser); - - assertTrue(closed); -@@ -584,7 +583,8 @@ public class HTTP2ServerTest extends AbstractServerTest - assertTrue(serverLatch.await(5, TimeUnit.SECONDS)); - - final CountDownLatch clientLatch = new CountDownLatch(1); -- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() -+ Parser parser = new Parser(byteBufferPool, 4096); -+ parser.init(new Parser.Listener.Adapter() - { - @Override - public void onHeaders(HeadersFrame frame) -@@ -592,8 +592,7 @@ public class HTTP2ServerTest extends AbstractServerTest - if (frame.isEndStream()) - clientLatch.countDown(); - } -- }, 4096, 8192); -- parser.init(UnaryOperator.identity()); -+ }); - boolean closed = parseResponse(client, parser); - - assertTrue(clientLatch.await(5, TimeUnit.SECONDS)); -diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/CharsetStringBuilder.java b/jetty-util/src/main/java/org/eclipse/jetty/util/CharsetStringBuilder.java -new file mode 100644 -index 0000000..13f588e ---- /dev/null -+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/CharsetStringBuilder.java -@@ -0,0 +1,312 @@ -+// -+// ======================================================================== -+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -+// ------------------------------------------------------------------------ -+// All rights reserved. This program and the accompanying materials -+// are made available under the terms of the Eclipse Public License v1.0 -+// and Apache License v2.0 which accompanies this distribution. -+// -+// The Eclipse Public License is available at -+// http://www.eclipse.org/legal/epl-v10.html -+// -+// The Apache License v2.0 is available at -+// http://www.opensource.org/licenses/apache2.0.php -+// -+// You may elect to redistribute this code under either of these licenses. -+// ======================================================================== -+// -+ -+package org.eclipse.jetty.util; -+ -+import java.nio.ByteBuffer; -+import java.nio.charset.CharacterCodingException; -+import java.nio.charset.Charset; -+import java.nio.charset.CharsetDecoder; -+import java.nio.charset.CodingErrorAction; -+import java.nio.charset.StandardCharsets; -+import java.util.Arrays; -+import java.util.Objects; -+ -+/** -+ *

Build a string from a sequence of bytes and/or characters.

-+ *

Implementations of this interface are optimized for processing a mix of calls to already decoded -+ * character based appends (e.g. {@link #append(char)} and calls to undecoded byte methods (e.g. {@link #append(byte)}. -+ * This is particularly useful for decoding % encoded strings that are mostly already decoded but may contain -+ * escaped byte sequences that are not decoded. The standard {@link CharsetDecoder} API is not well suited for this -+ * use-case.

-+ *

Any coding errors in the string will be reported by a {@link CharacterCodingException} thrown -+ * from the {@link #build()} method.

-+ * @see Utf8StringBuilder for UTF-8 decoding with replacement of coding errors and/or fast fail behaviour. -+ * @see CharsetDecoder for decoding arbitrary {@link Charset}s with control over {@link CodingErrorAction}. -+ */ -+public interface CharsetStringBuilder -+{ -+ /** -+ * @param b An encoded byte to append -+ */ -+ void append(byte b); -+ -+ /** -+ * @param c A decoded character to append -+ */ -+ void append(char c); -+ -+ /** -+ * @param bytes Array of encoded bytes to append -+ */ -+ default void append(byte[] bytes) -+ { -+ append(bytes, 0, bytes.length); -+ } -+ -+ /** -+ * @param b Array of encoded bytes -+ * @param offset offset into the array -+ * @param length the number of bytes to append from the array. -+ */ -+ default void append(byte[] b, int offset, int length) -+ { -+ int end = offset + length; -+ for (int i = offset; i < end; i++) -+ append(b[i]); -+ } -+ -+ /** -+ * @param chars sequence of decoded characters -+ * @param offset offset into the array -+ * @param length the number of character to append from the sequence. -+ */ -+ default void append(CharSequence chars, int offset, int length) -+ { -+ int end = offset + length; -+ for (int i = offset; i < end; i++) -+ append(chars.charAt(i)); -+ } -+ -+ /** -+ * @param buf Buffer of encoded bytes to append. The bytes are consumed from the buffer. -+ */ -+ default void append(ByteBuffer buf) -+ { -+ int end = buf.position() + buf.remaining(); -+ while (buf.position() < end) -+ append(buf.get()); -+ } -+ -+ /** -+ *

Build the completed string and reset the buffer.

-+ * @return The decoded built string which must be complete in regard to any multibyte sequences. -+ * @throws CharacterCodingException If the bytes cannot be correctly decoded or a multibyte sequence is incomplete. -+ */ -+ String build() throws CharacterCodingException; -+ -+ void reset(); -+ -+ /** -+ * @param charset The charset -+ * @return A {@link CharsetStringBuilder} suitable for the charset. -+ */ -+ static CharsetStringBuilder forCharset(Charset charset) -+ { -+ Objects.requireNonNull(charset); -+ if (charset == StandardCharsets.ISO_8859_1) -+ return new Iso88591StringBuilder(); -+ if (charset == StandardCharsets.US_ASCII) -+ return new UsAsciiStringBuilder(); -+ -+ // Use a CharsetDecoder that defaults to CodingErrorAction#REPORT -+ return new DecoderStringBuilder(charset.newDecoder()); -+ } -+ -+ class Iso88591StringBuilder implements CharsetStringBuilder -+ { -+ private final StringBuilder _builder = new StringBuilder(); -+ -+ @Override -+ public void append(byte b) -+ { -+ _builder.append((char)(0xff & b)); -+ } -+ -+ @Override -+ public void append(char c) -+ { -+ _builder.append(c); -+ } -+ -+ @Override -+ public void append(CharSequence chars, int offset, int length) -+ { -+ _builder.append(chars, offset, offset + length); -+ } -+ -+ @Override -+ public String build() -+ { -+ String s = _builder.toString(); -+ _builder.setLength(0); -+ return s; -+ } -+ -+ @Override -+ public void reset() -+ { -+ _builder.setLength(0); -+ } -+ } -+ -+ class UsAsciiStringBuilder implements CharsetStringBuilder -+ { -+ private final StringBuilder _builder = new StringBuilder(); -+ -+ @Override -+ public void append(byte b) -+ { -+ if (b < 0) -+ throw new IllegalArgumentException(); -+ _builder.append((char)b); -+ } -+ -+ @Override -+ public void append(char c) -+ { -+ _builder.append(c); -+ } -+ -+ @Override -+ public void append(CharSequence chars, int offset, int length) -+ { -+ _builder.append(chars, offset, offset + length); -+ } -+ -+ @Override -+ public String build() -+ { -+ String s = _builder.toString(); -+ _builder.setLength(0); -+ return s; -+ } -+ -+ @Override -+ public void reset() -+ { -+ _builder.setLength(0); -+ } -+ } -+ -+ class DecoderStringBuilder implements CharsetStringBuilder -+ { -+ private final CharsetDecoder _decoder; -+ private final StringBuilder _stringBuilder = new StringBuilder(32); -+ private ByteBuffer _buffer = ByteBuffer.allocate(32); -+ -+ public DecoderStringBuilder(CharsetDecoder charsetDecoder) -+ { -+ _decoder = charsetDecoder; -+ } -+ -+ private void ensureSpace(int needed) -+ { -+ int space = _buffer.remaining(); -+ if (space < needed) -+ { -+ int position = _buffer.position(); -+ _buffer = ByteBuffer.wrap(Arrays.copyOf(_buffer.array(), _buffer.capacity() + needed - space + 32)); -+ _buffer.position(position); -+ } -+ } -+ -+ @Override -+ public void append(byte b) -+ { -+ ensureSpace(1); -+ _buffer.put(b); -+ } -+ -+ @Override -+ public void append(char c) -+ { -+ if (_buffer.position() > 0) -+ { -+ try -+ { -+ // Append any data already in the decoder -+ _buffer.flip(); -+ _stringBuilder.append(_decoder.decode(_buffer)); -+ _buffer.clear(); -+ } -+ catch (CharacterCodingException e) -+ { -+ // This will be thrown only if the decoder is configured to REPORT, -+ // otherwise errors will be ignored or replaced and we will not catch here. -+ throw new RuntimeException(e); -+ } -+ } -+ _stringBuilder.append(c); -+ } -+ -+ @Override -+ public void append(CharSequence chars, int offset, int length) -+ { -+ if (_buffer.position() > 0) -+ { -+ try -+ { -+ // Append any data already in the decoder -+ _buffer.flip(); -+ _stringBuilder.append(_decoder.decode(_buffer)); -+ _buffer.clear(); -+ } -+ catch (CharacterCodingException e) -+ { -+ // This will be thrown only if the decoder is configured to REPORT, -+ // otherwise errors will be ignored or replaced and we will not catch here. -+ throw new RuntimeException(e); -+ } -+ } -+ _stringBuilder.append(chars, offset, offset + length); -+ } -+ -+ @Override -+ public void append(byte[] b, int offset, int length) -+ { -+ ensureSpace(length); -+ _buffer.put(b, offset, length); -+ } -+ -+ @Override -+ public void append(ByteBuffer buf) -+ { -+ ensureSpace(buf.remaining()); -+ _buffer.put(buf); -+ } -+ -+ @Override -+ public String build() throws CharacterCodingException -+ { -+ try -+ { -+ if (_buffer.position() > 0) -+ { -+ _buffer.flip(); -+ CharSequence decoded = _decoder.decode(_buffer); -+ _buffer.clear(); -+ if (_stringBuilder.length() == 0) -+ return decoded.toString(); -+ _stringBuilder.append(decoded); -+ } -+ return _stringBuilder.toString(); -+ } -+ finally -+ { -+ _stringBuilder.setLength(0); -+ } -+ } -+ -+ @Override -+ public void reset() -+ { -+ _stringBuilder.setLength(0); -+ } -+ } -+} -diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java b/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java -index 0bdb229..9d46b48 100644 ---- a/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java -+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java -@@ -107,6 +107,27 @@ public class StringUtil - '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177' - }; - -+ // @checkstyle-disable-check : IllegalTokenTextCheck -+ private static final char[] uppercases = -+ { -+ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', -+ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', -+ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', -+ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', -+ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', -+ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', -+ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', -+ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', -+ '\100', '\101', '\102', '\103', '\104', '\105', '\106', '\107', -+ '\110', '\111', '\112', '\113', '\114', '\115', '\116', '\117', -+ '\120', '\121', '\122', '\123', '\124', '\125', '\126', '\127', -+ '\130', '\131', '\132', '\133', '\134', '\135', '\136', '\137', -+ '\140', '\101', '\102', '\103', '\104', '\105', '\106', '\107', -+ '\110', '\111', '\112', '\113', '\114', '\115', '\116', '\117', -+ '\120', '\121', '\122', '\123', '\124', '\125', '\126', '\127', -+ '\130', '\131', '\132', '\173', '\174', '\175', '\176', '\177' -+ }; -+ - /** - * fast lower case conversion. Only works on ascii (not unicode) - * -@@ -144,6 +165,42 @@ public class StringUtil - return c == null ? s : new String(c); - } - -+ /** -+ * fast upper case conversion. Only works on ascii (not unicode) -+ * -+ * @param s the string to convert -+ * @return a lower case version of s -+ */ -+ public static String asciiToUpperCase(String s) -+ { -+ if (s == null) -+ return null; -+ -+ char[] c = null; -+ int i = s.length(); -+ // look for first conversion -+ while (i-- > 0) -+ { -+ char c1 = s.charAt(i); -+ if (c1 <= 127) -+ { -+ char c2 = uppercases[c1]; -+ if (c1 != c2) -+ { -+ c = s.toCharArray(); -+ c[i] = c2; -+ break; -+ } -+ } -+ } -+ while (i-- > 0) -+ { -+ if (c[i] <= 127) -+ c[i] = uppercases[c[i]]; -+ } -+ return c == null ? s : new String(c); -+ } -+ - /** - * Replace all characters from input string that are known to have - * special meaning in various filesystems. -@@ -453,6 +510,22 @@ public class StringUtil - } - } - -+ /** -+ * Generate a string from another string repeated n times. -+ * -+ * @param s the string to use -+ * @param n the number of times this string should be appended -+ */ -+ public static String stringFrom(String s, int n) -+ { -+ StringBuilder stringBuilder = new StringBuilder(s.length() * n); -+ for (int i = 0; i < n; i++) -+ { -+ stringBuilder.append(s); -+ } -+ return stringBuilder.toString(); -+ } -+ - /** - * Return a non null string. - * diff -Nru jetty9-9.4.50/debian/patches/CVE-2023-36479.patch jetty9-9.4.57/debian/patches/CVE-2023-36479.patch --- jetty9-9.4.50/debian/patches/CVE-2023-36479.patch 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/patches/CVE-2023-36479.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -From: Markus Koschany -Date: Wed, 27 Sep 2023 16:34:32 +0200 -Subject: CVE-2023-36479 - ---- - .../src/main/java/org/eclipse/jetty/servlets/CGI.java | 3 +++ - .../test-jetty-webapp/src/main/webapp/WEB-INF/web.xml | 12 ------------ - 2 files changed, 3 insertions(+), 12 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 9236825..6454540 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 -@@ -67,7 +67,10 @@ import org.eclipse.jetty.util.log.Logger; - *
ignoreExitState
- *
If true then do not act on a non-zero exec exit status")
- * -+ * -+ * @deprecated do not use, no replacement, will be removed in a future release. - */ -+@Deprecated - public class CGI extends HttpServlet - { - private static final long serialVersionUID = -6182088932884791074L; -diff --git a/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml b/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml -index 05e4f1d..ef7e279 100644 ---- a/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml -+++ b/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml -@@ -121,18 +121,6 @@ - /dispatch/* - - -- -- CGI -- org.eclipse.jetty.servlets.CGI -- 1 -- true -- -- -- -- CGI -- /cgi-bin/* -- -- - - Chat - com.acme.ChatServlet diff -Nru jetty9-9.4.50/debian/patches/CVE-2023-40167.patch jetty9-9.4.57/debian/patches/CVE-2023-40167.patch --- jetty9-9.4.50/debian/patches/CVE-2023-40167.patch 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/patches/CVE-2023-40167.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,268 +0,0 @@ -From: Markus Koschany -Date: Tue, 26 Sep 2023 18:45:05 +0200 -Subject: CVE-2023-40167 - -Origin: https://github.com/eclipse/jetty.project/commit/e4d596eafc887bcd813ae6e28295b5ce327def47 ---- - .../java/org/eclipse/jetty/http/HttpParser.java | 48 ++++++------ - .../org/eclipse/jetty/http/HttpParserTest.java | 87 +++++++--------------- - 2 files changed, 51 insertions(+), 84 deletions(-) - -diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java -index 990e53a..4db6716 100644 ---- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java -+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java -@@ -499,7 +499,7 @@ public class HttpParser - /* Quick lookahead for the start state looking for a request method or an HTTP version, - * otherwise skip white space until something else to parse. - */ -- private boolean quickStart(ByteBuffer buffer) -+ private void quickStart(ByteBuffer buffer) - { - if (_requestHandler != null) - { -@@ -510,7 +510,7 @@ public class HttpParser - buffer.position(buffer.position() + _methodString.length() + 1); - - setState(State.SPACE1); -- return false; -+ return; - } - } - else if (_responseHandler != null) -@@ -520,7 +520,7 @@ public class HttpParser - { - buffer.position(buffer.position() + _version.asString().length() + 1); - setState(State.SPACE1); -- return false; -+ return; - } - } - -@@ -541,7 +541,7 @@ public class HttpParser - _string.setLength(0); - _string.append(t.getChar()); - setState(_requestHandler != null ? State.METHOD : State.RESPONSE_VERSION); -- return false; -+ return; - } - case OTEXT: - case SPACE: -@@ -559,7 +559,6 @@ public class HttpParser - throw new BadMessageException(HttpStatus.BAD_REQUEST_400); - } - } -- return false; - } - - private void setString(String s) -@@ -974,23 +973,20 @@ public class HttpParser - case CONTENT_LENGTH: - if (_hasTransferEncoding && complianceViolation(TRANSFER_ENCODING_WITH_CONTENT_LENGTH)) - throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Transfer-Encoding and Content-Length"); -- -+ long contentLength = convertContentLength(_valueString); - if (_hasContentLength) - { - if (complianceViolation(MULTIPLE_CONTENT_LENGTHS)) - throw new BadMessageException(HttpStatus.BAD_REQUEST_400, MULTIPLE_CONTENT_LENGTHS.description); -- if (convertContentLength(_valueString) != _contentLength) -- throw new BadMessageException(HttpStatus.BAD_REQUEST_400, MULTIPLE_CONTENT_LENGTHS.description); -+ if (contentLength != _contentLength) -+ throw new BadMessageException(HttpStatus.BAD_REQUEST_400, MULTIPLE_CONTENT_LENGTHS.getDescription()); - } - _hasContentLength = true; - - if (_endOfContent != EndOfContent.CHUNKED_CONTENT) - { -- _contentLength = convertContentLength(_valueString); -- if (_contentLength <= 0) -- _endOfContent = EndOfContent.NO_CONTENT; -- else -- _endOfContent = EndOfContent.CONTENT_LENGTH; -+ _contentLength = contentLength; -+ _endOfContent = EndOfContent.CONTENT_LENGTH; - } - break; - -@@ -1107,15 +1103,21 @@ public class HttpParser - - private long convertContentLength(String valueString) - { -- try -- { -- return Long.parseLong(valueString); -- } -- catch (NumberFormatException e) -+ if (valueString == null || valueString.length() == 0) -+ throw new BadMessageException("Invalid Content-Length Value", new NumberFormatException()); -+ -+ long value = 0; -+ int length = valueString.length(); -+ -+ for (int i = 0; i < length; i++) - { -- LOG.ignore(e); -- throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Invalid Content-Length Value", e); -+ char c = valueString.charAt(i); -+ if (c < '0' || c > '9') -+ throw new BadMessageException("Invalid Content-Length Value", new NumberFormatException()); -+ -+ value = Math.addExact(Math.multiplyExact(value, 10L), c - '0'); - } -+ return value; - } - - /* -@@ -1511,12 +1513,11 @@ public class HttpParser - _methodString = null; - _endOfContent = EndOfContent.UNKNOWN_CONTENT; - _header = null; -- if (quickStart(buffer)) -- return true; -+ quickStart(buffer); - } - - // Request/response line -- if (_state.ordinal() >= State.START.ordinal() && _state.ordinal() < State.HEADER.ordinal()) -+ if (_state.ordinal() < State.HEADER.ordinal()) - { - if (parseLine(buffer)) - return true; -@@ -2036,7 +2037,6 @@ public class HttpParser - } - } - -- @SuppressWarnings("serial") - private static class IllegalCharacterException extends BadMessageException - { - private IllegalCharacterException(State state, HttpTokens.Token token, ByteBuffer buffer) -diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java -index a5bbb0c..ff19c59 100644 ---- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java -+++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java -@@ -41,6 +41,7 @@ import static org.hamcrest.MatcherAssert.assertThat; - import static org.hamcrest.Matchers.contains; - import static org.hamcrest.Matchers.containsString; - import static org.hamcrest.Matchers.is; -+import static org.hamcrest.Matchers.notNullValue; - import static org.hamcrest.Matchers.nullValue; - import static org.junit.jupiter.api.Assertions.assertEquals; - import static org.junit.jupiter.api.Assertions.assertFalse; -@@ -1672,7 +1673,7 @@ public class HttpParserTest - } - - @Test -- public void testUnknownReponseVersion() -+ public void testUnknownResponseVersion() - { - ByteBuffer buffer = BufferUtil.toBuffer( - "HPPT/7.7 200 OK\r\n" + -@@ -1815,65 +1816,31 @@ public class HttpParserTest - assertEquals(HttpParser.State.CLOSED, parser.getState()); - } - -- @Test -- public void testBadContentLength0() -- { -- ByteBuffer buffer = BufferUtil.toBuffer( -- "GET / HTTP/1.0\r\n" + -- "Content-Length: abc\r\n" + -- "Connection: close\r\n" + -- "\r\n"); -- -- HttpParser.RequestHandler handler = new Handler(); -- HttpParser parser = new HttpParser(handler); -- -- parser.parseNext(buffer); -- assertEquals("GET", _methodOrVersion); -- assertEquals("Invalid Content-Length Value", _bad); -- assertFalse(buffer.hasRemaining()); -- assertEquals(HttpParser.State.CLOSE, parser.getState()); -- parser.atEOF(); -- parser.parseNext(BufferUtil.EMPTY_BUFFER); -- assertEquals(HttpParser.State.CLOSED, parser.getState()); -- } -- -- @Test -- public void testBadContentLength1() -- { -- ByteBuffer buffer = BufferUtil.toBuffer( -- "GET / HTTP/1.0\r\n" + -- "Content-Length: 9999999999999999999999999999999999999999999999\r\n" + -- "Connection: close\r\n" + -- "\r\n"); -- -- HttpParser.RequestHandler handler = new Handler(); -- HttpParser parser = new HttpParser(handler); -- -- parser.parseNext(buffer); -- assertEquals("GET", _methodOrVersion); -- assertEquals("Invalid Content-Length Value", _bad); -- assertFalse(buffer.hasRemaining()); -- assertEquals(HttpParser.State.CLOSE, parser.getState()); -- parser.atEOF(); -- parser.parseNext(BufferUtil.EMPTY_BUFFER); -- assertEquals(HttpParser.State.CLOSED, parser.getState()); -- } -- -- @Test -- public void testBadContentLength2() -- { -- ByteBuffer buffer = BufferUtil.toBuffer( -- "GET / HTTP/1.0\r\n" + -- "Content-Length: 1.5\r\n" + -- "Connection: close\r\n" + -- "\r\n"); -+ @ParameterizedTest -+ @ValueSource(strings = { -+ "abc", -+ "1.5", -+ "9999999999999999999999999999999999999999999999", -+ "-10", -+ "+10", -+ "1.0", -+ "1,0", -+ "10," -+ }) -+ public void testBadContentLengths(String contentLength) -+ { -+ ByteBuffer buffer = BufferUtil.toBuffer( -+ "GET /test HTTP/1.1\r\n" + -+ "Host: localhost\r\n" + -+ "Content-Length: " + contentLength + "\r\n" + -+ "\r\n" + -+ "1234567890\r\n"); - - HttpParser.RequestHandler handler = new Handler(); -- HttpParser parser = new HttpParser(handler); -+ HttpParser parser = new HttpParser(handler, HttpCompliance.RFC2616_LEGACY); -+ parseAll(parser, buffer); - -- parser.parseNext(buffer); -- assertEquals("GET", _methodOrVersion); -- assertEquals("Invalid Content-Length Value", _bad); -+ assertThat(_bad, notNullValue()); - assertFalse(buffer.hasRemaining()); - assertEquals(HttpParser.State.CLOSE, parser.getState()); - parser.atEOF(); -@@ -2084,7 +2051,7 @@ public class HttpParserTest - @Test - public void testBadIPv6Host() - { -- try (StacklessLogging s = new StacklessLogging(HttpParser.class)) -+ try (StacklessLogging ignored = new StacklessLogging(HttpParser.class)) - { - ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.1\r\n" + -@@ -2930,8 +2897,8 @@ public class HttpParserTest - private String _methodOrVersion; - private String _uriOrStatus; - private String _versionOrReason; -- private List _fields = new ArrayList<>(); -- private List _trailers = new ArrayList<>(); -+ private final List _fields = new ArrayList<>(); -+ private final List _trailers = new ArrayList<>(); - private String[] _hdr; - private String[] _val; - private int _headers; diff -Nru jetty9-9.4.50/debian/patches/CVE-2023-41900.patch jetty9-9.4.57/debian/patches/CVE-2023-41900.patch --- jetty9-9.4.50/debian/patches/CVE-2023-41900.patch 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/patches/CVE-2023-41900.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,781 +0,0 @@ -From: Markus Koschany -Date: Tue, 26 Sep 2023 18:45:42 +0200 -Subject: CVE-2023-41900 - -Origin: https://github.com/eclipse/jetty.project/pull/9660 ---- - .../jetty/security/openid/OpenIdAuthenticator.java | 12 +- - .../jetty/security/openid/OpenIdCredentials.java | 19 +- - .../security/openid/OpenIdAuthenticationTest.java | 187 ++++++++++++--- - .../jetty/security/openid/OpenIdProvider.java | 250 ++++++++++++++++++--- - 4 files changed, 388 insertions(+), 80 deletions(-) - -diff --git a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java -index 0635f21..13e5e0e 100644 ---- a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java -+++ b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java -@@ -345,10 +345,7 @@ public class OpenIdAuthenticator extends LoginAuthenticator - { - if (LOG.isDebugEnabled()) - LOG.debug("auth revoked {}", authentication); -- synchronized (session) -- { -- session.removeAttribute(SessionAuthentication.__J_AUTHENTICATED); -- } -+ logout(request); - } - else - { -@@ -380,10 +377,11 @@ public class OpenIdAuthenticator extends LoginAuthenticator - } - } - } -+ -+ if (LOG.isDebugEnabled()) -+ LOG.debug("auth {}", authentication); -+ return authentication; - } -- if (LOG.isDebugEnabled()) -- LOG.debug("auth {}", authentication); -- return authentication; - } - - // If we can't send challenge. -diff --git a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java -index ba4e37e..1cd29b4 100644 ---- a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java -+++ b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java -@@ -20,6 +20,7 @@ package org.eclipse.jetty.security.openid; - - import java.io.Serializable; - import java.net.URI; -+import java.time.Instant; - import java.util.Arrays; - import java.util.List; - import java.util.Map; -@@ -142,12 +143,24 @@ public class OpenIdCredentials implements Serializable - throw new AuthenticationException("Authorized party claim value should be the client_id"); - - // Check that the ID token has not expired by checking the exp claim. -- long expiry = (Long)claims.get("exp"); -- long currentTimeSeconds = (long)(System.currentTimeMillis() / 1000F); -- if (currentTimeSeconds > expiry) -+ if (isExpired()) - throw new AuthenticationException("ID Token has expired"); - } - -+ public boolean isExpired() -+ { -+ return checkExpiry(claims); -+ } -+ -+ public static boolean checkExpiry(Map claims) -+ { -+ if (claims == null) -+ return true; -+ -+ // Check that the ID token has not expired by checking the exp claim. -+ return Instant.ofEpochSecond((Long)claims.get("exp")).isBefore(Instant.now()); -+ } -+ - private void validateAudience(OpenIdConfiguration configuration) throws AuthenticationException - { - Object aud = claims.get("aud"); -diff --git a/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdAuthenticationTest.java b/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdAuthenticationTest.java -index d649c33..1990454 100644 ---- a/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdAuthenticationTest.java -+++ b/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdAuthenticationTest.java -@@ -18,28 +18,41 @@ - - package org.eclipse.jetty.security.openid; - -+import java.io.File; - import java.io.IOException; - import java.security.Principal; - import java.util.Map; -+import java.util.concurrent.atomic.AtomicBoolean; -+import java.util.function.Consumer; -+import javax.servlet.ServletException; - import javax.servlet.http.HttpServlet; - import javax.servlet.http.HttpServletRequest; - import javax.servlet.http.HttpServletResponse; - - import org.eclipse.jetty.client.HttpClient; - import org.eclipse.jetty.client.api.ContentResponse; -+import org.eclipse.jetty.http.HttpHeader; - import org.eclipse.jetty.http.HttpStatus; --import org.eclipse.jetty.security.Authenticator; -+import org.eclipse.jetty.security.AbstractLoginService; - import org.eclipse.jetty.security.ConstraintMapping; - import org.eclipse.jetty.security.ConstraintSecurityHandler; -+import org.eclipse.jetty.security.LoginService; - import org.eclipse.jetty.server.Server; - import org.eclipse.jetty.server.ServerConnector; -+import org.eclipse.jetty.server.UserIdentity; -+import org.eclipse.jetty.server.session.FileSessionDataStoreFactory; - import org.eclipse.jetty.servlet.ServletContextHandler; -+import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -+import org.eclipse.jetty.util.IO; - import org.eclipse.jetty.util.security.Constraint; -+import org.eclipse.jetty.util.security.Password; - import org.junit.jupiter.api.AfterEach; --import org.junit.jupiter.api.BeforeEach; - import org.junit.jupiter.api.Test; - - import static org.hamcrest.MatcherAssert.assertThat; -+import static org.hamcrest.Matchers.containsString; -+import static org.hamcrest.Matchers.equalTo; -+import static org.hamcrest.Matchers.greaterThanOrEqualTo; - import static org.hamcrest.Matchers.is; - - public class OpenIdAuthenticationTest -@@ -52,8 +65,12 @@ public class OpenIdAuthenticationTest - private ServerConnector connector; - private HttpClient client; - -- @BeforeEach -- public void setup() throws Exception -+ public void setup(LoginService loginService) throws Exception -+ { -+ setup(loginService, null); -+ } -+ -+ public void setup(LoginService loginService, Consumer configure) throws Exception - { - openIdProvider = new OpenIdProvider(CLIENT_ID, CLIENT_SECRET); - openIdProvider.start(); -@@ -93,22 +110,29 @@ public class OpenIdAuthenticationTest - - // security handler - ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler(); -- securityHandler.setRealmName("OpenID Connect Authentication"); -+ assertThat(securityHandler.getKnownAuthenticatorFactories().size(), greaterThanOrEqualTo(2)); -+ -+ securityHandler.setAuthMethod(Constraint.__OPENID_AUTH); -+ securityHandler.setRealmName(openIdProvider.getProvider()); - securityHandler.addConstraintMapping(profileMapping); - securityHandler.addConstraintMapping(loginMapping); - securityHandler.addConstraintMapping(adminMapping); - - // Authentication using local OIDC Provider -- OpenIdConfiguration configuration = new OpenIdConfiguration(openIdProvider.getProvider(), CLIENT_ID, CLIENT_SECRET); -- -- // Configure OpenIdLoginService optionally providing a base LoginService to provide user roles -- OpenIdLoginService loginService = new OpenIdLoginService(configuration); -- securityHandler.setLoginService(loginService); -- -- Authenticator authenticator = new OpenIdAuthenticator(configuration, "/error"); -- securityHandler.setAuthenticator(authenticator); -+ OpenIdConfiguration openIdConfiguration = new OpenIdConfiguration(openIdProvider.getProvider(), CLIENT_ID, CLIENT_SECRET); -+ if (configure != null) -+ configure.accept(openIdConfiguration); -+ securityHandler.setLoginService(new OpenIdLoginService(openIdConfiguration, loginService)); -+ server.addBean(openIdConfiguration); -+ securityHandler.setInitParameter(OpenIdAuthenticator.ERROR_PAGE, "/error"); - context.setSecurityHandler(securityHandler); - -+ File datastoreDir = MavenTestingUtils.getTargetTestingDir("datastore"); -+ IO.delete(datastoreDir); -+ FileSessionDataStoreFactory fileSessionDataStoreFactory = new FileSessionDataStoreFactory(); -+ fileSessionDataStoreFactory.setStoreDir(datastoreDir); -+ server.addBean(fileSessionDataStoreFactory); -+ - server.start(); - String redirectUri = "http://localhost:" + connector.getLocalPort() + "/j_security_check"; - openIdProvider.addRedirectUri(redirectUri); -@@ -127,41 +151,127 @@ public class OpenIdAuthenticationTest - @Test - public void testLoginLogout() throws Exception - { -+ setup(null); -+ openIdProvider.setUser(new OpenIdProvider.User("123456789", "Alice")); -+ - String appUriString = "http://localhost:" + connector.getLocalPort(); - - // Initially not authenticated - ContentResponse response = client.GET(appUriString + "/"); - assertThat(response.getStatus(), is(HttpStatus.OK_200)); -- String[] content = response.getContentAsString().split("[\r\n]+"); -- assertThat(content.length, is(1)); -- assertThat(content[0], is("not authenticated")); -+ String content = response.getContentAsString(); -+ assertThat(content, containsString("not authenticated")); - - // Request to login is success - response = client.GET(appUriString + "/login"); - assertThat(response.getStatus(), is(HttpStatus.OK_200)); -- content = response.getContentAsString().split("[\r\n]+"); -- assertThat(content.length, is(1)); -- assertThat(content[0], is("success")); -+ content = response.getContentAsString(); -+ assertThat(content, containsString("success")); - - // Now authenticated we can get info - response = client.GET(appUriString + "/"); - assertThat(response.getStatus(), is(HttpStatus.OK_200)); -- content = response.getContentAsString().split("[\r\n]+"); -- assertThat(content.length, is(3)); -- assertThat(content[0], is("userId: 123456789")); -- assertThat(content[1], is("name: Alice")); -- assertThat(content[2], is("email: Alice@example.com")); -+ content = response.getContentAsString(); -+ assertThat(content, containsString("userId: 123456789")); -+ assertThat(content, containsString("name: Alice")); -+ assertThat(content, containsString("email: Alice@example.com")); - - // Request to admin page gives 403 as we do not have admin role - response = client.GET(appUriString + "/admin"); - assertThat(response.getStatus(), is(HttpStatus.FORBIDDEN_403)); - -+ // We can restart the server and still be logged in as we have persistent session datastore. -+ server.stop(); -+ server.start(); -+ appUriString = "http://localhost:" + connector.getLocalPort(); -+ -+ // After restarting server the authentication is saved as a session authentication. -+ response = client.GET(appUriString + "/"); -+ assertThat(response.getStatus(), is(HttpStatus.OK_200)); -+ content = response.getContentAsString(); -+ assertThat(content, containsString("userId: 123456789")); -+ assertThat(content, containsString("name: Alice")); -+ assertThat(content, containsString("email: Alice@example.com")); -+ - // We are no longer authenticated after logging out - response = client.GET(appUriString + "/logout"); - assertThat(response.getStatus(), is(HttpStatus.OK_200)); -- content = response.getContentAsString().split("[\r\n]+"); -- assertThat(content.length, is(1)); -- assertThat(content[0], is("not authenticated")); -+ content = response.getContentAsString(); -+ assertThat(content, containsString("not authenticated")); -+ -+ // Test that the user was logged out successfully on the openid provider. -+ assertThat(openIdProvider.getLoggedInUsers().getMax(), equalTo(1L)); -+ assertThat(openIdProvider.getLoggedInUsers().getTotal(), equalTo(1L)); -+ } -+ -+ @Test -+ public void testNestedLoginService() throws Exception -+ { -+ AtomicBoolean loggedIn = new AtomicBoolean(true); -+ setup(new AbstractLoginService() -+ { -+ @Override -+ protected String[] loadRoleInfo(UserPrincipal user) -+ { -+ return new String[]{"admin"}; -+ } -+ -+ @Override -+ protected UserPrincipal loadUserInfo(String username) -+ { -+ return new UserPrincipal(username, new Password("")); -+ } -+ -+ @Override -+ public boolean validate(UserIdentity user) -+ { -+ if (!loggedIn.get()) -+ return false; -+ return super.validate(user); -+ } -+ }); -+ -+ openIdProvider.setUser(new OpenIdProvider.User("123456789", "Alice")); -+ -+ String appUriString = "http://localhost:" + connector.getLocalPort(); -+ -+ // Initially not authenticated -+ ContentResponse response = client.GET(appUriString + "/"); -+ assertThat(response.getStatus(), is(HttpStatus.OK_200)); -+ String content = response.getContentAsString(); -+ assertThat(content, containsString("not authenticated")); -+ -+ // Request to login is success -+ response = client.GET(appUriString + "/login"); -+ assertThat(response.getStatus(), is(HttpStatus.OK_200)); -+ content = response.getContentAsString(); -+ assertThat(content, containsString("success")); -+ -+ // Now authenticated we can get info -+ response = client.GET(appUriString + "/"); -+ assertThat(response.getStatus(), is(HttpStatus.OK_200)); -+ content = response.getContentAsString(); -+ assertThat(content, containsString("userId: 123456789")); -+ assertThat(content, containsString("name: Alice")); -+ assertThat(content, containsString("email: Alice@example.com")); -+ -+ // The nested login service has supplied the admin role. -+ response = client.GET(appUriString + "/admin"); -+ assertThat(response.getStatus(), is(HttpStatus.OK_200)); -+ -+ // This causes any validation of UserIdentity in the LoginService to fail -+ // causing subsequent requests to be redirected to the auth endpoint for login again. -+ loggedIn.set(false); -+ client.setFollowRedirects(false); -+ response = client.GET(appUriString + "/admin"); -+ assertThat(response.getStatus(), is(HttpStatus.SEE_OTHER_303)); -+ String location = response.getHeaders().get(HttpHeader.LOCATION); -+ assertThat(location, containsString(openIdProvider.getProvider() + "/auth")); -+ -+ // Note that we couldn't follow "OpenID Connect RP-Initiated Logout 1.0" because we redirect straight to auth endpoint. -+ assertThat(openIdProvider.getLoggedInUsers().getCurrent(), equalTo(1L)); -+ assertThat(openIdProvider.getLoggedInUsers().getMax(), equalTo(1L)); -+ assertThat(openIdProvider.getLoggedInUsers().getTotal(), equalTo(1L)); - } - - public static class LoginPage extends HttpServlet -@@ -169,16 +279,18 @@ public class OpenIdAuthenticationTest - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException - { -+ response.setContentType("text/html"); - response.getWriter().println("success"); -+ response.getWriter().println("
Home"); - } - } - - public static class LogoutPage extends HttpServlet - { - @Override -- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException -+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException - { -- request.getSession().invalidate(); -+ request.logout(); - response.sendRedirect("/"); - } - } -@@ -188,7 +300,7 @@ public class OpenIdAuthenticationTest - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException - { -- Map userInfo = (Map)request.getSession().getAttribute(OpenIdAuthenticator.CLAIMS); -+ Map userInfo = (Map)request.getSession().getAttribute(OpenIdAuthenticator.CLAIMS); - response.getWriter().println(userInfo.get("sub") + ": success"); - } - } -@@ -198,18 +310,20 @@ public class OpenIdAuthenticationTest - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException - { -- response.setContentType("text/plain"); -+ response.setContentType("text/html"); - Principal userPrincipal = request.getUserPrincipal(); - if (userPrincipal != null) - { -- Map userInfo = (Map)request.getSession().getAttribute(OpenIdAuthenticator.CLAIMS); -- response.getWriter().println("userId: " + userInfo.get("sub")); -- response.getWriter().println("name: " + userInfo.get("name")); -- response.getWriter().println("email: " + userInfo.get("email")); -+ Map userInfo = (Map)request.getSession().getAttribute(OpenIdAuthenticator.CLAIMS); -+ response.getWriter().println("userId: " + userInfo.get("sub") + "
"); -+ response.getWriter().println("name: " + userInfo.get("name") + "
"); -+ response.getWriter().println("email: " + userInfo.get("email") + "
"); -+ response.getWriter().println("
Logout"); - } - else - { - response.getWriter().println("not authenticated"); -+ response.getWriter().println("
Login"); - } - } - } -@@ -219,8 +333,9 @@ public class OpenIdAuthenticationTest - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException - { -- response.setContentType("text/plain"); -+ response.setContentType("text/html"); - response.getWriter().println("not authorized"); -+ response.getWriter().println("
Home"); - } - } - } -diff --git a/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdProvider.java b/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdProvider.java -index 9c3015a..75b6071 100644 ---- a/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdProvider.java -+++ b/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdProvider.java -@@ -19,14 +19,16 @@ - package org.eclipse.jetty.security.openid; - - import java.io.IOException; -+import java.io.PrintWriter; - import java.time.Duration; -+import java.time.Instant; - import java.util.ArrayList; - import java.util.Arrays; - import java.util.Collections; - import java.util.HashMap; - import java.util.List; - import java.util.Map; --import java.util.Random; -+import java.util.Objects; - import java.util.UUID; - import javax.servlet.ServletException; - import javax.servlet.http.HttpServlet; -@@ -40,23 +42,52 @@ import org.eclipse.jetty.server.Server; - import org.eclipse.jetty.server.ServerConnector; - import org.eclipse.jetty.servlet.ServletContextHandler; - import org.eclipse.jetty.servlet.ServletHolder; --import org.eclipse.jetty.util.StringUtil; - import org.eclipse.jetty.util.component.ContainerLifeCycle; -+import org.eclipse.jetty.util.log.Log; -+import org.eclipse.jetty.util.log.Logger; -+import org.eclipse.jetty.util.statistic.CounterStatistic; - - public class OpenIdProvider extends ContainerLifeCycle - { -+ private static final Logger LOG = Log.getLogger(OpenIdProvider.class); -+ - private static final String CONFIG_PATH = "/.well-known/openid-configuration"; - private static final String AUTH_PATH = "/auth"; - private static final String TOKEN_PATH = "/token"; -+ private static final String END_SESSION_PATH = "/end_session"; - private final Map issuedAuthCodes = new HashMap<>(); - - protected final String clientId; - protected final String clientSecret; - protected final List redirectUris = new ArrayList<>(); -- -+ private final ServerConnector connector; -+ private final Server server; -+ private int port = 0; - private String provider; -- private Server server; -- private ServerConnector connector; -+ private User preAuthedUser; -+ private final CounterStatistic loggedInUsers = new CounterStatistic(); -+ private long _idTokenDuration = Duration.ofSeconds(10).toMillis(); -+ -+ public static void main(String[] args) throws Exception -+ { -+ String clientId = "CLIENT_ID123"; -+ String clientSecret = "PASSWORD123"; -+ int port = 5771; -+ String redirectUri = "http://localhost:8080/j_security_check"; -+ -+ OpenIdProvider openIdProvider = new OpenIdProvider(clientId, clientSecret); -+ openIdProvider.addRedirectUri(redirectUri); -+ openIdProvider.setPort(port); -+ openIdProvider.start(); -+ try -+ { -+ openIdProvider.join(); -+ } -+ finally -+ { -+ openIdProvider.stop(); -+ } -+ } - - public OpenIdProvider(String clientId, String clientSecret) - { -@@ -69,25 +100,67 @@ public class OpenIdProvider extends ContainerLifeCycle - - ServletContextHandler contextHandler = new ServletContextHandler(); - contextHandler.setContextPath("/"); -- contextHandler.addServlet(new ServletHolder(new OpenIdConfigServlet()), CONFIG_PATH); -- contextHandler.addServlet(new ServletHolder(new OpenIdAuthEndpoint()), AUTH_PATH); -- contextHandler.addServlet(new ServletHolder(new OpenIdTokenEndpoint()), TOKEN_PATH); -+ contextHandler.addServlet(new ServletHolder(new ConfigServlet()), CONFIG_PATH); -+ contextHandler.addServlet(new ServletHolder(new AuthEndpoint()), AUTH_PATH); -+ contextHandler.addServlet(new ServletHolder(new TokenEndpoint()), TOKEN_PATH); -+ contextHandler.addServlet(new ServletHolder(new EndSessionEndpoint()), END_SESSION_PATH); - server.setHandler(contextHandler); - - addBean(server); - } - -+ public void setIdTokenDuration(long duration) -+ { -+ _idTokenDuration = duration; -+ } -+ -+ public long getIdTokenDuration() -+ { -+ return _idTokenDuration; -+ } -+ -+ public void join() throws InterruptedException -+ { -+ server.join(); -+ } -+ -+ public OpenIdConfiguration getOpenIdConfiguration() -+ { -+ String provider = getProvider(); -+ String authEndpoint = provider + AUTH_PATH; -+ String tokenEndpoint = provider + TOKEN_PATH; -+ return new OpenIdConfiguration(provider, authEndpoint, tokenEndpoint, clientId, clientSecret, null); -+ } -+ -+ public CounterStatistic getLoggedInUsers() -+ { -+ return loggedInUsers; -+ } -+ - @Override - protected void doStart() throws Exception - { -+ connector.setPort(port); - super.doStart(); - provider = "http://localhost:" + connector.getLocalPort(); - } - -- public String getProvider() -+ public void setPort(int port) - { -- if (!isStarted()) -+ if (isStarted()) - throw new IllegalStateException(); -+ this.port = port; -+ } -+ -+ public void setUser(User user) -+ { -+ this.preAuthedUser = user; -+ } -+ -+ public String getProvider() -+ { -+ if (!isStarted() && port == 0) -+ throw new IllegalStateException("Port of OpenIdProvider not configured"); - return provider; - } - -@@ -96,10 +169,10 @@ public class OpenIdProvider extends ContainerLifeCycle - redirectUris.add(uri); - } - -- public class OpenIdAuthEndpoint extends HttpServlet -+ public class AuthEndpoint extends HttpServlet - { - @Override -- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException -+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException - { - if (!clientId.equals(req.getParameter("client_id"))) - { -@@ -110,12 +183,13 @@ public class OpenIdProvider extends ContainerLifeCycle - String redirectUri = req.getParameter("redirect_uri"); - if (!redirectUris.contains(redirectUri)) - { -+ LOG.warn("invalid redirectUri {}", redirectUri); - resp.sendError(HttpServletResponse.SC_FORBIDDEN, "invalid redirect_uri"); - return; - } - - String scopeString = req.getParameter("scope"); -- List scopes = (scopeString == null) ? Collections.emptyList() : Arrays.asList(StringUtil.csvSplit(scopeString)); -+ List scopes = (scopeString == null) ? Collections.emptyList() : Arrays.asList(scopeString.split(" ")); - if (!scopes.contains("openid")) - { - resp.sendError(HttpServletResponse.SC_FORBIDDEN, "no openid scope"); -@@ -135,20 +209,75 @@ public class OpenIdProvider extends ContainerLifeCycle - return; - } - -+ if (preAuthedUser == null) -+ { -+ PrintWriter writer = resp.getWriter(); -+ resp.setContentType("text/html"); -+ writer.println("

Login to OpenID Connect Provider

"); -+ writer.println("
"); -+ writer.println(""); -+ writer.println(""); -+ writer.println(""); -+ writer.println(""); -+ writer.println("
"); -+ } -+ else -+ { -+ redirectUser(req, preAuthedUser, redirectUri, state); -+ } -+ } -+ -+ @Override -+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException -+ { -+ String redirectUri = req.getParameter("redirectUri"); -+ if (!redirectUris.contains(redirectUri)) -+ { -+ resp.sendError(HttpServletResponse.SC_FORBIDDEN, "invalid redirect_uri"); -+ return; -+ } -+ -+ String state = req.getParameter("state"); -+ if (state == null) -+ { -+ resp.sendError(HttpServletResponse.SC_FORBIDDEN, "no state param"); -+ return; -+ } -+ -+ String username = req.getParameter("username"); -+ if (username == null) -+ { -+ resp.sendError(HttpServletResponse.SC_FORBIDDEN, "no username"); -+ return; -+ } -+ -+ User user = new User(username); -+ redirectUser(req, user, redirectUri, state); -+ } -+ -+ public void redirectUser(HttpServletRequest request, User user, String redirectUri, String state) throws IOException -+ { - String authCode = UUID.randomUUID().toString().replace("-", ""); -- User user = new User(123456789, "Alice"); - issuedAuthCodes.put(authCode, user); - -- final Request baseRequest = Request.getBaseRequest(req); -- final Response baseResponse = baseRequest.getResponse(); -- redirectUri += "?code=" + authCode + "&state=" + state; -- int redirectCode = (baseRequest.getHttpVersion().getVersion() < HttpVersion.HTTP_1_1.getVersion() -- ? HttpServletResponse.SC_MOVED_TEMPORARILY : HttpServletResponse.SC_SEE_OTHER); -- baseResponse.sendRedirect(redirectCode, resp.encodeRedirectURL(redirectUri)); -+ try -+ { -+ final Request baseRequest = Objects.requireNonNull(Request.getBaseRequest(request)); -+ final Response baseResponse = baseRequest.getResponse(); -+ redirectUri += "?code=" + authCode + "&state=" + state; -+ int redirectCode = (baseRequest.getHttpVersion().getVersion() < HttpVersion.HTTP_1_1.getVersion() -+ ? HttpServletResponse.SC_MOVED_TEMPORARILY : HttpServletResponse.SC_SEE_OTHER); -+ baseResponse.sendRedirect(redirectCode, baseResponse.encodeRedirectURL(redirectUri)); -+ } -+ catch (Throwable t) -+ { -+ issuedAuthCodes.remove(authCode); -+ throw t; -+ } - } - } - -- public class OpenIdTokenEndpoint extends HttpServlet -+ private class TokenEndpoint extends HttpServlet - { - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException -@@ -173,45 +302,79 @@ public class OpenIdProvider extends ContainerLifeCycle - } - - String accessToken = "ABCDEFG"; -- long expiry = System.currentTimeMillis() + Duration.ofMinutes(10).toMillis(); -+ long accessTokenDuration = Duration.ofMinutes(10).getSeconds(); - String response = "{" + - "\"access_token\": \"" + accessToken + "\"," + -- "\"id_token\": \"" + JwtEncoder.encode(user.getIdToken()) + "\"," + -- "\"expires_in\": " + expiry + "," + -+ "\"id_token\": \"" + JwtEncoder.encode(user.getIdToken(provider, clientId, _idTokenDuration)) + "\"," + -+ "\"expires_in\": " + accessTokenDuration + "," + - "\"token_type\": \"Bearer\"" + - "}"; - -+ loggedInUsers.increment(); - resp.setContentType("text/plain"); - resp.getWriter().print(response); - } - } - -- public class OpenIdConfigServlet extends HttpServlet -+ private class EndSessionEndpoint extends HttpServlet - { - @Override -- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException -+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException -+ { -+ doPost(req, resp); -+ } -+ -+ @Override -+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException -+ { -+ String idToken = req.getParameter("id_token_hint"); -+ if (idToken == null) -+ { -+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "no id_token_hint"); -+ return; -+ } -+ -+ String logoutRedirect = req.getParameter("post_logout_redirect_uri"); -+ if (logoutRedirect == null) -+ { -+ resp.setStatus(HttpServletResponse.SC_OK); -+ resp.getWriter().println("logout success on end_session_endpoint"); -+ return; -+ } -+ -+ loggedInUsers.decrement(); -+ resp.setContentType("text/plain"); -+ resp.sendRedirect(logoutRedirect); -+ } -+ } -+ -+ private class ConfigServlet extends HttpServlet -+ { -+ @Override -+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException - { - String discoveryDocument = "{" + - "\"issuer\": \"" + provider + "\"," + - "\"authorization_endpoint\": \"" + provider + AUTH_PATH + "\"," + - "\"token_endpoint\": \"" + provider + TOKEN_PATH + "\"," + -+ "\"end_session_endpoint\": \"" + provider + END_SESSION_PATH + "\"," + - "}"; - - resp.getWriter().write(discoveryDocument); - } - } - -- public class User -+ public static class User - { -- private long subject; -- private String name; -+ private final String subject; -+ private final String name; - - public User(String name) - { -- this(new Random().nextLong(), name); -+ this(UUID.nameUUIDFromBytes(name.getBytes()).toString(), name); - } - -- public User(long subject, String name) -+ public User(String subject, String name) - { - this.subject = subject; - this.name = name; -@@ -222,10 +385,29 @@ public class OpenIdProvider extends ContainerLifeCycle - return name; - } - -- public String getIdToken() -+ public String getSubject() -+ { -+ return subject; -+ } -+ -+ public String getIdToken(String provider, String clientId, long duration) -+ { -+ long expiryTime = Instant.now().plusMillis(duration).getEpochSecond(); -+ return JwtEncoder.createIdToken(provider, clientId, subject, name, expiryTime); -+ } -+ -+ @Override -+ public boolean equals(Object obj) -+ { -+ if (!(obj instanceof User)) -+ return false; -+ return Objects.equals(subject, ((User)obj).subject) && Objects.equals(name, ((User)obj).name); -+ } -+ -+ @Override -+ public int hashCode() - { -- long expiry = System.currentTimeMillis() + Duration.ofMinutes(1).toMillis(); -- return JwtEncoder.createIdToken(provider, clientId, Long.toString(subject), name, expiry); -+ return Objects.hash(subject, name); - } - } - } diff -Nru jetty9-9.4.50/debian/patches/CVE-2023-44487.patch jetty9-9.4.57/debian/patches/CVE-2023-44487.patch --- jetty9-9.4.50/debian/patches/CVE-2023-44487.patch 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/patches/CVE-2023-44487.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,622 +0,0 @@ -From: Markus Koschany -Date: Thu, 26 Oct 2023 20:25:08 +0200 -Subject: CVE-2023-44487 - -Origin: https://github.com/jetty/jetty.project/commit/2a512c2461282fa790a4c89b8ab5b7df15445b66 ---- - .../jetty/http2/parser/ContinuationBodyParser.java | 36 +++++++++++---- - .../jetty/http2/parser/HeaderBlockFragments.java | 33 +++++++++---- - .../jetty/http2/parser/HeadersBodyParser.java | 37 +++++++++++---- - .../org/eclipse/jetty/http2/parser/Parser.java | 2 +- - .../jetty/http2/parser/PushPromiseBodyParser.java | 13 ++++-- - .../jetty/http2/parser/ResetBodyParser.java | 8 ++-- - .../jetty/http2/parser/SettingsBodyParser.java | 29 ++++++++---- - .../jetty/http2/parser/UnknownBodyParser.java | 1 - - .../jetty/http2/frames/ContinuationParseTest.java | 54 ++++++++++++++++++++++ - .../eclipse/jetty/http2/frames/FrameFloodTest.java | 31 +++++++++++-- - .../http2/frames/SettingsGenerateParseTest.java | 16 +++---- - .../AbstractHTTP2ServerConnectionFactory.java | 2 +- - 12 files changed, 204 insertions(+), 58 deletions(-) - -diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ContinuationBodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ContinuationBodyParser.java -index 04d26d1..8f32800 100644 ---- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ContinuationBodyParser.java -+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ContinuationBodyParser.java -@@ -80,16 +80,28 @@ public class ContinuationBodyParser extends BodyParser - int remaining = buffer.remaining(); - if (remaining < length) - { -- headerBlockFragments.storeFragment(buffer, remaining, false); -+ ContinuationFrame frame = new ContinuationFrame(getStreamId(), false); -+ if (!rateControlOnEvent(frame)) -+ return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_continuation_frame_rate"); -+ -+ if (!headerBlockFragments.storeFragment(buffer, remaining, false)) -+ return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_continuation_stream"); -+ - length -= remaining; - break; - } - else - { -- boolean last = hasFlag(Flags.END_HEADERS); -- headerBlockFragments.storeFragment(buffer, length, last); -+ boolean endHeaders = hasFlag(Flags.END_HEADERS); -+ ContinuationFrame frame = new ContinuationFrame(getStreamId(), endHeaders); -+ if (!rateControlOnEvent(frame)) -+ return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_continuation_frame_rate"); -+ -+ if (!headerBlockFragments.storeFragment(buffer, length, endHeaders)) -+ return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_continuation_stream"); -+ - reset(); -- if (last) -+ if (endHeaders) - return onHeaders(buffer); - return true; - } -@@ -107,17 +119,21 @@ public class ContinuationBodyParser extends BodyParser - { - ByteBuffer headerBlock = headerBlockFragments.complete(); - MetaData metaData = headerBlockParser.parse(headerBlock, headerBlock.remaining()); -- if (metaData == null) -- return true; -+ HeadersFrame frame = new HeadersFrame(getStreamId(), metaData, headerBlockFragments.getPriorityFrame(), headerBlockFragments.isEndStream()); -+ headerBlockFragments.reset(); -+ - if (metaData == HeaderBlockParser.SESSION_FAILURE) - return false; -- HeadersFrame frame = new HeadersFrame(getStreamId(), metaData, headerBlockFragments.getPriorityFrame(), headerBlockFragments.isEndStream()); -- if (metaData == HeaderBlockParser.STREAM_FAILURE) -+ -+ if (metaData != HeaderBlockParser.STREAM_FAILURE) -+ { -+ notifyHeaders(frame); -+ } -+ else - { - if (!rateControlOnEvent(frame)) -- return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_continuation_frame_rate"); -+ return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_headers_frame_rate"); - } -- notifyHeaders(frame); - return true; - } - -diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockFragments.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockFragments.java -index be63ba4..3c69d2d 100644 ---- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockFragments.java -+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockFragments.java -@@ -24,22 +24,40 @@ import org.eclipse.jetty.http2.frames.PriorityFrame; - - public class HeaderBlockFragments - { -+ private final int maxCapacity; - private PriorityFrame priorityFrame; -- private boolean endStream; - private int streamId; -+ private boolean endStream; - private ByteBuffer storage; - -- public void storeFragment(ByteBuffer fragment, int length, boolean last) -+ public HeaderBlockFragments(int maxCapacity) -+ { -+ this.maxCapacity = maxCapacity; -+ } -+ -+ void reset() -+ { -+ priorityFrame = null; -+ streamId = 0; -+ endStream = false; -+ storage = null; -+ } -+ -+ public boolean storeFragment(ByteBuffer fragment, int length, boolean last) - { - if (storage == null) - { -- int space = last ? length : length * 2; -- storage = ByteBuffer.allocate(space); -+ if (length > maxCapacity) -+ return false; -+ int capacity = last ? length : length * 2; -+ storage = ByteBuffer.allocate(capacity); - } - - // Grow the storage if necessary. - if (storage.remaining() < length) - { -+ if (storage.position() + length > maxCapacity) -+ return false; - int space = last ? length : length * 2; - int capacity = storage.position() + space; - ByteBuffer newStorage = ByteBuffer.allocate(capacity); -@@ -53,6 +71,7 @@ public class HeaderBlockFragments - fragment.limit(fragment.position() + length); - storage.put(fragment); - fragment.limit(limit); -+ return true; - } - - public PriorityFrame getPriorityFrame() -@@ -77,10 +96,8 @@ public class HeaderBlockFragments - - public ByteBuffer complete() - { -- ByteBuffer result = storage; -- storage = null; -- result.flip(); -- return result; -+ storage.flip(); -+ return storage; - } - - public int getStreamId() -diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeadersBodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeadersBodyParser.java -index b38a286..e222420 100644 ---- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeadersBodyParser.java -+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeadersBodyParser.java -@@ -76,8 +76,15 @@ public class HeadersBodyParser extends BodyParser - } - else - { -- headerBlockFragments.setStreamId(getStreamId()); -- headerBlockFragments.setEndStream(isEndStream()); -+ if (headerBlockFragments.getStreamId() != 0) -+ { -+ connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_headers_frame"); -+ } -+ else -+ { -+ headerBlockFragments.setStreamId(getStreamId()); -+ headerBlockFragments.setEndStream(isEndStream()); -+ } - } - } - -@@ -172,6 +179,18 @@ public class HeadersBodyParser extends BodyParser - break; - } - case HEADERS: -+ { -+ if (!hasFlag(Flags.END_HEADERS)) -+ { -+ headerBlockFragments.setStreamId(getStreamId()); -+ headerBlockFragments.setEndStream(isEndStream()); -+ if (hasFlag(Flags.PRIORITY)) -+ headerBlockFragments.setPriorityFrame(new PriorityFrame(getStreamId(), parentStreamId, weight, exclusive)); -+ } -+ state = State.HEADER_BLOCK; -+ break; -+ } -+ case HEADER_BLOCK: - { - if (hasFlag(Flags.END_HEADERS)) - { -@@ -192,7 +211,7 @@ public class HeadersBodyParser extends BodyParser - { - HeadersFrame frame = new HeadersFrame(getStreamId(), metaData, null, isEndStream()); - if (!rateControlOnEvent(frame)) -- connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_headers_frame_rate"); -+ return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_headers_frame_rate"); - } - } - } -@@ -201,16 +220,14 @@ public class HeadersBodyParser extends BodyParser - int remaining = buffer.remaining(); - if (remaining < length) - { -- headerBlockFragments.storeFragment(buffer, remaining, false); -+ if (!headerBlockFragments.storeFragment(buffer, remaining, false)) -+ return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_headers_frame"); - length -= remaining; - } - else - { -- headerBlockFragments.setStreamId(getStreamId()); -- headerBlockFragments.setEndStream(isEndStream()); -- if (hasFlag(Flags.PRIORITY)) -- headerBlockFragments.setPriorityFrame(new PriorityFrame(getStreamId(), parentStreamId, weight, exclusive)); -- headerBlockFragments.storeFragment(buffer, length, false); -+ if (!headerBlockFragments.storeFragment(buffer, length, false)) -+ return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_headers_frame"); - state = State.PADDING; - loop = paddingLength == 0; - } -@@ -254,6 +271,6 @@ public class HeadersBodyParser extends BodyParser - - private enum State - { -- PREPARE, PADDING_LENGTH, EXCLUSIVE, PARENT_STREAM_ID, PARENT_STREAM_ID_BYTES, WEIGHT, HEADERS, PADDING -+ PREPARE, PADDING_LENGTH, EXCLUSIVE, PARENT_STREAM_ID, PARENT_STREAM_ID_BYTES, WEIGHT, HEADERS, HEADER_BLOCK, PADDING - } - } -diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java -index 8044e71..5e2dfd0 100644 ---- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java -+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java -@@ -78,7 +78,7 @@ public class Parser - Listener listener = wrapper.apply(this.listener); - unknownBodyParser = new UnknownBodyParser(headerParser, listener); - HeaderBlockParser headerBlockParser = new HeaderBlockParser(headerParser, byteBufferPool, hpackDecoder, unknownBodyParser); -- HeaderBlockFragments headerBlockFragments = new HeaderBlockFragments(); -+ HeaderBlockFragments headerBlockFragments = new HeaderBlockFragments(hpackDecoder.getMaxHeaderListSize()); - bodyParsers[FrameType.DATA.getType()] = new DataBodyParser(headerParser, listener); - bodyParsers[FrameType.HEADERS.getType()] = new HeadersBodyParser(headerParser, listener, headerBlockParser, headerBlockFragments); - bodyParsers[FrameType.PRIORITY.getType()] = new PriorityBodyParser(headerParser, listener); -diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PushPromiseBodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PushPromiseBodyParser.java -index c09405d..f02107d 100644 ---- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PushPromiseBodyParser.java -+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PushPromiseBodyParser.java -@@ -23,6 +23,7 @@ import java.nio.ByteBuffer; - import org.eclipse.jetty.http.MetaData; - import org.eclipse.jetty.http2.ErrorCode; - import org.eclipse.jetty.http2.Flags; -+import org.eclipse.jetty.http2.frames.HeadersFrame; - import org.eclipse.jetty.http2.frames.PushPromiseFrame; - - public class PushPromiseBodyParser extends BodyParser -@@ -70,13 +71,9 @@ public class PushPromiseBodyParser extends BodyParser - length = getBodyLength(); - - if (isPadding()) -- { - state = State.PADDING_LENGTH; -- } - else -- { - state = State.STREAM_ID; -- } - break; - } - case PADDING_LENGTH: -@@ -132,7 +129,15 @@ public class PushPromiseBodyParser extends BodyParser - state = State.PADDING; - loop = paddingLength == 0; - if (metaData != HeaderBlockParser.STREAM_FAILURE) -+ { - onPushPromise(streamId, metaData); -+ } -+ else -+ { -+ HeadersFrame frame = new HeadersFrame(getStreamId(), metaData, null, isEndStream()); -+ if (!rateControlOnEvent(frame)) -+ return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_headers_frame_rate"); -+ } - } - break; - } -diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ResetBodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ResetBodyParser.java -index bcc80f1..19b072a 100644 ---- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ResetBodyParser.java -+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ResetBodyParser.java -@@ -63,7 +63,7 @@ public class ResetBodyParser extends BodyParser - { - if (buffer.remaining() >= 4) - { -- return onReset(buffer.getInt()); -+ return onReset(buffer, buffer.getInt()); - } - else - { -@@ -78,7 +78,7 @@ public class ResetBodyParser extends BodyParser - --cursor; - error += currByte << (8 * cursor); - if (cursor == 0) -- return onReset(error); -+ return onReset(buffer, error); - break; - } - default: -@@ -90,9 +90,11 @@ public class ResetBodyParser extends BodyParser - return false; - } - -- private boolean onReset(int error) -+ private boolean onReset(ByteBuffer buffer, int error) - { - ResetFrame frame = new ResetFrame(getStreamId(), error); -+ if (!rateControlOnEvent(frame)) -+ return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_rst_stream_frame_rate"); - reset(); - notifyReset(frame); - return true; -diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/SettingsBodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/SettingsBodyParser.java -index 5ee0252..fe9eaf0 100644 ---- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/SettingsBodyParser.java -+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/SettingsBodyParser.java -@@ -73,12 +73,22 @@ public class SettingsBodyParser extends BodyParser - @Override - protected void emptyBody(ByteBuffer buffer) - { -+ if (!validateFrame(buffer, getStreamId(), 0)) -+ return; - boolean isReply = hasFlag(Flags.ACK); - SettingsFrame frame = new SettingsFrame(Collections.emptyMap(), isReply); -- if (!isReply && !rateControlOnEvent(frame)) -- connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_settings_frame_rate"); -- else -- onSettings(frame); -+ onSettings(buffer, frame); -+ } -+ -+ private boolean validateFrame(ByteBuffer buffer, int streamId, int bodyLength) -+ { -+ // SPEC: wrong streamId is treated as connection error. -+ if (streamId != 0) -+ return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_settings_frame"); -+ // SPEC: reply with body is treated as connection error. -+ if (hasFlag(Flags.ACK) && bodyLength > 0) -+ return connectionFailure(buffer, ErrorCode.FRAME_SIZE_ERROR.code, "invalid_settings_frame"); -+ return true; - } - - @Override -@@ -95,9 +105,8 @@ public class SettingsBodyParser extends BodyParser - { - case PREPARE: - { -- // SPEC: wrong streamId is treated as connection error. -- if (streamId != 0) -- return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_settings_frame"); -+ if (!validateFrame(buffer, streamId, bodyLength)) -+ return false; - length = bodyLength; - settings = new HashMap<>(); - state = State.SETTING_ID; -@@ -211,11 +220,13 @@ public class SettingsBodyParser extends BodyParser - return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_settings_max_frame_size"); - - SettingsFrame frame = new SettingsFrame(settings, hasFlag(Flags.ACK)); -- return onSettings(frame); -+ return onSettings(buffer, frame); - } - -- private boolean onSettings(SettingsFrame frame) -+ private boolean onSettings(ByteBuffer buffer, SettingsFrame frame) - { -+ if (!rateControlOnEvent(frame)) -+ return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_settings_frame_rate"); - reset(); - notifySettings(frame); - return true; -diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/UnknownBodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/UnknownBodyParser.java -index 86a8628..23ca493 100644 ---- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/UnknownBodyParser.java -+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/UnknownBodyParser.java -@@ -40,7 +40,6 @@ public class UnknownBodyParser extends BodyParser - boolean parsed = cursor == 0; - if (parsed && !rateControlOnEvent(new UnknownFrame(getFrameType()))) - return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_unknown_frame_rate"); -- - return parsed; - } - -diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java -index 9fb1bbf..54a7cde 100644 ---- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java -+++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java -@@ -22,6 +22,8 @@ import java.nio.ByteBuffer; - import java.util.ArrayList; - import java.util.List; - import java.util.function.UnaryOperator; -+import java.util.concurrent.atomic.AtomicBoolean; -+import java.util.stream.IntStream; - - import org.eclipse.jetty.http.HostPortHttpField; - import org.eclipse.jetty.http.HttpField; -@@ -38,6 +40,8 @@ import org.eclipse.jetty.io.ByteBufferPool; - import org.eclipse.jetty.io.MappedByteBufferPool; - import org.junit.jupiter.api.Test; - -+import static org.hamcrest.MatcherAssert.assertThat; -+import static org.hamcrest.Matchers.greaterThan; - import static org.junit.jupiter.api.Assertions.assertEquals; - import static org.junit.jupiter.api.Assertions.assertNull; - import static org.junit.jupiter.api.Assertions.assertTrue; -@@ -160,4 +164,54 @@ public class ContinuationParseTest - assertNull(priority); - } - } -+ -+ @Test -+ public void testLargeHeadersBlock() throws Exception -+ { -+ // Use a ByteBufferPool with a small factor, so that the accumulation buffer is not too large. -+ ByteBufferPool byteBufferPool = new MappedByteBufferPool(128); -+ // A small max headers size, used for both accumulation and decoding. -+ int maxHeadersSize = 512; -+ Parser parser = new Parser(byteBufferPool, maxHeadersSize); -+ // Specify headers block size to generate CONTINUATION frames. -+ int maxHeadersBlockFragment = 128; -+ HeadersGenerator generator = new HeadersGenerator(new HeaderGenerator(), new HpackEncoder(), maxHeadersBlockFragment); -+ -+ int streamId = 13; -+ HttpFields fields = new HttpFields(); -+ fields.put("Accept", "text/html"); -+ // Large header that generates a large headers block. -+ StringBuilder large = new StringBuilder(); -+ IntStream.range(0, 256).forEach(i -> large.append("Jetty")); -+ fields.put("User-Agent", large.toString()); -+ -+ MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP.asString(), new HostPortHttpField("localhost:8080"), "/path", HttpVersion.HTTP_2, fields, -1); -+ -+ ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool); -+ generator.generateHeaders(lease, streamId, metaData, null, true); -+ List byteBuffers = lease.getByteBuffers(); -+ assertThat(byteBuffers.stream().mapToInt(ByteBuffer::remaining).sum(), greaterThan(maxHeadersSize)); -+ -+ AtomicBoolean failed = new AtomicBoolean(); -+ parser.init(new Parser.Listener.Adapter() -+ { -+ @Override -+ public void onConnectionFailure(int error, String reason) -+ { -+ failed.set(true); -+ } -+ }); -+ // Set a large max headers size for decoding, to ensure -+ // the failure is due to accumulation, not decoding. -+ parser.getHpackDecoder().setMaxHeaderListSize(10 * maxHeadersSize); -+ -+ for (ByteBuffer byteBuffer : byteBuffers) -+ { -+ parser.parse(byteBuffer); -+ if (failed.get()) -+ break; -+ } -+ -+ assertTrue(failed.get()); -+ } - } -diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java -index f9ee47f..2a1b187 100644 ---- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java -+++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java -@@ -95,21 +95,29 @@ public class FrameFloodTest - } - - @Test -- public void testSettingsFrameFlood() -+ public void testEmptySettingsFrameFlood() - { - byte[] payload = new byte[0]; - testFrameFlood(null, frameFrom(payload.length, FrameType.SETTINGS.getType(), 0, 0, payload)); - } - -+ @Test -+ public void testSettingsFrameFlood() -+ { -+ // | Key0 | Key1 | Value0 | Value1 | Value2 | Value3 | -+ byte[] payload = new byte[]{0, 8, 0, 0, 0, 1}; -+ testFrameFlood(null, frameFrom(payload.length, FrameType.SETTINGS.getType(), 0, 0, payload)); -+ } -+ - @Test - public void testPingFrameFlood() - { - byte[] payload = {0, 0, 0, 0, 0, 0, 0, 0}; - testFrameFlood(null, frameFrom(payload.length, FrameType.PING.getType(), 0, 0, payload)); - } -- -+ - @Test -- public void testContinuationFrameFlood() -+ public void testEmptyContinuationFrameFlood() - { - int streamId = 13; - byte[] headersPayload = new byte[0]; -@@ -118,6 +126,23 @@ public class FrameFloodTest - testFrameFlood(headersBytes, frameFrom(continuationPayload.length, FrameType.CONTINUATION.getType(), 0, streamId, continuationPayload)); - } - -+ @Test -+ public void testContinuationFrameFlood() -+ { -+ int streamId = 13; -+ byte[] headersPayload = new byte[0]; -+ byte[] headersBytes = frameFrom(headersPayload.length, FrameType.HEADERS.getType(), 0, streamId, headersPayload); -+ byte[] continuationPayload = new byte[1]; -+ testFrameFlood(headersBytes, frameFrom(continuationPayload.length, FrameType.CONTINUATION.getType(), 0, streamId, continuationPayload)); -+ } -+ -+ @Test -+ public void testResetStreamFrameFlood() -+ { -+ byte[] payload = {0, 0, 0, 0}; -+ testFrameFlood(null, frameFrom(payload.length, FrameType.RST_STREAM.getType(), 0, 13, payload)); -+ } -+ - @Test - public void testUnknownFrameFlood() - { -diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java -index 83ab018..4cc6a45 100644 ---- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java -+++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java -@@ -36,6 +36,7 @@ import org.eclipse.jetty.io.MappedByteBufferPool; - import org.junit.jupiter.api.Test; - - import static org.junit.jupiter.api.Assertions.assertEquals; -+import static org.junit.jupiter.api.Assertions.assertFalse; - import static org.junit.jupiter.api.Assertions.assertTrue; - - public class SettingsGenerateParseTest -@@ -45,8 +46,7 @@ public class SettingsGenerateParseTest - @Test - public void testGenerateParseNoSettings() - { -- -- List frames = testGenerateParse(Collections.emptyMap()); -+ List frames = testGenerateParse(Collections.emptyMap(), true); - assertEquals(1, frames.size()); - SettingsFrame frame = frames.get(0); - assertEquals(0, frame.getSettings().size()); -@@ -63,7 +63,7 @@ public class SettingsGenerateParseTest - int key2 = 19; - Integer value2 = 23; - settings1.put(key2, value2); -- List frames = testGenerateParse(settings1); -+ List frames = testGenerateParse(settings1, false); - assertEquals(1, frames.size()); - SettingsFrame frame = frames.get(0); - Map settings2 = frame.getSettings(); -@@ -72,7 +72,7 @@ public class SettingsGenerateParseTest - assertEquals(value2, settings2.get(key2)); - } - -- private List testGenerateParse(Map settings) -+ private List testGenerateParse(Map settings, boolean reply) - { - SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator()); - -@@ -91,7 +91,7 @@ public class SettingsGenerateParseTest - for (int i = 0; i < 2; ++i) - { - ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool); -- generator.generateSettings(lease, settings, true); -+ generator.generateSettings(lease, settings, reply); - - frames.clear(); - for (ByteBuffer buffer : lease.getByteBuffers()) -@@ -125,7 +125,7 @@ public class SettingsGenerateParseTest - Map settings1 = new HashMap<>(); - settings1.put(13, 17); - ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool); -- generator.generateSettings(lease, settings1, true); -+ generator.generateSettings(lease, settings1, false); - // Modify the length of the frame to make it invalid - ByteBuffer bytes = lease.getByteBuffers().get(0); - bytes.putShort(1, (short)(bytes.getShort(1) - 1)); -@@ -166,7 +166,7 @@ public class SettingsGenerateParseTest - for (int i = 0; i < 2; ++i) - { - ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool); -- generator.generateSettings(lease, settings1, true); -+ generator.generateSettings(lease, settings1, false); - - frames.clear(); - for (ByteBuffer buffer : lease.getByteBuffers()) -@@ -182,7 +182,7 @@ public class SettingsGenerateParseTest - Map settings2 = frame.getSettings(); - assertEquals(1, settings2.size()); - assertEquals(value, settings2.get(key)); -- assertTrue(frame.isReply()); -+ assertFalse(frame.isReply()); - } - } - -diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java -index 9d6306e..554ecfd 100644 ---- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java -+++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java -@@ -60,7 +60,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne - private int maxHeaderBlockFragment = 0; - private int maxFrameLength = Frame.DEFAULT_MAX_LENGTH; - private int maxSettingsKeys = SettingsFrame.DEFAULT_MAX_KEYS; -- private RateControl.Factory rateControlFactory = new WindowRateControl.Factory(50); -+ private RateControl.Factory rateControlFactory = new WindowRateControl.Factory(128); - private FlowControlStrategy.Factory flowControlStrategyFactory = () -> new BufferingFlowControlStrategy(0.5F); - private long streamIdleTimeout; - diff -Nru jetty9-9.4.50/debian/patches/CVE-2024-22201.patch jetty9-9.4.57/debian/patches/CVE-2024-22201.patch --- jetty9-9.4.50/debian/patches/CVE-2024-22201.patch 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/patches/CVE-2024-22201.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,138 +0,0 @@ -From: Markus Koschany -Date: Wed, 20 Mar 2024 09:28:22 +0100 -Subject: CVE-2024-22201 - -Origin: https://github.com/jetty/jetty.project/commit/86586df0a8a4d9c6b5af9a621ad1adf1b494d39b -Bug-Debian: https://bugs.debian.org/1064923 ---- - .../jetty/http2/client/IdleTimeoutTest.java | 56 ++++++++++++++++++++++ - .../java/org/eclipse/jetty/http2/HTTP2Session.java | 14 +++++- - 2 files changed, 69 insertions(+), 1 deletion(-) - -diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/IdleTimeoutTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/IdleTimeoutTest.java -index 3871b32..5e65cbb 100644 ---- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/IdleTimeoutTest.java -+++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/IdleTimeoutTest.java -@@ -19,7 +19,11 @@ - package org.eclipse.jetty.http2.client; - - import java.io.IOException; -+import java.net.InetSocketAddress; - import java.nio.ByteBuffer; -+import java.nio.channels.SelectionKey; -+import java.nio.channels.SocketChannel; -+import java.time.Duration; - import java.util.concurrent.CountDownLatch; - import java.util.concurrent.TimeUnit; - import java.util.concurrent.TimeoutException; -@@ -43,7 +47,10 @@ import org.eclipse.jetty.http2.frames.DataFrame; - import org.eclipse.jetty.http2.frames.GoAwayFrame; - import org.eclipse.jetty.http2.frames.HeadersFrame; - import org.eclipse.jetty.http2.frames.ResetFrame; -+import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory; - import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory; -+import org.eclipse.jetty.io.ManagedSelector; -+import org.eclipse.jetty.io.SocketChannelEndPoint; - import org.eclipse.jetty.server.HttpConfiguration; - import org.eclipse.jetty.server.Server; - import org.eclipse.jetty.server.ServerConnector; -@@ -57,7 +64,9 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool; - import org.hamcrest.Matchers; - import org.junit.jupiter.api.Test; - -+import static org.awaitility.Awaitility.await; - import static org.hamcrest.MatcherAssert.assertThat; -+import static org.hamcrest.Matchers.is; - import static org.junit.jupiter.api.Assertions.assertEquals; - import static org.junit.jupiter.api.Assertions.assertFalse; - import static org.junit.jupiter.api.Assertions.assertTrue; -@@ -681,6 +690,53 @@ public class IdleTimeoutTest extends AbstractTest - assertThat(((ISession)client).updateSendWindow(0), Matchers.greaterThan(0)); - } - -+ @Test -+ public void testIdleTimeoutWhenCongested() throws Exception -+ { -+ long idleTimeout = 1000; -+ HTTP2CServerConnectionFactory h2c = new HTTP2CServerConnectionFactory(new HttpConfiguration()); -+ prepareServer(h2c); -+ server.removeConnector(connector); -+ connector = new ServerConnector(server, 1, 1, h2c) -+ { -+ @Override -+ protected SocketChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) -+ { -+ SocketChannelEndPoint endpoint = new SocketChannelEndPoint(channel, selectSet, key, getScheduler()) -+ { -+ @Override -+ public boolean flush(ByteBuffer... buffers) -+ { -+ // Fake TCP congestion. -+ return false; -+ } -+ -+ @Override -+ protected void onIncompleteFlush() -+ { -+ // Do nothing here to avoid spin loop, -+ // since the network is actually writable, -+ // as we are only faking TCP congestion. -+ } -+ }; -+ endpoint.setIdleTimeout(getIdleTimeout()); -+ return endpoint; -+ } -+ }; -+ connector.setIdleTimeout(idleTimeout); -+ server.addConnector(connector); -+ server.start(); -+ -+ prepareClient(); -+ client.start(); -+ -+ InetSocketAddress address = new InetSocketAddress("localhost", connector.getLocalPort()); -+ // The connect() will complete exceptionally. -+ client.connect(address, new Session.Listener.Adapter(), new Promise.Completable<>()); -+ -+ await().atMost(Duration.ofMillis(5 * idleTimeout)).until(() -> connector.getConnectedEndPoints().size(), is(0)); -+ } -+ - private void sleep(long value) - { - try -diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java -index a1c5ace..bfbc02b 100644 ---- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java -+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java -@@ -1824,6 +1824,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio - { - String reason = "idle_timeout"; - boolean notify = false; -+ boolean terminate = false; - boolean sendGoAway = false; - GoAwayFrame goAwayFrame = null; - Throwable cause = null; -@@ -1867,11 +1868,22 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio - { - if (LOG.isDebugEnabled()) - LOG.debug("Already closed, ignored idle timeout for {}", HTTP2Session.this); -- return false; -+ // Writes may be TCP congested, so termination never happened. -+ terminate = true; -+ goAwayFrame = goAwaySent; -+ if (goAwayFrame == null) -+ goAwayFrame = goAwayRecv; -+ break; - } - } - } - -+ if (terminate) -+ { -+ terminate(goAwayFrame); -+ return false; -+ } -+ - if (notify) - { - boolean confirmed = notifyIdleTimeout(HTTP2Session.this); diff -Nru jetty9-9.4.50/debian/patches/series jetty9-9.4.57/debian/patches/series --- jetty9-9.4.50/debian/patches/series 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/patches/series 2025-04-01 17:22:08.000000000 +0000 @@ -6,11 +6,3 @@ 08-ignore-jetty-test-policy.patch 09-tweak-distribution.patch servlet-api.patch -CVE-2023-26048.patch -CVE-2023-26049.patch -CVE-2023-40167.patch -CVE-2023-41900.patch -CVE-2023-36479.patch -CVE-2023-44487.patch -CVE-2023-36478.patch -CVE-2024-22201.patch diff -Nru jetty9-9.4.50/debian/patches/servlet-api.patch jetty9-9.4.57/debian/patches/servlet-api.patch --- jetty9-9.4.50/debian/patches/servlet-api.patch 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/patches/servlet-api.patch 2025-04-01 17:22:08.000000000 +0000 @@ -7,8 +7,6 @@ jetty-home/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -diff --git a/jetty-home/pom.xml b/jetty-home/pom.xml -index 90471d7..fee2898 100644 --- a/jetty-home/pom.xml +++ b/jetty-home/pom.xml @@ -284,10 +284,10 @@ diff -Nru jetty9-9.4.50/debian/source/lintian-overrides jetty9-9.4.57/debian/source/lintian-overrides --- jetty9-9.4.50/debian/source/lintian-overrides 2024-04-07 20:26:26.000000000 +0000 +++ jetty9-9.4.57/debian/source/lintian-overrides 2025-04-01 17:22:08.000000000 +0000 @@ -1 +1 @@ -jetty9 source: dh-exec-subst-unknown-variable * VERSION +jetty9 source: dh-exec-subst-unknown-variable *VERSION* diff -Nru jetty9-9.4.50/examples/async-rest/async-rest-jar/pom.xml jetty9-9.4.57/examples/async-rest/async-rest-jar/pom.xml --- jetty9-9.4.50/examples/async-rest/async-rest-jar/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/examples/async-rest/async-rest-jar/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/examples/async-rest/async-rest-webapp/pom.xml jetty9-9.4.57/examples/async-rest/async-rest-webapp/pom.xml --- jetty9-9.4.50/examples/async-rest/async-rest-webapp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/examples/async-rest/async-rest-webapp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/examples/async-rest/async-rest-webapp/src/main/webapp/WEB-INF/jetty-web.xml jetty9-9.4.57/examples/async-rest/async-rest-webapp/src/main/webapp/WEB-INF/jetty-web.xml --- jetty9-9.4.50/examples/async-rest/async-rest-webapp/src/main/webapp/WEB-INF/jetty-web.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/examples/async-rest/async-rest-webapp/src/main/webapp/WEB-INF/jetty-web.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-annotations/src/main/config/modules/annotations.mod jetty9-9.4.57/jetty-annotations/src/main/config/modules/annotations.mod --- jetty9-9.4.50/jetty-annotations/src/main/config/modules/annotations.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-annotations/src/main/config/modules/annotations.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables Annotation scanning for deployed webapplications. diff -Nru jetty9-9.4.50/jetty-ant/pom.xml jetty9-9.4.57/jetty-ant/pom.xml --- jetty9-9.4.50/jetty-ant/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-ant/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-ant diff -Nru jetty9-9.4.50/jetty-bom/pom.xml jetty9-9.4.57/jetty-bom/pom.xml --- jetty9-9.4.50/jetty-bom/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-bom/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,13 +3,13 @@ jetty-bom Jetty :: Bom Jetty BOM artifact - https://eclipse.org/jetty + https://jetty.org/ pom org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 @@ -17,7 +17,7 @@ org.codehaus.mojo flatten-maven-plugin - 1.2.7 + 1.6.0 ${project.build.directory} flattened-pom.xml @@ -53,336 +53,336 @@ org.eclipse.jetty apache-jsp - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty apache-jstl - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-alpn-client - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-alpn-java-client - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-alpn-java-server - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-alpn-openjdk8-client - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-alpn-openjdk8-server - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-alpn-conscrypt-client - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-alpn-conscrypt-server - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-alpn-server - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-annotations - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-ant - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-client - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-continuation - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-deploy - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-distribution - 9.4.50.v20221107 + 9.4.57.v20241219 zip org.eclipse.jetty jetty-distribution - 9.4.50.v20221107 + 9.4.57.v20241219 tar.gz org.eclipse.jetty.fcgi fcgi-client - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty.fcgi fcgi-server - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty.gcloud jetty-gcloud-session-manager - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-home - 9.4.50.v20221107 + 9.4.57.v20241219 zip org.eclipse.jetty jetty-home - 9.4.50.v20221107 + 9.4.57.v20241219 tar.gz org.eclipse.jetty jetty-http - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty.http2 http2-client - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty.http2 http2-common - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty.http2 http2-hpack - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty.http2 http2-http-client-transport - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty.http2 http2-server - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-http-spi - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty infinispan-common - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty infinispan-remote-query - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty infinispan-embedded-query - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-hazelcast - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-io - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-jaas - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-jaspi - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-jmx - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-jndi - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty.memcached jetty-memcached-sessions - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-nosql - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty.osgi jetty-osgi-boot - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty.osgi jetty-osgi-boot-jsp - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty.osgi jetty-osgi-boot-warurl - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty.osgi jetty-httpservice - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-plus - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-proxy - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-quickstart - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-rewrite - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-security - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-openid - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-server - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-servlet - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-servlets - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-spring - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-unixsocket - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-util - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-util-ajax - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-webapp - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty.websocket javax-websocket-client-impl - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty.websocket javax-websocket-server-impl - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty.websocket websocket-api - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty.websocket websocket-client - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty.websocket websocket-common - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty.websocket websocket-server - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty.websocket websocket-servlet - 9.4.50.v20221107 + 9.4.57.v20241219 org.eclipse.jetty jetty-xml - 9.4.50.v20221107 + 9.4.57.v20241219 diff -Nru jetty9-9.4.50/jetty-cdi/pom.xml jetty9-9.4.57/jetty-cdi/pom.xml --- jetty9-9.4.50/jetty-cdi/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-cdi/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 org.eclipse.jetty @@ -46,6 +46,16 @@ weld-servlet-core ${weld.version} test + + + org.jboss.logging + jboss-logging + + + + + org.jboss.logging + jboss-logging diff -Nru jetty9-9.4.50/jetty-cdi/src/main/config/etc/cdi/jetty-cdi.xml jetty9-9.4.57/jetty-cdi/src/main/config/etc/cdi/jetty-cdi.xml --- jetty9-9.4.50/jetty-cdi/src/main/config/etc/cdi/jetty-cdi.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-cdi/src/main/config/etc/cdi/jetty-cdi.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-cdi/src/main/config/etc/cdi/jetty-cdi2.xml jetty9-9.4.57/jetty-cdi/src/main/config/etc/cdi/jetty-cdi2.xml --- jetty9-9.4.50/jetty-cdi/src/main/config/etc/cdi/jetty-cdi2.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-cdi/src/main/config/etc/cdi/jetty-cdi2.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-cdi/src/main/config/etc/cdi/jetty-web-cdi2.xml jetty9-9.4.57/jetty-cdi/src/main/config/etc/cdi/jetty-web-cdi2.xml --- jetty9-9.4.50/jetty-cdi/src/main/config/etc/cdi/jetty-web-cdi2.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-cdi/src/main/config/etc/cdi/jetty-web-cdi2.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-cdi/src/main/config/modules/cdi-decorate.mod jetty9-9.4.57/jetty-cdi/src/main/config/modules/cdi-decorate.mod --- jetty9-9.4.50/jetty-cdi/src/main/config/modules/cdi-decorate.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-cdi/src/main/config/modules/cdi-decorate.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Configures Jetty to use the "CdiDecoratingListener" as the default diff -Nru jetty9-9.4.50/jetty-cdi/src/main/config/modules/cdi-spi.mod jetty9-9.4.57/jetty-cdi/src/main/config/modules/cdi-spi.mod --- jetty9-9.4.50/jetty-cdi/src/main/config/modules/cdi-spi.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-cdi/src/main/config/modules/cdi-spi.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Configures Jetty to use the "CdiSpiDecorator" that calls the CDI SPI diff -Nru jetty9-9.4.50/jetty-cdi/src/main/config/modules/cdi.mod jetty9-9.4.57/jetty-cdi/src/main/config/modules/cdi.mod --- jetty9-9.4.50/jetty-cdi/src/main/config/modules/cdi.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-cdi/src/main/config/modules/cdi.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Support for CDI inside the webapp. diff -Nru jetty9-9.4.50/jetty-cdi/src/main/config/modules/cdi2.mod jetty9-9.4.57/jetty-cdi/src/main/config/modules/cdi2.mod --- jetty9-9.4.50/jetty-cdi/src/main/config/modules/cdi2.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-cdi/src/main/config/modules/cdi2.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Deprecated support for CDI integrations inside the webapp. diff -Nru jetty9-9.4.50/jetty-client/pom.xml jetty9-9.4.57/jetty-client/pom.xml --- jetty9-9.4.50/jetty-client/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-client/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 @@ -115,14 +115,20 @@ org.apache.kerby kerb-simplekdc - 2.0.2 + 2.1.0 test + + + org.jline + jline + + net.minidev json-smart - 2.4.8 + 2.5.1 test diff -Nru jetty9-9.4.50/jetty-client/src/main/config/modules/client.mod jetty9-9.4.57/jetty-client/src/main/config/modules/client.mod --- jetty9-9.4.50/jetty-client/src/main/config/modules/client.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-client/src/main/config/modules/client.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Adds the Jetty HTTP client to the server classpath. diff -Nru jetty9-9.4.50/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java jetty9-9.4.57/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java --- jetty9-9.4.50/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -71,6 +71,7 @@ import org.hamcrest.Matchers; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledForJreRange; import org.junit.jupiter.api.condition.JRE; @@ -367,7 +368,7 @@ // Excluded in JDK 11+ because resumed sessions cannot be compared // using their session IDs even though they are resumed correctly. - @EnabledForJreRange(max = JRE.JAVA_10) + @Disabled("No longer supported on newer Java 8 releases") @Test public void testHandshakeSucceededWithSessionResumption() throws Exception { @@ -447,7 +448,7 @@ // Excluded in JDK 11+ because resumed sessions cannot be compared // using their session IDs even though they are resumed correctly. - @EnabledForJreRange(max = JRE.JAVA_10) + @Disabled("Not supported with newer Java 8 releases") @Test public void testClientRawCloseDoesNotInvalidateSession() throws Exception { diff -Nru jetty9-9.4.50/jetty-continuation/pom.xml jetty9-9.4.57/jetty-continuation/pom.xml --- jetty9-9.4.50/jetty-continuation/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-continuation/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-continuation diff -Nru jetty9-9.4.50/jetty-deploy/pom.xml jetty9-9.4.57/jetty-deploy/pom.xml --- jetty9-9.4.50/jetty-deploy/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-deploy/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-deploy diff -Nru jetty9-9.4.50/jetty-deploy/src/main/config/etc/jetty-decorate.xml jetty9-9.4.57/jetty-deploy/src/main/config/etc/jetty-decorate.xml --- jetty9-9.4.50/jetty-deploy/src/main/config/etc/jetty-decorate.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-deploy/src/main/config/etc/jetty-decorate.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-deploy/src/main/config/etc/jetty-deploy.xml jetty9-9.4.57/jetty-deploy/src/main/config/etc/jetty-deploy.xml --- jetty9-9.4.50/jetty-deploy/src/main/config/etc/jetty-deploy.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-deploy/src/main/config/etc/jetty-deploy.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-deploy/src/main/config/etc/jetty-web-decorate.xml jetty9-9.4.57/jetty-deploy/src/main/config/etc/jetty-web-decorate.xml --- jetty9-9.4.50/jetty-deploy/src/main/config/etc/jetty-web-decorate.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-deploy/src/main/config/etc/jetty-web-decorate.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-deploy/src/main/config/modules/decorate.mod jetty9-9.4.57/jetty-deploy/src/main/config/modules/decorate.mod --- jetty9-9.4.50/jetty-deploy/src/main/config/modules/decorate.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-deploy/src/main/config/modules/decorate.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Jetty setup to support Decoration of Listeners, Filters and Servlets within a deployed webapp. diff -Nru jetty9-9.4.50/jetty-deploy/src/main/config/modules/deploy.mod jetty9-9.4.57/jetty-deploy/src/main/config/modules/deploy.mod --- jetty9-9.4.50/jetty-deploy/src/main/config/modules/deploy.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-deploy/src/main/config/modules/deploy.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables webapplication deployment from the webapps directory. diff -Nru jetty9-9.4.50/jetty-deploy/src/main/config/modules/global-webapp-common.d/global-webapp-common.xml jetty9-9.4.57/jetty-deploy/src/main/config/modules/global-webapp-common.d/global-webapp-common.xml --- jetty9-9.4.50/jetty-deploy/src/main/config/modules/global-webapp-common.d/global-webapp-common.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-deploy/src/main/config/modules/global-webapp-common.d/global-webapp-common.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-deploy/src/main/config/modules/global-webapp-common.d/webapp-common.xml jetty9-9.4.57/jetty-deploy/src/main/config/modules/global-webapp-common.d/webapp-common.xml --- jetty9-9.4.50/jetty-deploy/src/main/config/modules/global-webapp-common.d/webapp-common.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-deploy/src/main/config/modules/global-webapp-common.d/webapp-common.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-deploy/src/main/config/modules/global-webapp-common.mod jetty9-9.4.57/jetty-deploy/src/main/config/modules/global-webapp-common.mod --- jetty9-9.4.50/jetty-deploy/src/main/config/modules/global-webapp-common.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-deploy/src/main/config/modules/global-webapp-common.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables Deployer to apply common configuration to all webapp deployments diff -Nru jetty9-9.4.50/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentTempDirTest.java jetty9-9.4.57/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentTempDirTest.java --- jetty9-9.4.50/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentTempDirTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentTempDirTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -101,7 +101,10 @@ public void testTmpDirectory() throws Exception { Path warPath = MavenTestingUtils.getTestResourcePath("webapps/foo-webapp-1.war"); - String deploymentXml = "\n" + + String deploymentXml = + "\n" + + "\n" + + "\n" + "" + warPath + "\n" + "" + tmpDir + "\n" + "false\n" + @@ -141,7 +144,10 @@ public void testPersistentTmpDirectory() throws Exception { Path warPath = MavenTestingUtils.getTestResourcePath("webapps/foo-webapp-1.war"); - String deploymentXml = "\n" + + String deploymentXml = + "\n" + + "\n" + + "\n" + "" + warPath + "\n" + "" + tmpDir + "\n" + "true\n" + diff -Nru jetty9-9.4.50/jetty-deploy/src/test/resources/binding-test-contexts-1.xml jetty9-9.4.57/jetty-deploy/src/test/resources/binding-test-contexts-1.xml --- jetty9-9.4.50/jetty-deploy/src/test/resources/binding-test-contexts-1.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-deploy/src/test/resources/binding-test-contexts-1.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ - + diff -Nru jetty9-9.4.50/jetty-deploy/src/test/resources/context-binding-test-1.xml jetty9-9.4.57/jetty-deploy/src/test/resources/context-binding-test-1.xml --- jetty9-9.4.50/jetty-deploy/src/test/resources/context-binding-test-1.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-deploy/src/test/resources/context-binding-test-1.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,3 +1,5 @@ + + diff -Nru jetty9-9.4.50/jetty-deploy/src/test/resources/jetty-deploy-wars.xml jetty9-9.4.57/jetty-deploy/src/test/resources/jetty-deploy-wars.xml --- jetty9-9.4.50/jetty-deploy/src/test/resources/jetty-deploy-wars.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-deploy/src/test/resources/jetty-deploy-wars.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml jetty9-9.4.57/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml --- jetty9-9.4.50/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-deploy/src/test/resources/jetty-http.xml jetty9-9.4.57/jetty-deploy/src/test/resources/jetty-http.xml --- jetty9-9.4.50/jetty-deploy/src/test/resources/jetty-http.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-deploy/src/test/resources/jetty-http.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-deploy/src/test/resources/jetty.xml jetty9-9.4.57/jetty-deploy/src/test/resources/jetty.xml --- jetty9-9.4.50/jetty-deploy/src/test/resources/jetty.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-deploy/src/test/resources/jetty.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,8 +1,9 @@ - + + - + diff -Nru jetty9-9.4.50/jetty-deploy/src/test/resources/webapps/badapp/badapp.xml jetty9-9.4.57/jetty-deploy/src/test/resources/webapps/badapp/badapp.xml --- jetty9-9.4.50/jetty-deploy/src/test/resources/webapps/badapp/badapp.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-deploy/src/test/resources/webapps/badapp/badapp.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ - + /badapp diff -Nru jetty9-9.4.50/jetty-deploy/src/test/resources/webapps/foo.xml jetty9-9.4.57/jetty-deploy/src/test/resources/webapps/foo.xml --- jetty9-9.4.50/jetty-deploy/src/test/resources/webapps/foo.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-deploy/src/test/resources/webapps/foo.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + /foo diff -Nru jetty9-9.4.50/jetty-distribution/pom.xml jetty9-9.4.57/jetty-distribution/pom.xml --- jetty9-9.4.50/jetty-distribution/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-distribution/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-distribution diff -Nru jetty9-9.4.50/jetty-distribution/src/main/resources/README.TXT jetty9-9.4.57/jetty-distribution/src/main/resources/README.TXT --- jetty9-9.4.50/jetty-distribution/src/main/resources/README.TXT 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-distribution/src/main/resources/README.TXT 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ The Jetty project is a 100% Java HTTP Server, HTTP Client and Servlet Container from the eclipse foundation - https://www.eclipse.org/jetty/ + https://jetty.org/ Jetty is open source and is dual licensed using the Apache 2.0 and Eclipse Public License 1.0. You may choose either license when diff -Nru jetty9-9.4.50/jetty-distribution/src/main/resources/demo-base/webapps/ROOT/index.html jetty9-9.4.57/jetty-distribution/src/main/resources/demo-base/webapps/ROOT/index.html --- jetty9-9.4.50/jetty-distribution/src/main/resources/demo-base/webapps/ROOT/index.html 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-distribution/src/main/resources/demo-base/webapps/ROOT/index.html 2024-12-19 21:51:26.000000000 +0000 @@ -23,7 +23,7 @@ Websocket and HTTP/2 protocols. The project is 100% Open Source and hosted by the - Eclipse Foundation at https://www.eclipse.org/jetty/. + Eclipse Foundation at https://jetty.org/.

@@ -44,16 +44,16 @@

information ...

getting help ...

    -
  • Mailing lists @ eclipse
  • +
  • Mailing lists @ eclipse
  • Developer Advice
  • Custom Development
  • Production support
  • diff -Nru jetty9-9.4.50/jetty-distribution/src/main/resources/demo-base/webapps/example-moved.xml jetty9-9.4.57/jetty-distribution/src/main/resources/demo-base/webapps/example-moved.xml --- jetty9-9.4.50/jetty-distribution/src/main/resources/demo-base/webapps/example-moved.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-distribution/src/main/resources/demo-base/webapps/example-moved.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-distribution/src/main/resources/start.ini jetty9-9.4.57/jetty-distribution/src/main/resources/start.ini --- jetty9-9.4.50/jetty-distribution/src/main/resources/start.ini 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-distribution/src/main/resources/start.ini 2024-12-19 21:51:26.000000000 +0000 @@ -7,7 +7,7 @@ # of making changes to this {jetty.home} directory. # # See documentation about {jetty.base} at -# https://www.eclipse.org/jetty/documentation/current/startup.html +# https://jetty.org/docs/9/startup.html # # A demo-base directory has been provided as an example of # this sort of setup. diff -Nru jetty9-9.4.50/jetty-fcgi/fcgi-client/pom.xml jetty9-9.4.57/jetty-fcgi/fcgi-client/pom.xml --- jetty9-9.4.50/jetty-fcgi/fcgi-client/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-fcgi/fcgi-client/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.fcgi fcgi-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-fcgi/fcgi-server/pom.xml jetty9-9.4.57/jetty-fcgi/fcgi-server/pom.xml --- jetty9-9.4.50/jetty-fcgi/fcgi-server/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-fcgi/fcgi-server/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.fcgi fcgi-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-fcgi/fcgi-server/src/main/config/modules/fcgi.mod jetty9-9.4.57/jetty-fcgi/fcgi-server/src/main/config/modules/fcgi.mod --- jetty9-9.4.50/jetty-fcgi/fcgi-server/src/main/config/modules/fcgi.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-fcgi/fcgi-server/src/main/config/modules/fcgi.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Adds the FastCGI implementation to the classpath. @@ -13,4 +13,4 @@ [ini-template] ## For configuration of FastCGI contexts, see -## https://www.eclipse.org/jetty/documentation/current/fastcgi.html +## https://jetty.org/docs/9/fastcgi.html diff -Nru jetty9-9.4.50/jetty-fcgi/pom.xml jetty9-9.4.57/jetty-fcgi/pom.xml --- jetty9-9.4.50/jetty-fcgi/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-fcgi/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-gcloud/jetty-gcloud-session-manager/pom.xml jetty9-9.4.57/jetty-gcloud/jetty-gcloud-session-manager/pom.xml --- jetty9-9.4.50/jetty-gcloud/jetty-gcloud-session-manager/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-gcloud/jetty-gcloud-session-manager/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.gcloud gcloud-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/etc/sessions/gcloud/session-store.xml jetty9-9.4.57/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/etc/sessions/gcloud/session-store.xml --- jetty9-9.4.50/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/etc/sessions/gcloud/session-store.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/etc/sessions/gcloud/session-store.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud-datastore.mod jetty9-9.4.57/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud-datastore.mod --- jetty9-9.4.50/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud-datastore.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud-datastore.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables GCloud Datastore API and implementation diff -Nru jetty9-9.4.50/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud.mod jetty9-9.4.57/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud.mod --- jetty9-9.4.50/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Control GCloud API classpath diff -Nru jetty9-9.4.50/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/session-store-gcloud.mod jetty9-9.4.57/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/session-store-gcloud.mod --- jetty9-9.4.50/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/session-store-gcloud.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/session-store-gcloud.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables GCloudDatastore session management. diff -Nru jetty9-9.4.50/jetty-gcloud/pom.xml jetty9-9.4.57/jetty-gcloud/pom.xml --- jetty9-9.4.50/jetty-gcloud/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-gcloud/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 @@ -13,7 +13,7 @@ Jetty :: GCloud - 2.9.1 + 2.24.3 diff -Nru jetty9-9.4.50/jetty-hazelcast/pom.xml jetty9-9.4.57/jetty-hazelcast/pom.xml --- jetty9-9.4.50/jetty-hazelcast/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-hazelcast/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/default.xml jetty9-9.4.57/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/default.xml --- jetty9-9.4.50/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/default.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/default.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/remote.xml jetty9-9.4.57/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/remote.xml --- jetty9-9.4.50/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/remote.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/remote.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod jetty9-9.4.57/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod --- jetty9-9.4.50/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables session data store in an embedded Hazelcast Map diff -Nru jetty9-9.4.50/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod jetty9-9.4.57/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod --- jetty9-9.4.50/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables session data store in a remote Hazelcast Map diff -Nru jetty9-9.4.50/jetty-home/pom.xml jetty9-9.4.57/jetty-home/pom.xml --- jetty9-9.4.50/jetty-home/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-home/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-home diff -Nru jetty9-9.4.50/jetty-home/src/main/resources/etc/jetty-setuid.xml jetty9-9.4.57/jetty-home/src/main/resources/etc/jetty-setuid.xml --- jetty9-9.4.50/jetty-home/src/main/resources/etc/jetty-setuid.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-home/src/main/resources/etc/jetty-setuid.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-home/src/main/resources/etc/jetty-started.xml jetty9-9.4.57/jetty-home/src/main/resources/etc/jetty-started.xml --- jetty9-9.4.50/jetty-home/src/main/resources/etc/jetty-started.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-home/src/main/resources/etc/jetty-started.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-home/src/main/resources/etc/jetty-stop.xml jetty9-9.4.57/jetty-home/src/main/resources/etc/jetty-stop.xml --- jetty9-9.4.50/jetty-home/src/main/resources/etc/jetty-stop.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-home/src/main/resources/etc/jetty-stop.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-home/src/main/resources/modules/conscrypt/conscrypt.xml jetty9-9.4.57/jetty-home/src/main/resources/modules/conscrypt/conscrypt.xml --- jetty9-9.4.50/jetty-home/src/main/resources/modules/conscrypt/conscrypt.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-home/src/main/resources/modules/conscrypt/conscrypt.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-home/src/main/resources/modules/conscrypt.mod jetty9-9.4.57/jetty-home/src/main/resources/modules/conscrypt.mod --- jetty9-9.4.50/jetty-home/src/main/resources/modules/conscrypt.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-home/src/main/resources/modules/conscrypt.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Installs the Conscrypt JSSE provider diff -Nru jetty9-9.4.50/jetty-home/src/main/resources/modules/hawtio/hawtio.xml jetty9-9.4.57/jetty-home/src/main/resources/modules/hawtio/hawtio.xml --- jetty9-9.4.50/jetty-home/src/main/resources/modules/hawtio/hawtio.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-home/src/main/resources/modules/hawtio/hawtio.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-home/src/main/resources/modules/hawtio.mod jetty9-9.4.57/jetty-home/src/main/resources/modules/hawtio.mod --- jetty9-9.4.50/jetty-home/src/main/resources/modules/hawtio.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-home/src/main/resources/modules/hawtio.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Deploys the Hawtio console as a webapplication. diff -Nru jetty9-9.4.50/jetty-home/src/main/resources/modules/jamon/jamon.xml jetty9-9.4.57/jetty-home/src/main/resources/modules/jamon/jamon.xml --- jetty9-9.4.50/jetty-home/src/main/resources/modules/jamon/jamon.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-home/src/main/resources/modules/jamon/jamon.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-home/src/main/resources/modules/jamon.mod jetty9-9.4.57/jetty-home/src/main/resources/modules/jamon.mod --- jetty9-9.4.50/jetty-home/src/main/resources/modules/jamon.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-home/src/main/resources/modules/jamon.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Deploys the JAMon webapplication diff -Nru jetty9-9.4.50/jetty-home/src/main/resources/modules/jminix/jminix.xml jetty9-9.4.57/jetty-home/src/main/resources/modules/jminix/jminix.xml --- jetty9-9.4.50/jetty-home/src/main/resources/modules/jminix/jminix.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-home/src/main/resources/modules/jminix/jminix.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ - + diff -Nru jetty9-9.4.50/jetty-home/src/main/resources/modules/jminix.mod jetty9-9.4.57/jetty-home/src/main/resources/modules/jminix.mod --- jetty9-9.4.50/jetty-home/src/main/resources/modules/jminix.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-home/src/main/resources/modules/jminix.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Deploys the Jminix JMX Console within the server diff -Nru jetty9-9.4.50/jetty-home/src/main/resources/modules/jolokia/jolokia.xml jetty9-9.4.57/jetty-home/src/main/resources/modules/jolokia/jolokia.xml --- jetty9-9.4.50/jetty-home/src/main/resources/modules/jolokia/jolokia.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-home/src/main/resources/modules/jolokia/jolokia.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-home/src/main/resources/modules/jolokia.mod jetty9-9.4.57/jetty-home/src/main/resources/modules/jolokia.mod --- jetty9-9.4.50/jetty-home/src/main/resources/modules/jolokia.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-home/src/main/resources/modules/jolokia.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Deploys the Jolokia console as a web application. diff -Nru jetty9-9.4.50/jetty-home/src/main/resources/modules/jsp.mod jetty9-9.4.57/jetty-home/src/main/resources/modules/jsp.mod --- jetty9-9.4.50/jetty-home/src/main/resources/modules/jsp.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-home/src/main/resources/modules/jsp.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables JSP for all webapplications deployed on the server. diff -Nru jetty9-9.4.50/jetty-home/src/main/resources/modules/jstl.mod jetty9-9.4.57/jetty-home/src/main/resources/modules/jstl.mod --- jetty9-9.4.50/jetty-home/src/main/resources/modules/jstl.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-home/src/main/resources/modules/jstl.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables JSTL for all webapplications deployed on the server diff -Nru jetty9-9.4.50/jetty-home/src/main/resources/modules/setuid.mod jetty9-9.4.57/jetty-home/src/main/resources/modules/setuid.mod --- jetty9-9.4.50/jetty-home/src/main/resources/modules/setuid.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-home/src/main/resources/modules/setuid.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables the unix setUID configuration so that the server diff -Nru jetty9-9.4.50/jetty-home/src/main/resources/modules/stop.mod jetty9-9.4.57/jetty-home/src/main/resources/modules/stop.mod --- jetty9-9.4.50/jetty-home/src/main/resources/modules/stop.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-home/src/main/resources/modules/stop.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] This module causes jetty to stop immediately after starting. This is good for testing configuration and/or precompiling quickstart webapps diff -Nru jetty9-9.4.50/jetty-http/pom.xml jetty9-9.4.57/jetty-http/pom.xml --- jetty9-9.4.50/jetty-http/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-http diff -Nru jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCompliance.java jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCompliance.java --- jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCompliance.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCompliance.java 2024-12-19 21:51:26.000000000 +0000 @@ -24,5 +24,6 @@ public enum CookieCompliance { RFC6265, + RFC6265_LEGACY, // Forgiving of bad quotes. RFC2965 } diff -Nru jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCompliance.java jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCompliance.java --- jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCompliance.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCompliance.java 2024-12-19 21:51:26.000000000 +0000 @@ -135,6 +135,7 @@ HttpComplianceSection.NO_AMBIGUOUS_PATH_SEGMENTS, HttpComplianceSection.NO_AMBIGUOUS_PATH_SEPARATORS, HttpComplianceSection.NO_UTF16_ENCODINGS, + HttpComplianceSection.NO_USER_INFO, HttpComplianceSection.NO_AMBIGUOUS_EMPTY_SEGMENT, HttpComplianceSection.NO_AMBIGUOUS_PATH_ENCODING)); break; @@ -217,6 +218,7 @@ } private static final EnumMap __uriViolations = new EnumMap<>(HttpURI.Violation.class); + static { // create a map from Violation to compliance in a loop, so that any new violations added are detected with ISE @@ -242,6 +244,9 @@ case UTF16: __uriViolations.put(violation, HttpComplianceSection.NO_UTF16_ENCODINGS); break; + case USER_INFO: + __uriViolations.put(violation, HttpComplianceSection.NO_USER_INFO); + break; default: throw new IllegalStateException(); } diff -Nru jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/HttpComplianceSection.java jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/HttpComplianceSection.java --- jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/HttpComplianceSection.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/HttpComplianceSection.java 2024-12-19 21:51:26.000000000 +0000 @@ -36,6 +36,7 @@ NO_AMBIGUOUS_PATH_SEPARATORS("https://tools.ietf.org/html/rfc3986#section-3.3", "No ambiguous URI path separators"), NO_AMBIGUOUS_PATH_PARAMETERS("https://tools.ietf.org/html/rfc3986#section-3.3", "No ambiguous URI path parameters"), NO_UTF16_ENCODINGS("https://www.w3.org/International/iri-edit/draft-duerst-iri.html#anchor29", "UTF16 encoding"), + NO_USER_INFO("https://datatracker.ietf.org/doc/html/rfc9110#name-deprecation-of-userinfo-in-", "User info in authority"), NO_AMBIGUOUS_EMPTY_SEGMENT("https://tools.ietf.org/html/rfc3986#section-3.3", "Ambiguous URI empty segment"), NO_AMBIGUOUS_PATH_ENCODING("https://tools.ietf.org/html/rfc3986#section-3.3", "Ambiguous URI path encoding"); diff -Nru jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java --- jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java 2024-12-19 21:51:26.000000000 +0000 @@ -499,7 +499,7 @@ /* Quick lookahead for the start state looking for a request method or an HTTP version, * otherwise skip white space until something else to parse. */ - private boolean quickStart(ByteBuffer buffer) + private void quickStart(ByteBuffer buffer) { if (_requestHandler != null) { @@ -510,7 +510,7 @@ buffer.position(buffer.position() + _methodString.length() + 1); setState(State.SPACE1); - return false; + return; } } else if (_responseHandler != null) @@ -520,7 +520,7 @@ { buffer.position(buffer.position() + _version.asString().length() + 1); setState(State.SPACE1); - return false; + return; } } @@ -541,7 +541,7 @@ _string.setLength(0); _string.append(t.getChar()); setState(_requestHandler != null ? State.METHOD : State.RESPONSE_VERSION); - return false; + return; } case OTEXT: case SPACE: @@ -559,7 +559,6 @@ throw new BadMessageException(HttpStatus.BAD_REQUEST_400); } } - return false; } private void setString(String s) @@ -974,23 +973,20 @@ case CONTENT_LENGTH: if (_hasTransferEncoding && complianceViolation(TRANSFER_ENCODING_WITH_CONTENT_LENGTH)) throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Transfer-Encoding and Content-Length"); - + long contentLength = convertContentLength(_valueString); if (_hasContentLength) { if (complianceViolation(MULTIPLE_CONTENT_LENGTHS)) throw new BadMessageException(HttpStatus.BAD_REQUEST_400, MULTIPLE_CONTENT_LENGTHS.description); - if (convertContentLength(_valueString) != _contentLength) - throw new BadMessageException(HttpStatus.BAD_REQUEST_400, MULTIPLE_CONTENT_LENGTHS.description); + if (contentLength != _contentLength) + throw new BadMessageException(HttpStatus.BAD_REQUEST_400, MULTIPLE_CONTENT_LENGTHS.getDescription()); } _hasContentLength = true; if (_endOfContent != EndOfContent.CHUNKED_CONTENT) { - _contentLength = convertContentLength(_valueString); - if (_contentLength <= 0) - _endOfContent = EndOfContent.NO_CONTENT; - else - _endOfContent = EndOfContent.CONTENT_LENGTH; + _contentLength = contentLength; + _endOfContent = EndOfContent.CONTENT_LENGTH; } break; @@ -1107,15 +1103,21 @@ private long convertContentLength(String valueString) { - try - { - return Long.parseLong(valueString); - } - catch (NumberFormatException e) + if (valueString == null || valueString.length() == 0) + throw new BadMessageException("Invalid Content-Length Value", new NumberFormatException()); + + long value = 0; + int length = valueString.length(); + + for (int i = 0; i < length; i++) { - LOG.ignore(e); - throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Invalid Content-Length Value", e); + char c = valueString.charAt(i); + if (c < '0' || c > '9') + throw new BadMessageException("Invalid Content-Length Value", new NumberFormatException()); + + value = Math.addExact(Math.multiplyExact(value, 10L), c - '0'); } + return value; } /* @@ -1511,12 +1513,11 @@ _methodString = null; _endOfContent = EndOfContent.UNKNOWN_CONTENT; _header = null; - if (quickStart(buffer)) - return true; + quickStart(buffer); } // Request/response line - if (_state.ordinal() >= State.START.ordinal() && _state.ordinal() < State.HEADER.ordinal()) + if (_state.ordinal() < State.HEADER.ordinal()) { if (parseLine(buffer)) return true; @@ -2036,7 +2037,6 @@ } } - @SuppressWarnings("serial") private static class IllegalCharacterException extends BadMessageException { private IllegalCharacterException(State state, HttpTokens.Token token, ByteBuffer buffer) diff -Nru jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/HttpTokens.java jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/HttpTokens.java --- jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/HttpTokens.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/HttpTokens.java 2024-12-19 21:51:26.000000000 +0000 @@ -188,5 +188,49 @@ } } } + + /** + * This is used when decoding to not decode illegal characters based on RFC9110. + * CR, LF, or NUL are replaced with ' ', all other control and multibyte characters + * are replaced with '?'. If this is given a legal character the same value will be returned. + *
    +     * field-vchar = VCHAR / obs-text
    +     * obs-text    = %x80-FF
    +     * VCHAR       = %x21-7E
    +     * 
    + * @param c the character to test. + * @return the original character or the replacement character ' ' or '?', + * the return value is guaranteed to be a valid ISO-8859-1 character. + */ + public static char sanitizeFieldVchar(char c) + { + switch (c) + { + // A recipient of CR, LF, or NUL within a field value MUST either reject the message + // or replace each of those characters with SP before further processing + case '\r': + case '\n': + case 0x00: + return ' '; + + default: + if (isIllegalFieldVchar(c)) + return '?'; + } + return c; + } + + /** + * Checks whether this is an invalid VCHAR based on RFC9110. + * If this not a valid ISO-8859-1 character or a control character + * we say that it is illegal. + * + * @param c the character to test. + * @return true if this is invalid VCHAR. + */ + public static boolean isIllegalFieldVchar(char c) + { + return (c >= 256 || c < ' '); + } } diff -Nru jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java --- jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java 2024-12-19 21:51:26.000000000 +0000 @@ -122,7 +122,11 @@ /** * Non standard UTF-16 encoding eg {@code /foo%u2192bar}. */ - UTF16("Non standard UTF-16 encoding"); + UTF16("Non standard UTF-16 encoding"), + /** + * User info in authority + */ + USER_INFO("User info in Authority"); private final String _message; @@ -155,6 +159,84 @@ __ambiguousSegments.put("%u002e%u002e", Boolean.TRUE); } + private static final boolean[] __unreservedPctEncodedSubDelims; + + private static boolean isDigit(char c) + { + return (c >= '0') && (c <= '9'); + } + + private static boolean isHexDigit(char c) + { + return (((c >= 'a') && (c <= 'f')) || // ALPHA (lower) + ((c >= 'A') && (c <= 'F')) || // ALPHA (upper) + ((c >= '0') && (c <= '9'))); + } + + private static boolean isUnreserved(char c) + { + return (((c >= 'a') && (c <= 'z')) || // ALPHA (lower) + ((c >= 'A') && (c <= 'Z')) || // ALPHA (upper) + ((c >= '0') && (c <= '9')) || // DIGIT + (c == '-') || (c == '.') || (c == '_') || (c == '~')); + } + + private static boolean isSubDelim(char c) + { + return c == '!' || c == '$' || c == '&' || c == '\'' || c == '(' || c == ')' || c == '*' || c == '+' || c == ',' || c == ';' || c == '='; + } + + static boolean isUnreservedPctEncodedOrSubDelim(char c) + { + return c < __unreservedPctEncodedSubDelims.length && __unreservedPctEncodedSubDelims[c]; + } + + static + { + // Establish allowed and disallowed characters per the path rules of + // https://datatracker.ietf.org/doc/html/rfc3986#section-3.3 + // ABNF + // path = path-abempty ; begins with "/" or is empty + // / path-absolute ; begins with "/" but not "//" + // / path-noscheme ; begins with a non-colon segment + // / path-rootless ; begins with a segment + // / path-empty ; zero characters + // path-abempty = *( "/" segment ) + // path-absolute = "/" [ segment-nz *( "/" segment ) ] + // path-noscheme = segment-nz-nc *( "/" segment ) + // path-rootless = segment-nz *( "/" segment ) + // path-empty = 0 + // + // segment = *pchar + // segment-nz = 1*pchar + // segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" ) + // ; non-zero-length segment without any colon ":" + // pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + // pct-encoded = "%" HEXDIG HEXDIG + // + // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + // reserved = gen-delims / sub-delims + // gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" + // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + // / "*" / "+" / "," / ";" / "=" + // + // authority = [ userinfo "@" ] host [ ":" port ] + // userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) + // host = IP-literal / IPv4address / reg-name + // port = *DIGIT + // + // reg-name = *( unreserved / pct-encoded / sub-delims ) + // + // we are limited to US-ASCII per https://datatracker.ietf.org/doc/html/rfc3986#section-2 + __unreservedPctEncodedSubDelims = new boolean[128]; + + for (int i = 0; i < __unreservedPctEncodedSubDelims.length; i++) + { + char c = (char)i; + __unreservedPctEncodedSubDelims[i] = isUnreserved(c) || c == '%' || isSubDelim(c); + } + } + private String _scheme; private String _user; private String _host; @@ -334,7 +416,7 @@ int mark = offset; // the start of the current section being parsed int pathMark = 0; // the start of the path section int segment = 0; // the start of the current segment within the path - boolean encodedPath = false; // set to true if the path contains % encoded characters + boolean encoded = false; // set to true if the path contains % encoded characters boolean encodedUtf16 = false; // Is the current encoding for UTF16? int encodedCharacters = 0; // partial state of parsing a % encoded character int encodedValue = 0; // the partial encoded value @@ -378,7 +460,7 @@ state = State.ASTERISK; break; case '%': - encodedPath = true; + encoded = true; encodedCharacters = 2; encodedValue = 0; mark = pathMark = segment = i; @@ -431,7 +513,7 @@ break; case '%': // must have been in an encoded path - encodedPath = true; + encoded = true; encodedCharacters = 2; encodedValue = 0; state = State.PATH; @@ -481,7 +563,10 @@ switch (c) { case '/': + if (encodedCharacters > 0) + throw new IllegalArgumentException("Bad authority"); _host = uri.substring(mark, i); + encoded = false; pathMark = mark = i; segment = mark + 1; state = State.PATH; @@ -496,12 +581,35 @@ if (_user != null) throw new IllegalArgumentException("Bad authority"); _user = uri.substring(mark, i); + _violations.add(Violation.USER_INFO); mark = i + 1; break; case '[': + if (i != mark) + throw new IllegalArgumentException("Bad authority"); state = State.IPV6; break; + case '%': + if (encodedCharacters > 0) + throw new IllegalArgumentException("Bad authority"); + encodedCharacters = 2; + encoded = true; + break; + case '#': + case ';': + throw new IllegalArgumentException("Bad authority"); + default: + if (encodedCharacters > 0) + { + if (!isHexDigit(c)) + throw new IllegalArgumentException("Bad authority"); + encodedCharacters--; + } + else if (!isUnreservedPctEncodedOrSubDelim(c)) + { + throw new IllegalArgumentException("Bad authority"); + } break; } break; @@ -526,7 +634,11 @@ state = State.PATH; } break; + case ':': + break; default: + if (!isHexDigit(c)) + throw new IllegalArgumentException("Bad authority"); break; } break; @@ -539,6 +651,7 @@ throw new IllegalArgumentException("Bad authority"); // It wasn't a port, but a password! _user = _host + ":" + uri.substring(mark, i); + _violations.add(Violation.USER_INFO); mark = i + 1; state = State.HOST; } @@ -614,7 +727,7 @@ dot |= segment == i; break; case '%': - encodedPath = true; + encoded = true; encodedUtf16 = false; encodedCharacters = 2; encodedValue = 0; @@ -642,7 +755,7 @@ state = State.FRAGMENT; break; case '/': - encodedPath = true; + encoded = true; segment = i + 1; state = State.PATH; break; @@ -721,7 +834,7 @@ throw new IllegalStateException(state.toString()); } - if (!encodedPath && !dot) + if (!encoded && !dot) { if (_param == null) _decodedPath = _path; diff -Nru jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormInputStream.java jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormInputStream.java --- jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormInputStream.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormInputStream.java 2024-12-19 21:51:26.000000000 +0000 @@ -61,9 +61,12 @@ public class MultiPartFormInputStream { private static final Logger LOG = Log.getLogger(MultiPartFormInputStream.class); + private static final int DEFAULT_MAX_FORM_KEYS = 1000; private static final MultiMap EMPTY_MAP = new MultiMap<>(Collections.emptyMap()); - private final MultiMap _parts; private final EnumSet _nonComplianceWarnings = EnumSet.noneOf(NonCompliance.class); + private final MultiMap _parts; + private final int _maxParts; + private int _numParts = 0; private InputStream _in; private MultipartConfigElement _config; private String _contentType; @@ -351,17 +354,29 @@ */ public MultiPartFormInputStream(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir) { + this(in, contentType, config, contextTmpDir, DEFAULT_MAX_FORM_KEYS); + } + + /** + * @param in Request input stream + * @param contentType Content-Type header + * @param config MultipartConfigElement + * @param contextTmpDir javax.servlet.context.tempdir + * @param maxParts the maximum number of parts that can be parsed from the multipart content (0 for no parts allowed, -1 for unlimited parts). + */ + public MultiPartFormInputStream(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir, int maxParts) + { _contentType = contentType; _config = config; _contextTmpDir = contextTmpDir; + _maxParts = maxParts; if (_contextTmpDir == null) _contextTmpDir = new File(System.getProperty("java.io.tmpdir")); if (_config == null) _config = new MultipartConfigElement(_contextTmpDir.getAbsolutePath()); - MultiMap parts = new MultiMap(); - + MultiMap parts = new MultiMap<>(); if (in instanceof ServletInputStream) { if (((ServletInputStream)in).isFinished()) @@ -752,6 +767,9 @@ public void startPart() { reset(); + _numParts++; + if (_maxParts >= 0 && _numParts > _maxParts) + throw new IllegalStateException(String.format("Form with too many parts [%d > %d]", _numParts, _maxParts)); } @Override diff -Nru jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/compression/EncodingException.java jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/compression/EncodingException.java --- jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/compression/EncodingException.java 1970-01-01 00:00:00.000000000 +0000 +++ jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/compression/EncodingException.java 2024-12-19 21:51:26.000000000 +0000 @@ -0,0 +1,27 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http.compression; + +public class EncodingException extends Exception +{ + public EncodingException(String message) + { + super(message); + } +} diff -Nru jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/compression/Huffman.java jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/compression/Huffman.java --- jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/compression/Huffman.java 1970-01-01 00:00:00.000000000 +0000 +++ jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/compression/Huffman.java 2024-12-19 21:51:26.000000000 +0000 @@ -0,0 +1,357 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http.compression; + +/** + * This class contains the Huffman Codes defined in RFC7541. + */ +public class Huffman +{ + private Huffman() + { + } + + // Appendix C: Huffman Codes + // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-12#appendix-C + static final int[][] CODES = + { + /* ( 0) |11111111|11000 */ {0x1ff8, 13}, + /* ( 1) |11111111|11111111|1011000 */ {0x7fffd8, 23}, + /* ( 2) |11111111|11111111|11111110|0010 */ {0xfffffe2, 28}, + /* ( 3) |11111111|11111111|11111110|0011 */ {0xfffffe3, 28}, + /* ( 4) |11111111|11111111|11111110|0100 */ {0xfffffe4, 28}, + /* ( 5) |11111111|11111111|11111110|0101 */ {0xfffffe5, 28}, + /* ( 6) |11111111|11111111|11111110|0110 */ {0xfffffe6, 28}, + /* ( 7) |11111111|11111111|11111110|0111 */ {0xfffffe7, 28}, + /* ( 8) |11111111|11111111|11111110|1000 */ {0xfffffe8, 28}, + /* ( 9) |11111111|11111111|11101010 */ {0xffffea, 24}, + /* ( 10) |11111111|11111111|11111111|111100 */ {0x3ffffffc, 30}, + /* ( 11) |11111111|11111111|11111110|1001 */ {0xfffffe9, 28}, + /* ( 12) |11111111|11111111|11111110|1010 */ {0xfffffea, 28}, + /* ( 13) |11111111|11111111|11111111|111101 */ {0x3ffffffd, 30}, + /* ( 14) |11111111|11111111|11111110|1011 */ {0xfffffeb, 28}, + /* ( 15) |11111111|11111111|11111110|1100 */ {0xfffffec, 28}, + /* ( 16) |11111111|11111111|11111110|1101 */ {0xfffffed, 28}, + /* ( 17) |11111111|11111111|11111110|1110 */ {0xfffffee, 28}, + /* ( 18) |11111111|11111111|11111110|1111 */ {0xfffffef, 28}, + /* ( 19) |11111111|11111111|11111111|0000 */ {0xffffff0, 28}, + /* ( 20) |11111111|11111111|11111111|0001 */ {0xffffff1, 28}, + /* ( 21) |11111111|11111111|11111111|0010 */ {0xffffff2, 28}, + /* ( 22) |11111111|11111111|11111111|111110 */ {0x3ffffffe, 30}, + /* ( 23) |11111111|11111111|11111111|0011 */ {0xffffff3, 28}, + /* ( 24) |11111111|11111111|11111111|0100 */ {0xffffff4, 28}, + /* ( 25) |11111111|11111111|11111111|0101 */ {0xffffff5, 28}, + /* ( 26) |11111111|11111111|11111111|0110 */ {0xffffff6, 28}, + /* ( 27) |11111111|11111111|11111111|0111 */ {0xffffff7, 28}, + /* ( 28) |11111111|11111111|11111111|1000 */ {0xffffff8, 28}, + /* ( 29) |11111111|11111111|11111111|1001 */ {0xffffff9, 28}, + /* ( 30) |11111111|11111111|11111111|1010 */ {0xffffffa, 28}, + /* ( 31) |11111111|11111111|11111111|1011 */ {0xffffffb, 28}, + /*' ' ( 32) |010100 */ {0x14, 6}, + /*'!' ( 33) |11111110|00 */ {0x3f8, 10}, + /*'"' ( 34) |11111110|01 */ {0x3f9, 10}, + /*'#' ( 35) |11111111|1010 */ {0xffa, 12}, + /*'$' ( 36) |11111111|11001 */ {0x1ff9, 13}, + /*'%' ( 37) |010101 */ {0x15, 6}, + /*'&' ( 38) |11111000 */ {0xf8, 8}, + /*''' ( 39) |11111111|010 */ {0x7fa, 11}, + /*'(' ( 40) |11111110|10 */ {0x3fa, 10}, + /*')' ( 41) |11111110|11 */ {0x3fb, 10}, + /*'*' ( 42) |11111001 */ {0xf9, 8}, + /*'+' ( 43) |11111111|011 */ {0x7fb, 11}, + /*',' ( 44) |11111010 */ {0xfa, 8}, + /*'-' ( 45) |010110 */ {0x16, 6}, + /*'.' ( 46) |010111 */ {0x17, 6}, + /*'/' ( 47) |011000 */ {0x18, 6}, + /*'0' ( 48) |00000 */ {0x0, 5}, + /*'1' ( 49) |00001 */ {0x1, 5}, + /*'2' ( 50) |00010 */ {0x2, 5}, + /*'3' ( 51) |011001 */ {0x19, 6}, + /*'4' ( 52) |011010 */ {0x1a, 6}, + /*'5' ( 53) |011011 */ {0x1b, 6}, + /*'6' ( 54) |011100 */ {0x1c, 6}, + /*'7' ( 55) |011101 */ {0x1d, 6}, + /*'8' ( 56) |011110 */ {0x1e, 6}, + /*'9' ( 57) |011111 */ {0x1f, 6}, + /*':' ( 58) |1011100 */ {0x5c, 7}, + /*';' ( 59) |11111011 */ {0xfb, 8}, + /*'<' ( 60) |11111111|1111100 */ {0x7ffc, 15}, + /*'=' ( 61) |100000 */ {0x20, 6}, + /*'>' ( 62) |11111111|1011 */ {0xffb, 12}, + /*'?' ( 63) |11111111|00 */ {0x3fc, 10}, + /*'@' ( 64) |11111111|11010 */ {0x1ffa, 13}, + /*'A' ( 65) |100001 */ {0x21, 6}, + /*'B' ( 66) |1011101 */ {0x5d, 7}, + /*'C' ( 67) |1011110 */ {0x5e, 7}, + /*'D' ( 68) |1011111 */ {0x5f, 7}, + /*'E' ( 69) |1100000 */ {0x60, 7}, + /*'F' ( 70) |1100001 */ {0x61, 7}, + /*'G' ( 71) |1100010 */ {0x62, 7}, + /*'H' ( 72) |1100011 */ {0x63, 7}, + /*'I' ( 73) |1100100 */ {0x64, 7}, + /*'J' ( 74) |1100101 */ {0x65, 7}, + /*'K' ( 75) |1100110 */ {0x66, 7}, + /*'L' ( 76) |1100111 */ {0x67, 7}, + /*'M' ( 77) |1101000 */ {0x68, 7}, + /*'N' ( 78) |1101001 */ {0x69, 7}, + /*'O' ( 79) |1101010 */ {0x6a, 7}, + /*'P' ( 80) |1101011 */ {0x6b, 7}, + /*'Q' ( 81) |1101100 */ {0x6c, 7}, + /*'R' ( 82) |1101101 */ {0x6d, 7}, + /*'S' ( 83) |1101110 */ {0x6e, 7}, + /*'T' ( 84) |1101111 */ {0x6f, 7}, + /*'U' ( 85) |1110000 */ {0x70, 7}, + /*'V' ( 86) |1110001 */ {0x71, 7}, + /*'W' ( 87) |1110010 */ {0x72, 7}, + /*'X' ( 88) |11111100 */ {0xfc, 8}, + /*'Y' ( 89) |1110011 */ {0x73, 7}, + /*'Z' ( 90) |11111101 */ {0xfd, 8}, + /*'[' ( 91) |11111111|11011 */ {0x1ffb, 13}, + /*'\' ( 92) |11111111|11111110|000 */ {0x7fff0, 19}, + /*']' ( 93) |11111111|11100 */ {0x1ffc, 13}, + /*'^' ( 94) |11111111|111100 */ {0x3ffc, 14}, + /*'_' ( 95) |100010 */ {0x22, 6}, + /*'`' ( 96) |11111111|1111101 */ {0x7ffd, 15}, + /*'a' ( 97) |00011 */ {0x3, 5}, + /*'b' ( 98) |100011 */ {0x23, 6}, + /*'c' ( 99) |00100 */ {0x4, 5}, + /*'d' (100) |100100 */ {0x24, 6}, + /*'e' (101) |00101 */ {0x5, 5}, + /*'f' (102) |100101 */ {0x25, 6}, + /*'g' (103) |100110 */ {0x26, 6}, + /*'h' (104) |100111 */ {0x27, 6}, + /*'i' (105) |00110 */ {0x6, 5}, + /*'j' (106) |1110100 */ {0x74, 7}, + /*'k' (107) |1110101 */ {0x75, 7}, + /*'l' (108) |101000 */ {0x28, 6}, + /*'m' (109) |101001 */ {0x29, 6}, + /*'n' (110) |101010 */ {0x2a, 6}, + /*'o' (111) |00111 */ {0x7, 5}, + /*'p' (112) |101011 */ {0x2b, 6}, + /*'q' (113) |1110110 */ {0x76, 7}, + /*'r' (114) |101100 */ {0x2c, 6}, + /*'s' (115) |01000 */ {0x8, 5}, + /*'t' (116) |01001 */ {0x9, 5}, + /*'u' (117) |101101 */ {0x2d, 6}, + /*'v' (118) |1110111 */ {0x77, 7}, + /*'w' (119) |1111000 */ {0x78, 7}, + /*'x' (120) |1111001 */ {0x79, 7}, + /*'y' (121) |1111010 */ {0x7a, 7}, + /*'z' (122) |1111011 */ {0x7b, 7}, + /*'{' (123) |11111111|1111110 */ {0x7ffe, 15}, + /*'|' (124) |11111111|100 */ {0x7fc, 11}, + /*'}' (125) |11111111|111101 */ {0x3ffd, 14}, + /*'~' (126) |11111111|11101 */ {0x1ffd, 13}, + /* (127) |11111111|11111111|11111111|1100 */ {0xffffffc, 28}, + /* (128) |11111111|11111110|0110 */ {0xfffe6, 20}, + /* (129) |11111111|11111111|010010 */ {0x3fffd2, 22}, + /* (130) |11111111|11111110|0111 */ {0xfffe7, 20}, + /* (131) |11111111|11111110|1000 */ {0xfffe8, 20}, + /* (132) |11111111|11111111|010011 */ {0x3fffd3, 22}, + /* (133) |11111111|11111111|010100 */ {0x3fffd4, 22}, + /* (134) |11111111|11111111|010101 */ {0x3fffd5, 22}, + /* (135) |11111111|11111111|1011001 */ {0x7fffd9, 23}, + /* (136) |11111111|11111111|010110 */ {0x3fffd6, 22}, + /* (137) |11111111|11111111|1011010 */ {0x7fffda, 23}, + /* (138) |11111111|11111111|1011011 */ {0x7fffdb, 23}, + /* (139) |11111111|11111111|1011100 */ {0x7fffdc, 23}, + /* (140) |11111111|11111111|1011101 */ {0x7fffdd, 23}, + /* (141) |11111111|11111111|1011110 */ {0x7fffde, 23}, + /* (142) |11111111|11111111|11101011 */ {0xffffeb, 24}, + /* (143) |11111111|11111111|1011111 */ {0x7fffdf, 23}, + /* (144) |11111111|11111111|11101100 */ {0xffffec, 24}, + /* (145) |11111111|11111111|11101101 */ {0xffffed, 24}, + /* (146) |11111111|11111111|010111 */ {0x3fffd7, 22}, + /* (147) |11111111|11111111|1100000 */ {0x7fffe0, 23}, + /* (148) |11111111|11111111|11101110 */ {0xffffee, 24}, + /* (149) |11111111|11111111|1100001 */ {0x7fffe1, 23}, + /* (150) |11111111|11111111|1100010 */ {0x7fffe2, 23}, + /* (151) |11111111|11111111|1100011 */ {0x7fffe3, 23}, + /* (152) |11111111|11111111|1100100 */ {0x7fffe4, 23}, + /* (153) |11111111|11111110|11100 */ {0x1fffdc, 21}, + /* (154) |11111111|11111111|011000 */ {0x3fffd8, 22}, + /* (155) |11111111|11111111|1100101 */ {0x7fffe5, 23}, + /* (156) |11111111|11111111|011001 */ {0x3fffd9, 22}, + /* (157) |11111111|11111111|1100110 */ {0x7fffe6, 23}, + /* (158) |11111111|11111111|1100111 */ {0x7fffe7, 23}, + /* (159) |11111111|11111111|11101111 */ {0xffffef, 24}, + /* (160) |11111111|11111111|011010 */ {0x3fffda, 22}, + /* (161) |11111111|11111110|11101 */ {0x1fffdd, 21}, + /* (162) |11111111|11111110|1001 */ {0xfffe9, 20}, + /* (163) |11111111|11111111|011011 */ {0x3fffdb, 22}, + /* (164) |11111111|11111111|011100 */ {0x3fffdc, 22}, + /* (165) |11111111|11111111|1101000 */ {0x7fffe8, 23}, + /* (166) |11111111|11111111|1101001 */ {0x7fffe9, 23}, + /* (167) |11111111|11111110|11110 */ {0x1fffde, 21}, + /* (168) |11111111|11111111|1101010 */ {0x7fffea, 23}, + /* (169) |11111111|11111111|011101 */ {0x3fffdd, 22}, + /* (170) |11111111|11111111|011110 */ {0x3fffde, 22}, + /* (171) |11111111|11111111|11110000 */ {0xfffff0, 24}, + /* (172) |11111111|11111110|11111 */ {0x1fffdf, 21}, + /* (173) |11111111|11111111|011111 */ {0x3fffdf, 22}, + /* (174) |11111111|11111111|1101011 */ {0x7fffeb, 23}, + /* (175) |11111111|11111111|1101100 */ {0x7fffec, 23}, + /* (176) |11111111|11111111|00000 */ {0x1fffe0, 21}, + /* (177) |11111111|11111111|00001 */ {0x1fffe1, 21}, + /* (178) |11111111|11111111|100000 */ {0x3fffe0, 22}, + /* (179) |11111111|11111111|00010 */ {0x1fffe2, 21}, + /* (180) |11111111|11111111|1101101 */ {0x7fffed, 23}, + /* (181) |11111111|11111111|100001 */ {0x3fffe1, 22}, + /* (182) |11111111|11111111|1101110 */ {0x7fffee, 23}, + /* (183) |11111111|11111111|1101111 */ {0x7fffef, 23}, + /* (184) |11111111|11111110|1010 */ {0xfffea, 20}, + /* (185) |11111111|11111111|100010 */ {0x3fffe2, 22}, + /* (186) |11111111|11111111|100011 */ {0x3fffe3, 22}, + /* (187) |11111111|11111111|100100 */ {0x3fffe4, 22}, + /* (188) |11111111|11111111|1110000 */ {0x7ffff0, 23}, + /* (189) |11111111|11111111|100101 */ {0x3fffe5, 22}, + /* (190) |11111111|11111111|100110 */ {0x3fffe6, 22}, + /* (191) |11111111|11111111|1110001 */ {0x7ffff1, 23}, + /* (192) |11111111|11111111|11111000|00 */ {0x3ffffe0, 26}, + /* (193) |11111111|11111111|11111000|01 */ {0x3ffffe1, 26}, + /* (194) |11111111|11111110|1011 */ {0xfffeb, 20}, + /* (195) |11111111|11111110|001 */ {0x7fff1, 19}, + /* (196) |11111111|11111111|100111 */ {0x3fffe7, 22}, + /* (197) |11111111|11111111|1110010 */ {0x7ffff2, 23}, + /* (198) |11111111|11111111|101000 */ {0x3fffe8, 22}, + /* (199) |11111111|11111111|11110110|0 */ {0x1ffffec, 25}, + /* (200) |11111111|11111111|11111000|10 */ {0x3ffffe2, 26}, + /* (201) |11111111|11111111|11111000|11 */ {0x3ffffe3, 26}, + /* (202) |11111111|11111111|11111001|00 */ {0x3ffffe4, 26}, + /* (203) |11111111|11111111|11111011|110 */ {0x7ffffde, 27}, + /* (204) |11111111|11111111|11111011|111 */ {0x7ffffdf, 27}, + /* (205) |11111111|11111111|11111001|01 */ {0x3ffffe5, 26}, + /* (206) |11111111|11111111|11110001 */ {0xfffff1, 24}, + /* (207) |11111111|11111111|11110110|1 */ {0x1ffffed, 25}, + /* (208) |11111111|11111110|010 */ {0x7fff2, 19}, + /* (209) |11111111|11111111|00011 */ {0x1fffe3, 21}, + /* (210) |11111111|11111111|11111001|10 */ {0x3ffffe6, 26}, + /* (211) |11111111|11111111|11111100|000 */ {0x7ffffe0, 27}, + /* (212) |11111111|11111111|11111100|001 */ {0x7ffffe1, 27}, + /* (213) |11111111|11111111|11111001|11 */ {0x3ffffe7, 26}, + /* (214) |11111111|11111111|11111100|010 */ {0x7ffffe2, 27}, + /* (215) |11111111|11111111|11110010 */ {0xfffff2, 24}, + /* (216) |11111111|11111111|00100 */ {0x1fffe4, 21}, + /* (217) |11111111|11111111|00101 */ {0x1fffe5, 21}, + /* (218) |11111111|11111111|11111010|00 */ {0x3ffffe8, 26}, + /* (219) |11111111|11111111|11111010|01 */ {0x3ffffe9, 26}, + /* (220) |11111111|11111111|11111111|1101 */ {0xffffffd, 28}, + /* (221) |11111111|11111111|11111100|011 */ {0x7ffffe3, 27}, + /* (222) |11111111|11111111|11111100|100 */ {0x7ffffe4, 27}, + /* (223) |11111111|11111111|11111100|101 */ {0x7ffffe5, 27}, + /* (224) |11111111|11111110|1100 */ {0xfffec, 20}, + /* (225) |11111111|11111111|11110011 */ {0xfffff3, 24}, + /* (226) |11111111|11111110|1101 */ {0xfffed, 20}, + /* (227) |11111111|11111111|00110 */ {0x1fffe6, 21}, + /* (228) |11111111|11111111|101001 */ {0x3fffe9, 22}, + /* (229) |11111111|11111111|00111 */ {0x1fffe7, 21}, + /* (230) |11111111|11111111|01000 */ {0x1fffe8, 21}, + /* (231) |11111111|11111111|1110011 */ {0x7ffff3, 23}, + /* (232) |11111111|11111111|101010 */ {0x3fffea, 22}, + /* (233) |11111111|11111111|101011 */ {0x3fffeb, 22}, + /* (234) |11111111|11111111|11110111|0 */ {0x1ffffee, 25}, + /* (235) |11111111|11111111|11110111|1 */ {0x1ffffef, 25}, + /* (236) |11111111|11111111|11110100 */ {0xfffff4, 24}, + /* (237) |11111111|11111111|11110101 */ {0xfffff5, 24}, + /* (238) |11111111|11111111|11111010|10 */ {0x3ffffea, 26}, + /* (239) |11111111|11111111|1110100 */ {0x7ffff4, 23}, + /* (240) |11111111|11111111|11111010|11 */ {0x3ffffeb, 26}, + /* (241) |11111111|11111111|11111100|110 */ {0x7ffffe6, 27}, + /* (242) |11111111|11111111|11111011|00 */ {0x3ffffec, 26}, + /* (243) |11111111|11111111|11111011|01 */ {0x3ffffed, 26}, + /* (244) |11111111|11111111|11111100|111 */ {0x7ffffe7, 27}, + /* (245) |11111111|11111111|11111101|000 */ {0x7ffffe8, 27}, + /* (246) |11111111|11111111|11111101|001 */ {0x7ffffe9, 27}, + /* (247) |11111111|11111111|11111101|010 */ {0x7ffffea, 27}, + /* (248) |11111111|11111111|11111101|011 */ {0x7ffffeb, 27}, + /* (249) |11111111|11111111|11111111|1110 */ {0xffffffe, 28}, + /* (250) |11111111|11111111|11111101|100 */ {0x7ffffec, 27}, + /* (251) |11111111|11111111|11111101|101 */ {0x7ffffed, 27}, + /* (252) |11111111|11111111|11111101|110 */ {0x7ffffee, 27}, + /* (253) |11111111|11111111|11111101|111 */ {0x7ffffef, 27}, + /* (254) |11111111|11111111|11111110|000 */ {0x7fffff0, 27}, + /* (255) |11111111|11111111|11111011|10 */ {0x3ffffee, 26}, + /*EOS (256) |11111111|11111111|11111111|111111 */ {0x3fffffff, 30} + }; + + static final int[][] LCCODES = new int[CODES.length][]; + static final char EOS = 256; + + // Huffman decode tree stored in a flattened char array for good + // locality of reference. + static final char[] tree; + static final char[] rowsym; + static final byte[] rowbits; + + // Build the Huffman lookup tree and LC TABLE + static + { + System.arraycopy(CODES, 0, LCCODES, 0, CODES.length); + for (int i = 'A'; i <= 'Z'; i++) + { + LCCODES[i] = LCCODES['a' + i - 'A']; + } + + int r = 0; + for (int[] ints : CODES) + { + r += (ints[1] + 7) / 8; + } + tree = new char[r * 256]; + rowsym = new char[r]; + rowbits = new byte[r]; + + r = 0; + for (int sym = 0; sym < CODES.length; sym++) + { + int code = CODES[sym][0]; + int len = CODES[sym][1]; + + int current = 0; + + while (len > 8) + { + len -= 8; + int i = ((code >>> len) & 0xFF); + + int t = current * 256 + i; + current = tree[t]; + if (current == 0) + { + tree[t] = (char)++r; + current = r; + } + } + + int terminal = ++r; + rowsym[r] = (char)sym; + int b = len & 0x07; + int terminalBits = b == 0 ? 8 : b; + + rowbits[r] = (byte)terminalBits; + int shift = 8 - len; + int start = current * 256 + ((code << shift) & 0xFF); + int end = start + (1 << shift); + for (int i = start; i < end; i++) + { + tree[i] = (char)terminal; + } + } + } +} diff -Nru jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/compression/HuffmanDecoder.java jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/compression/HuffmanDecoder.java --- jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/compression/HuffmanDecoder.java 1970-01-01 00:00:00.000000000 +0000 +++ jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/compression/HuffmanDecoder.java 2024-12-19 21:51:26.000000000 +0000 @@ -0,0 +1,143 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http.compression; + +import java.nio.ByteBuffer; + +import org.eclipse.jetty.http.HttpTokens; +import org.eclipse.jetty.util.CharsetStringBuilder; + +import static org.eclipse.jetty.http.compression.Huffman.rowbits; +import static org.eclipse.jetty.http.compression.Huffman.rowsym; + +/** + *

    Used to decoded Huffman encoded strings.

    + * + *

    Characters which are illegal field-vchar values are replaced with + * either ' ' or '?' as described in RFC9110

    + */ +public class HuffmanDecoder +{ + private final CharsetStringBuilder.Iso88591StringBuilder _builder = new CharsetStringBuilder.Iso88591StringBuilder(); + private int _length = 0; + private int _count = 0; + private int _node = 0; + private int _current = 0; + private int _bits = 0; + + /** + * @param length in bytes of the huffman data. + */ + public void setLength(int length) + { + if (_count != 0) + throw new IllegalStateException(); + _length = length; + } + + /** + * @param buffer the buffer containing the Huffman encoded bytes. + * @return the decoded String. + * @throws EncodingException if the huffman encoding is invalid. + */ + public String decode(ByteBuffer buffer) throws EncodingException + { + for (; _count < _length; _count++) + { + if (!buffer.hasRemaining()) + return null; + + int b = buffer.get() & 0xFF; + _current = (_current << 8) | b; + _bits += 8; + while (_bits >= 8) + { + int i = (_current >>> (_bits - 8)) & 0xFF; + _node = Huffman.tree[_node * 256 + i]; + if (rowbits[_node] != 0) + { + if (rowsym[_node] == Huffman.EOS) + { + reset(); + throw new EncodingException("eos_in_content"); + } + + // terminal node + char c = rowsym[_node]; + c = HttpTokens.sanitizeFieldVchar(c); + _builder.append((byte)c); + _bits -= rowbits[_node]; + _node = 0; + } + else + { + // non-terminal node + _bits -= 8; + } + } + } + + while (_bits > 0) + { + int i = (_current << (8 - _bits)) & 0xFF; + int lastNode = _node; + _node = Huffman.tree[_node * 256 + i]; + + if (rowbits[_node] == 0 || rowbits[_node] > _bits) + { + int requiredPadding = 0; + for (int j = 0; j < _bits; j++) + { + requiredPadding = (requiredPadding << 1) | 1; + } + + if ((i >> (8 - _bits)) != requiredPadding) + throw new EncodingException("incorrect_padding"); + + _node = lastNode; + break; + } + + char c = rowsym[_node]; + c = HttpTokens.sanitizeFieldVchar(c); + _builder.append((byte)c); + _bits -= rowbits[_node]; + _node = 0; + } + + if (_node != 0) + { + reset(); + throw new EncodingException("bad_termination"); + } + + String value = _builder.build(); + reset(); + return value; + } + + public void reset() + { + _builder.reset(); + _count = 0; + _current = 0; + _node = 0; + _bits = 0; + } +} diff -Nru jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/compression/HuffmanEncoder.java jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/compression/HuffmanEncoder.java --- jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/compression/HuffmanEncoder.java 1970-01-01 00:00:00.000000000 +0000 +++ jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/compression/HuffmanEncoder.java 2024-12-19 21:51:26.000000000 +0000 @@ -0,0 +1,142 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http.compression; + +import java.nio.ByteBuffer; + +import org.eclipse.jetty.http.HttpTokens; + +import static org.eclipse.jetty.http.compression.Huffman.CODES; +import static org.eclipse.jetty.http.compression.Huffman.LCCODES; + +/** + *

    Used to encode strings Huffman encoding.

    + * + *

    Characters are encoded with ISO-8859-1, if any multi-byte characters or + * control characters are present the encoder will throw {@link EncodingException}.

    + */ +public class HuffmanEncoder +{ + private HuffmanEncoder() + { + } + + /** + * @param s the string to encode. + * @return the number of octets needed to encode the string, or -1 if it cannot be encoded. + */ + public static int octetsNeeded(String s) + { + return octetsNeeded(CODES, s); + } + + /** + * @param b the byte array to encode. + * @return the number of octets needed to encode the bytes, or -1 if it cannot be encoded. + */ + public static int octetsNeeded(byte[] b) + { + int needed = 0; + for (byte value : b) + { + int c = 0xFF & value; + needed += CODES[c][1]; + } + return (needed + 7) / 8; + } + + /** + * @param buffer the buffer to encode into. + * @param s the string to encode. + */ + public static void encode(ByteBuffer buffer, String s) + { + encode(CODES, buffer, s); + } + + /** + * @param s the string to encode in lowercase. + * @return the number of octets needed to encode the string, or -1 if it cannot be encoded. + */ + public static int octetsNeededLowerCase(String s) + { + return octetsNeeded(LCCODES, s); + } + + /** + * @param buffer the buffer to encode into in lowercase. + * @param s the string to encode. + */ + public static void encodeLowerCase(ByteBuffer buffer, String s) + { + encode(LCCODES, buffer, s); + } + + private static int octetsNeeded(final int[][] table, String s) + { + int needed = 0; + int len = s.length(); + for (int i = 0; i < len; i++) + { + char c = s.charAt(i); + if (HttpTokens.isIllegalFieldVchar(c)) + return -1; + needed += table[c][1]; + } + + return (needed + 7) / 8; + } + + /** + * @param table The table to encode by + * @param buffer The buffer to encode to + * @param s The string to encode + */ + private static void encode(final int[][] table, ByteBuffer buffer, String s) + { + long current = 0; + int n = 0; + int len = s.length(); + for (int i = 0; i < len; i++) + { + char c = s.charAt(i); + if (HttpTokens.isIllegalFieldVchar(c)) + throw new IllegalArgumentException(); + int code = table[c][0]; + int bits = table[c][1]; + + current <<= bits; + current |= code; + n += bits; + + while (n >= 8) + { + n -= 8; + buffer.put((byte)(current >> n)); + } + } + + if (n > 0) + { + current <<= (8 - n); + current |= (0xFF >>> n); + buffer.put((byte)(current)); + } + } +} diff -Nru jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitIntegerDecoder.java jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitIntegerDecoder.java --- jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitIntegerDecoder.java 1970-01-01 00:00:00.000000000 +0000 +++ jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitIntegerDecoder.java 2024-12-19 21:51:26.000000000 +0000 @@ -0,0 +1,113 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http.compression; + +import java.nio.ByteBuffer; + +/** + * Used to decode integers as described in RFC7541. + */ +public class NBitIntegerDecoder +{ + private int _prefix; + private long _total; + private long _multiplier; + private boolean _started; + + /** + * Set the prefix length in of the integer representation in bits. + * A prefix of 6 means the integer representation starts after the first 2 bits. + * @param prefix the number of bits in the integer prefix. + */ + public void setPrefix(int prefix) + { + if (_started) + throw new IllegalStateException(); + _prefix = prefix; + } + + /** + * Decode an integer from the buffer. If the buffer does not contain the complete integer representation + * a value of -1 is returned to indicate that more data is needed to complete parsing. + * This should be only after the prefix has been set with {@link #setPrefix(int)}. + * @param buffer the buffer containing the encoded integer. + * @return the decoded integer or -1 to indicate that more data is needed. + * @throws ArithmeticException if the value overflows a int. + */ + public int decodeInt(ByteBuffer buffer) + { + return Math.toIntExact(decodeLong(buffer)); + } + + /** + * Decode a long from the buffer. If the buffer does not contain the complete integer representation + * a value of -1 is returned to indicate that more data is needed to complete parsing. + * This should be only after the prefix has been set with {@link #setPrefix(int)}. + * @param buffer the buffer containing the encoded integer. + * @return the decoded long or -1 to indicate that more data is needed. + * @throws ArithmeticException if the value overflows a long. + */ + public long decodeLong(ByteBuffer buffer) + { + if (!_started) + { + if (!buffer.hasRemaining()) + return -1; + + _started = true; + _multiplier = 1; + int nbits = 0xFF >>> (8 - _prefix); + _total = buffer.get() & nbits; + if (_total < nbits) + { + long total = _total; + reset(); + return total; + } + } + + while (true) + { + // If we have no more remaining we return -1 to indicate that more data is needed to continue parsing. + if (!buffer.hasRemaining()) + return -1; + + int b = buffer.get() & 0xFF; + _total = Math.addExact(_total, (b & 127) * _multiplier); + _multiplier = Math.multiplyExact(_multiplier, 128); + if ((b & 128) == 0) + { + long total = _total; + reset(); + return total; + } + } + } + + /** + * Reset the internal state of the parser. + */ + public void reset() + { + _prefix = 0; + _total = 0; + _multiplier = 1; + _started = false; + } +} diff -Nru jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitIntegerEncoder.java jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitIntegerEncoder.java --- jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitIntegerEncoder.java 1970-01-01 00:00:00.000000000 +0000 +++ jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitIntegerEncoder.java 2024-12-19 21:51:26.000000000 +0000 @@ -0,0 +1,96 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http.compression; + +import java.nio.ByteBuffer; + +/** + * Used to encode integers as described in RFC7541. + */ +public class NBitIntegerEncoder +{ + private NBitIntegerEncoder() + { + } + + /** + * @param prefix the prefix used to encode this long. + * @param value the integer to encode. + * @return the number of octets it would take to encode the long. + */ + public static int octetsNeeded(int prefix, long value) + { + if (prefix <= 0 || prefix > 8) + throw new IllegalArgumentException(); + + int nbits = 0xFF >>> (8 - prefix); + value = value - nbits; + if (value < 0) + return 1; + if (value == 0) + return 2; + int lz = Long.numberOfLeadingZeros(value); + int log = 64 - lz; + + // The return value is 1 for the prefix + the number of 7-bit groups necessary to encode the value. + return 1 + (log + 6) / 7; + } + + /** + * + * @param buffer the buffer to encode into. + * @param prefix the prefix used to encode this long. + * @param value the long to encode into the buffer. + */ + public static void encode(ByteBuffer buffer, int prefix, long value) + { + if (prefix <= 0 || prefix > 8) + throw new IllegalArgumentException(); + + // If prefix is 8 we add an empty byte as we initially modify last byte from the buffer. + if (prefix == 8) + buffer.put((byte)0x00); + + int bits = 0xFF >>> (8 - prefix); + int p = buffer.position() - 1; + if (value < bits) + { + buffer.put(p, (byte)((buffer.get(p) & ~bits) | value)); + } + else + { + buffer.put(p, (byte)(buffer.get(p) | bits)); + long length = value - bits; + while (true) + { + // The value of ~0x7F is different to 0x80 because of all the 1s from the MSB. + if ((length & ~0x7FL) == 0) + { + buffer.put((byte)length); + return; + } + else + { + buffer.put((byte)((length & 0x7F) | 0x80)); + length >>>= 7; + } + } + } + } +} diff -Nru jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitStringDecoder.java jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitStringDecoder.java --- jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitStringDecoder.java 1970-01-01 00:00:00.000000000 +0000 +++ jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitStringDecoder.java 2024-12-19 21:51:26.000000000 +0000 @@ -0,0 +1,138 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http.compression; + +import java.nio.ByteBuffer; + +import org.eclipse.jetty.util.CharsetStringBuilder; + +/** + *

    Used to decode string literals as described in RFC7541.

    + * + *

    The string literal representation consists of a single bit to indicate whether huffman encoding is used, + * followed by the string byte length encoded with the n-bit integer representation also from RFC7541, and + * the bytes of the string are directly after this.

    + * + *

    Characters which are illegal field-vchar values are replaced with + * either ' ' or '?' as described in RFC9110

    + */ +public class NBitStringDecoder +{ + private final NBitIntegerDecoder _integerDecoder; + private final HuffmanDecoder _huffmanBuilder; + private final CharsetStringBuilder.Iso88591StringBuilder _builder; + private boolean _huffman; + private int _count; + private int _length; + private int _prefix; + + private State _state = State.PARSING; + + private enum State + { + PARSING, + LENGTH, + VALUE + } + + public NBitStringDecoder() + { + _integerDecoder = new NBitIntegerDecoder(); + _huffmanBuilder = new HuffmanDecoder(); + _builder = new CharsetStringBuilder.Iso88591StringBuilder(); + } + + /** + * Set the prefix length in of the string representation in bits. + * A prefix of 6 means the string representation starts after the first 2 bits. + * @param prefix the number of bits in the string prefix. + */ + public void setPrefix(int prefix) + { + if (_state != State.PARSING) + throw new IllegalStateException(); + _prefix = prefix; + } + + /** + * Decode a string from the buffer. If the buffer does not contain the complete string representation + * then a value of null is returned to indicate that more data is needed to complete parsing. + * This should be only after the prefix has been set with {@link #setPrefix(int)}. + * @param buffer the buffer containing the encoded string. + * @return the decoded string or null to indicate that more data is needed. + * @throws ArithmeticException if the string length value overflows a int. + * @throws EncodingException if the string encoding is invalid. + */ + public String decode(ByteBuffer buffer) throws EncodingException + { + while (true) + { + switch (_state) + { + case PARSING: + byte firstByte = buffer.get(buffer.position()); + _huffman = ((0x80 >>> (8 - _prefix)) & firstByte) != 0; + _state = State.LENGTH; + _integerDecoder.setPrefix(_prefix - 1); + continue; + + case LENGTH: + _length = _integerDecoder.decodeInt(buffer); + if (_length < 0) + return null; + _state = State.VALUE; + _huffmanBuilder.setLength(_length); + continue; + + case VALUE: + String value = _huffman ? _huffmanBuilder.decode(buffer) : stringDecode(buffer); + if (value != null) + reset(); + return value; + + default: + throw new IllegalStateException(_state.name()); + } + } + } + + private String stringDecode(ByteBuffer buffer) + { + for (; _count < _length; _count++) + { + if (!buffer.hasRemaining()) + return null; + _builder.append(buffer.get()); + } + + return _builder.build(); + } + + public void reset() + { + _state = State.PARSING; + _integerDecoder.reset(); + _huffmanBuilder.reset(); + _builder.reset(); + _prefix = 0; + _count = 0; + _length = 0; + _huffman = false; + } +} diff -Nru jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitStringEncoder.java jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitStringEncoder.java --- jetty9-9.4.50/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitStringEncoder.java 1970-01-01 00:00:00.000000000 +0000 +++ jetty9-9.4.57/jetty-http/src/main/java/org/eclipse/jetty/http/compression/NBitStringEncoder.java 2024-12-19 21:51:26.000000000 +0000 @@ -0,0 +1,82 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http.compression; + +import java.nio.ByteBuffer; + +import org.eclipse.jetty.http.HttpTokens; + +public class NBitStringEncoder +{ + private NBitStringEncoder() + { + } + + public static int octetsNeeded(int prefix, String value, boolean huffman) + { + if (prefix <= 0 || prefix > 8) + throw new IllegalArgumentException(); + + int contentPrefix = (prefix == 1) ? 8 : prefix - 1; + int encodedValueSize = huffman ? HuffmanEncoder.octetsNeeded(value) : value.length(); + int encodedLengthSize = NBitIntegerEncoder.octetsNeeded(contentPrefix, encodedValueSize); + + // If prefix was 1, then we count an extra byte needed for the prefix. + return encodedLengthSize + encodedValueSize + (prefix == 1 ? 1 : 0); + } + + public static void encode(ByteBuffer buffer, int prefix, String value, boolean huffman) + { + if (prefix <= 0 || prefix > 8) + throw new IllegalArgumentException(); + + byte huffmanFlag = huffman ? (byte)(0x01 << (prefix - 1)) : (byte)0x00; + if (prefix == 8) + { + buffer.put(huffmanFlag); + } + else + { + int p = buffer.position() - 1; + buffer.put(p, (byte)(buffer.get(p) | huffmanFlag)); + } + + // Start encoding size & content in rest of prefix. + // If prefix was 1 we set it back to 8 to indicate to start on a new byte. + prefix = (prefix == 1) ? 8 : prefix - 1; + + if (huffman) + { + int encodedValueSize = HuffmanEncoder.octetsNeeded(value); + NBitIntegerEncoder.encode(buffer, prefix, encodedValueSize); + HuffmanEncoder.encode(buffer, value); + } + else + { + int encodedValueSize = value.length(); + NBitIntegerEncoder.encode(buffer, prefix, encodedValueSize); + for (int i = 0; i < encodedValueSize; i++) + { + char c = value.charAt(i); + c = HttpTokens.sanitizeFieldVchar(c); + buffer.put((byte)c); + } + } + } +} diff -Nru jetty9-9.4.50/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java jetty9-9.4.57/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java --- jetty9-9.4.50/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -41,6 +41,7 @@ import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -1672,7 +1673,7 @@ } @Test - public void testUnknownReponseVersion() + public void testUnknownResponseVersion() { ByteBuffer buffer = BufferUtil.toBuffer( "HPPT/7.7 200 OK\r\n" + @@ -1815,65 +1816,31 @@ assertEquals(HttpParser.State.CLOSED, parser.getState()); } - @Test - public void testBadContentLength0() - { - ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.0\r\n" + - "Content-Length: abc\r\n" + - "Connection: close\r\n" + - "\r\n"); - - HttpParser.RequestHandler handler = new Handler(); - HttpParser parser = new HttpParser(handler); - - parser.parseNext(buffer); - assertEquals("GET", _methodOrVersion); - assertEquals("Invalid Content-Length Value", _bad); - assertFalse(buffer.hasRemaining()); - assertEquals(HttpParser.State.CLOSE, parser.getState()); - parser.atEOF(); - parser.parseNext(BufferUtil.EMPTY_BUFFER); - assertEquals(HttpParser.State.CLOSED, parser.getState()); - } - - @Test - public void testBadContentLength1() - { - ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.0\r\n" + - "Content-Length: 9999999999999999999999999999999999999999999999\r\n" + - "Connection: close\r\n" + - "\r\n"); - - HttpParser.RequestHandler handler = new Handler(); - HttpParser parser = new HttpParser(handler); - - parser.parseNext(buffer); - assertEquals("GET", _methodOrVersion); - assertEquals("Invalid Content-Length Value", _bad); - assertFalse(buffer.hasRemaining()); - assertEquals(HttpParser.State.CLOSE, parser.getState()); - parser.atEOF(); - parser.parseNext(BufferUtil.EMPTY_BUFFER); - assertEquals(HttpParser.State.CLOSED, parser.getState()); - } - - @Test - public void testBadContentLength2() + @ParameterizedTest + @ValueSource(strings = { + "abc", + "1.5", + "9999999999999999999999999999999999999999999999", + "-10", + "+10", + "1.0", + "1,0", + "10," + }) + public void testBadContentLengths(String contentLength) { ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.0\r\n" + - "Content-Length: 1.5\r\n" + - "Connection: close\r\n" + - "\r\n"); + "GET /test HTTP/1.1\r\n" + + "Host: localhost\r\n" + + "Content-Length: " + contentLength + "\r\n" + + "\r\n" + + "1234567890\r\n"); HttpParser.RequestHandler handler = new Handler(); - HttpParser parser = new HttpParser(handler); + HttpParser parser = new HttpParser(handler, HttpCompliance.RFC2616_LEGACY); + parseAll(parser, buffer); - parser.parseNext(buffer); - assertEquals("GET", _methodOrVersion); - assertEquals("Invalid Content-Length Value", _bad); + assertThat(_bad, notNullValue()); assertFalse(buffer.hasRemaining()); assertEquals(HttpParser.State.CLOSE, parser.getState()); parser.atEOF(); @@ -2084,7 +2051,7 @@ @Test public void testBadIPv6Host() { - try (StacklessLogging s = new StacklessLogging(HttpParser.class)) + try (StacklessLogging ignored = new StacklessLogging(HttpParser.class)) { ByteBuffer buffer = BufferUtil.toBuffer( "GET / HTTP/1.1\r\n" + @@ -2930,8 +2897,8 @@ private String _methodOrVersion; private String _uriOrStatus; private String _versionOrReason; - private List _fields = new ArrayList<>(); - private List _trailers = new ArrayList<>(); + private final List _fields = new ArrayList<>(); + private final List _trailers = new ArrayList<>(); private String[] _hdr; private String[] _val; private int _headers; diff -Nru jetty9-9.4.50/jetty-http/src/test/java/org/eclipse/jetty/http/HttpURITest.java jetty9-9.4.57/jetty-http/src/test/java/org/eclipse/jetty/http/HttpURITest.java --- jetty9-9.4.50/jetty-http/src/test/java/org/eclipse/jetty/http/HttpURITest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http/src/test/java/org/eclipse/jetty/http/HttpURITest.java 2024-12-19 21:51:26.000000000 +0000 @@ -87,11 +87,6 @@ uri.parse("http://foo/bar"); assertThat(uri.getHost(), is("foo")); assertThat(uri.getPath(), is("/bar")); - - // We do allow nulls if not encoded. This can be used for testing 2nd line of defence. - uri.parse("http://fo\000/bar"); - assertThat(uri.getHost(), is("fo\000")); - assertThat(uri.getPath(), is("/bar")); } @Test @@ -875,4 +870,36 @@ uri.setPath(""); assertEquals("//host", uri.toString()); } + + public static Stream badAuthorities() + { + return Stream.of( + "http://#host/path", + "https:// host/path", + "https://h st/path", + "https://h\000st/path", + "https://h%GGst/path", + "https://host%/path", + "https://host%0/path", + "https://host%u001f/path", + "https://host%:8080/path", + "https://host%0:8080/path", + "https://user%@host/path", + "https://user%0@host/path", + "https://host:notport/path", + "https://user@host:notport/path", + "https://user:password@host:notport/path", + "https://user @host.com/", + "https://user#@host.com/", + "https://[notIpv6]/", + "https://bad[0::1::2::3::4]/" + ); + } + + @ParameterizedTest + @MethodSource("badAuthorities") + public void testBadAuthority(String uri) + { + assertThrows(IllegalArgumentException.class, () -> new HttpURI(uri)); + } } diff -Nru jetty9-9.4.50/jetty-http/src/test/java/org/eclipse/jetty/http/HuffmanTest.java jetty9-9.4.57/jetty-http/src/test/java/org/eclipse/jetty/http/HuffmanTest.java --- jetty9-9.4.50/jetty-http/src/test/java/org/eclipse/jetty/http/HuffmanTest.java 1970-01-01 00:00:00.000000000 +0000 +++ jetty9-9.4.57/jetty-http/src/test/java/org/eclipse/jetty/http/HuffmanTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -0,0 +1,168 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http; + +import java.nio.ByteBuffer; +import java.util.Locale; +import java.util.stream.Stream; + +import org.eclipse.jetty.http.compression.EncodingException; +import org.eclipse.jetty.http.compression.HuffmanDecoder; +import org.eclipse.jetty.http.compression.HuffmanEncoder; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.TypeUtil; +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.equalTo; +import static org.hamcrest.Matchers.greaterThan; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class HuffmanTest +{ + public static String decode(ByteBuffer buffer, int length) throws EncodingException + { + HuffmanDecoder huffmanDecoder = new HuffmanDecoder(); + huffmanDecoder.setLength(length); + String decoded = huffmanDecoder.decode(buffer); + if (decoded == null) + throw new EncodingException("invalid string encoding"); + + huffmanDecoder.reset(); + return decoded; + } + + public static Stream data() + { + return Stream.of( + new String[][]{ + {"D.4.1", "f1e3c2e5f23a6ba0ab90f4ff", "www.example.com"}, + {"D.4.2", "a8eb10649cbf", "no-cache"}, + {"D.6.1k", "6402", "302"}, + {"D.6.1v", "aec3771a4b", "private"}, + {"D.6.1d", "d07abe941054d444a8200595040b8166e082a62d1bff", "Mon, 21 Oct 2013 20:13:21 GMT"}, + {"D.6.1l", "9d29ad171863c78f0b97c8e9ae82ae43d3", "https://www.example.com"}, + {"D.6.2te", "640cff", "303"}, + }).map(Arguments::of); + } + + @ParameterizedTest(name = "[{index}] spec={0}") + @MethodSource("data") + public void testDecode(String specSection, String hex, String expected) throws Exception + { + byte[] encoded = TypeUtil.fromHexString(hex); + HuffmanDecoder huffmanDecoder = new HuffmanDecoder(); + huffmanDecoder.setLength(encoded.length); + String decoded = huffmanDecoder.decode(ByteBuffer.wrap(encoded)); + assertEquals(expected, decoded, specSection); + } + + @ParameterizedTest(name = "[{index}] spec={0}") + @MethodSource("data") + public void testEncode(String specSection, String hex, String expected) + { + ByteBuffer buf = BufferUtil.allocate(1024); + int pos = BufferUtil.flipToFill(buf); + HuffmanEncoder.encode(buf, expected); + BufferUtil.flipToFlush(buf, pos); + String encoded = TypeUtil.toHexString(BufferUtil.toArray(buf)).toLowerCase(Locale.ENGLISH); + assertEquals(hex, encoded, specSection); + assertEquals(hex.length() / 2, HuffmanEncoder.octetsNeeded(expected)); + } + + public static Stream testDecode8859OnlyArguments() + { + return Stream.of( + // These are valid characters for ISO-8859-1. + Arguments.of("FfFe6f", (char)128), + Arguments.of("FfFfFbBf", (char)255), + + // RFC9110 specifies these to be replaced as ' ' during decoding. + Arguments.of("FfC7", ' '), // (char)0 + Arguments.of("FfFfFfF7", ' '), // '\r' + Arguments.of("FfFfFfF3", ' '), // '\n' + + // We replace control chars with the default replacement character of '?'. + Arguments.of("FfFfFfBf", '?') // (char)(' ' - 1) + ); + } + + @ParameterizedTest(name = "[{index}]") // don't include unprintable character in test display-name + @MethodSource("testDecode8859OnlyArguments") + public void testDecode8859Only(String hexString, char expected) throws Exception + { + ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(hexString)); + String decoded = decode(buffer, buffer.remaining()); + assertThat(decoded, equalTo("" + expected)); + } + + public static Stream testEncode8859OnlyArguments() + { + return Stream.of( + Arguments.of((char)128, (char)128), + Arguments.of((char)255, (char)255), + Arguments.of((char)0, null), + Arguments.of('\r', null), + Arguments.of('\n', null), + Arguments.of((char)456, null), + Arguments.of((char)256, null), + Arguments.of((char)-1, null), + Arguments.of((char)(' ' - 1), null) + ); + } + + @ParameterizedTest(name = "[{index}]") // don't include unprintable character in test display-name + @MethodSource("testEncode8859OnlyArguments") + public void testEncode8859Only(char value, Character expectedValue) throws Exception + { + String s = "value = '" + value + "'"; + + // If expected is null we should not be able to encode. + if (expectedValue == null) + { + assertThat(HuffmanEncoder.octetsNeeded(s), equalTo(-1)); + assertThrows(Throwable.class, () -> encode(s)); + return; + } + + String expected = "value = '" + expectedValue + "'"; + assertThat(HuffmanEncoder.octetsNeeded(s), greaterThan(0)); + ByteBuffer buffer = encode(s); + String decode = decode(buffer); + System.err.println("decoded: " + decode); + assertThat(decode, equalTo(expected)); + } + + private ByteBuffer encode(String s) + { + ByteBuffer buffer = BufferUtil.allocate(32); + BufferUtil.clearToFill(buffer); + HuffmanEncoder.encode(buffer, s); + BufferUtil.flipToFlush(buffer, 0); + return buffer; + } + + private String decode(ByteBuffer buffer) throws Exception + { + return decode(buffer, buffer.remaining()); + } +} diff -Nru jetty9-9.4.50/jetty-http/src/test/java/org/eclipse/jetty/http/NBitIntegerTest.java jetty9-9.4.57/jetty-http/src/test/java/org/eclipse/jetty/http/NBitIntegerTest.java --- jetty9-9.4.50/jetty-http/src/test/java/org/eclipse/jetty/http/NBitIntegerTest.java 1970-01-01 00:00:00.000000000 +0000 +++ jetty9-9.4.57/jetty-http/src/test/java/org/eclipse/jetty/http/NBitIntegerTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -0,0 +1,207 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http; + +import java.nio.ByteBuffer; + +import org.eclipse.jetty.http.compression.NBitIntegerDecoder; +import org.eclipse.jetty.http.compression.NBitIntegerEncoder; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.TypeUtil; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@SuppressWarnings("PointlessArithmeticExpression") +public class NBitIntegerTest +{ + private final NBitIntegerDecoder _decoder = new NBitIntegerDecoder(); + + @Test + public void testOctetsNeeded() + { + assertEquals(1, NBitIntegerEncoder.octetsNeeded(5, 10)); + assertEquals(3, NBitIntegerEncoder.octetsNeeded(5, 1337)); + assertEquals(1, NBitIntegerEncoder.octetsNeeded(8, 42)); + assertEquals(3, NBitIntegerEncoder.octetsNeeded(8, 1337)); + + assertEquals(1, NBitIntegerEncoder.octetsNeeded(6, 62)); + assertEquals(2, NBitIntegerEncoder.octetsNeeded(6, 63)); + assertEquals(2, NBitIntegerEncoder.octetsNeeded(6, 64)); + assertEquals(3, NBitIntegerEncoder.octetsNeeded(6, 63 + 0x00 + 0x80 * 0x01)); + assertEquals(4, NBitIntegerEncoder.octetsNeeded(6, 63 + 0x00 + 0x80 * 0x80)); + assertEquals(5, NBitIntegerEncoder.octetsNeeded(6, 63 + 0x00 + 0x80 * 0x80 * 0x80)); + } + + @Test + public void testEncode() + { + testEncode(6, 0, "00"); + testEncode(6, 1, "01"); + testEncode(6, 62, "3e"); + testEncode(6, 63, "3f00"); + testEncode(6, 63 + 1, "3f01"); + testEncode(6, 63 + 0x7e, "3f7e"); + testEncode(6, 63 + 0x7f, "3f7f"); + testEncode(6, 63 + 0x00 + 0x80 * 0x01, "3f8001"); + testEncode(6, 63 + 0x01 + 0x80 * 0x01, "3f8101"); + testEncode(6, 63 + 0x7f + 0x80 * 0x01, "3fFf01"); + testEncode(6, 63 + 0x00 + 0x80 * 0x02, "3f8002"); + testEncode(6, 63 + 0x01 + 0x80 * 0x02, "3f8102"); + testEncode(6, 63 + 0x7f + 0x80 * 0x7f, "3fFf7f"); + testEncode(6, 63 + 0x00 + 0x80 * 0x80, "3f808001"); + testEncode(6, 63 + 0x7f + 0x80 * 0x80 * 0x7f, "3fFf807f"); + testEncode(6, 63 + 0x00 + 0x80 * 0x80 * 0x80, "3f80808001"); + + testEncode(8, 0, "00"); + testEncode(8, 1, "01"); + testEncode(8, 128, "80"); + testEncode(8, 254, "Fe"); + testEncode(8, 255, "Ff00"); + testEncode(8, 255 + 1, "Ff01"); + testEncode(8, 255 + 0x7e, "Ff7e"); + testEncode(8, 255 + 0x7f, "Ff7f"); + testEncode(8, 255 + 0x80, "Ff8001"); + testEncode(8, 255 + 0x00 + 0x80 * 0x80, "Ff808001"); + } + + public void testEncode(int n, int i, String expected) + { + ByteBuffer buf = BufferUtil.allocate(16); + int p = BufferUtil.flipToFill(buf); + if (n < 8) + buf.put((byte)0x00); + NBitIntegerEncoder.encode(buf, n, i); + BufferUtil.flipToFlush(buf, p); + String r = TypeUtil.toHexString(BufferUtil.toArray(buf)); + assertEquals(expected, r); + + assertEquals(expected.length() / 2, NBitIntegerEncoder.octetsNeeded(n, i)); + } + + @Test + public void testDecode() + { + testDecode(6, 0, "00"); + testDecode(6, 1, "01"); + testDecode(6, 62, "3e"); + testDecode(6, 63, "3f00"); + testDecode(6, 63 + 1, "3f01"); + testDecode(6, 63 + 0x7e, "3f7e"); + testDecode(6, 63 + 0x7f, "3f7f"); + testDecode(6, 63 + 0x80, "3f8001"); + testDecode(6, 63 + 0x81, "3f8101"); + testDecode(6, 63 + 0x7f + 0x80 * 0x01, "3fFf01"); + testDecode(6, 63 + 0x00 + 0x80 * 0x02, "3f8002"); + testDecode(6, 63 + 0x01 + 0x80 * 0x02, "3f8102"); + testDecode(6, 63 + 0x7f + 0x80 * 0x7f, "3fFf7f"); + testDecode(6, 63 + 0x00 + 0x80 * 0x80, "3f808001"); + testDecode(6, 63 + 0x7f + 0x80 * 0x80 * 0x7f, "3fFf807f"); + testDecode(6, 63 + 0x00 + 0x80 * 0x80 * 0x80, "3f80808001"); + + testDecode(8, 0, "00"); + testDecode(8, 1, "01"); + testDecode(8, 128, "80"); + testDecode(8, 254, "Fe"); + testDecode(8, 255, "Ff00"); + testDecode(8, 255 + 1, "Ff01"); + testDecode(8, 255 + 0x7e, "Ff7e"); + testDecode(8, 255 + 0x7f, "Ff7f"); + testDecode(8, 255 + 0x80, "Ff8001"); + testDecode(8, 255 + 0x00 + 0x80 * 0x80, "Ff808001"); + } + + public void testDecode(int n, int expected, String encoded) + { + ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); + _decoder.setPrefix(n); + assertEquals(expected, _decoder.decodeInt(buf)); + } + + @Test + public void testEncodeExampleD11() + { + ByteBuffer buf = BufferUtil.allocate(16); + int p = BufferUtil.flipToFill(buf); + buf.put((byte)0x77); + buf.put((byte)0xFF); + NBitIntegerEncoder.encode(buf, 5, 10); + BufferUtil.flipToFlush(buf, p); + + String r = TypeUtil.toHexString(BufferUtil.toArray(buf)); + + assertEquals("77Ea", r); + } + + @Test + public void testDecodeExampleD11() + { + ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("77EaFF")); + buf.position(1); + _decoder.setPrefix(5); + assertEquals(10, _decoder.decodeInt(buf)); + } + + @Test + public void testEncodeExampleD12() + { + ByteBuffer buf = BufferUtil.allocate(16); + int p = BufferUtil.flipToFill(buf); + buf.put((byte)0x88); + buf.put((byte)0x00); + NBitIntegerEncoder.encode(buf, 5, 1337); + BufferUtil.flipToFlush(buf, p); + + String r = TypeUtil.toHexString(BufferUtil.toArray(buf)); + assertEquals("881f9a0a", r); + } + + @Test + public void testDecodeExampleD12() + { + ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("881f9a0aff")); + buf.position(1); + _decoder.setPrefix(5); + assertEquals(1337, _decoder.decodeInt(buf)); + } + + @Test + public void testEncodeExampleD13() + { + ByteBuffer buf = BufferUtil.allocate(16); + int p = BufferUtil.flipToFill(buf); + buf.put((byte)0x88); + buf.put((byte)0xFF); + NBitIntegerEncoder.encode(buf, 8, 42); + BufferUtil.flipToFlush(buf, p); + + String r = TypeUtil.toHexString(BufferUtil.toArray(buf)); + + assertEquals("88Ff2a", r); + } + + @Test + public void testDecodeExampleD13() + { + ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("882aFf")); + buf.position(1); + _decoder.setPrefix(8); + assertEquals(42, _decoder.decodeInt(buf)); + } +} diff -Nru jetty9-9.4.50/jetty-http-spi/pom.xml jetty9-9.4.57/jetty-http-spi/pom.xml --- jetty9-9.4.50/jetty-http-spi/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http-spi/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-http-spi @@ -63,27 +63,29 @@ + jdk9 [9,) - javax.xml - jaxws-api - 2.0EA3 + jakarta.xml.ws + jakarta.xml.ws-api + 2.3.3 test com.sun.xml.ws jaxws-rt - 2.3.3 + 2.3.7 test - javax.activation - javax.activation-api - 1.2.0 + jakarta.activation + jakarta.activation-api + 1.2.2 test diff -Nru jetty9-9.4.50/jetty-http2/http2-alpn-tests/pom.xml jetty9-9.4.57/jetty-http2/http2-alpn-tests/pom.xml --- jetty9-9.4.50/jetty-http2/http2-alpn-tests/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-alpn-tests/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-http2/http2-client/pom.xml jetty9-9.4.57/jetty-http2/http2-client/pom.xml --- jetty9-9.4.50/jetty-http2/http2-client/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-client/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 @@ -63,6 +63,11 @@ ${project.version} test + + org.awaitility + awaitility + test + diff -Nru jetty9-9.4.50/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java jetty9-9.4.57/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java --- jetty9-9.4.50/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java 2024-12-19 21:51:26.000000000 +0000 @@ -36,6 +36,7 @@ import org.eclipse.jetty.http2.api.Session; import org.eclipse.jetty.http2.frames.Frame; import org.eclipse.jetty.http2.frames.SettingsFrame; +import org.eclipse.jetty.http2.hpack.HpackContext; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.ClientConnectionFactory; import org.eclipse.jetty.io.Connection; @@ -125,6 +126,7 @@ private int selectors = 1; private long idleTimeout = 30000; private long connectTimeout = 10000; + private long streamIdleTimeout; private boolean connectBlocking; private SocketAddress bindAddress; private boolean tcpNoDelay = true; @@ -132,11 +134,13 @@ private List protocols = Arrays.asList("h2", "h2-17", "h2-16", "h2-15", "h2-14"); private int initialSessionRecvWindow = 16 * 1024 * 1024; private int initialStreamRecvWindow = 8 * 1024 * 1024; - private int maxFrameLength = Frame.DEFAULT_MAX_LENGTH; + private int maxFrameSize = Frame.DEFAULT_MAX_LENGTH; private int maxConcurrentPushedStreams = 32; private int maxSettingsKeys = SettingsFrame.DEFAULT_MAX_KEYS; - private int maxDynamicTableSize = 4096; + private int maxDecoderTableCapacity = HpackContext.DEFAULT_MAX_TABLE_CAPACITY; + private int maxEncoderTableCapacity = HpackContext.DEFAULT_MAX_TABLE_CAPACITY; private int maxHeaderBlockFragment = 0; + private int maxResponseHeadersSize = 8 * 1024; private FlowControlStrategy.Factory flowControlStrategyFactory = () -> new BufferingFlowControlStrategy(0.5F); @Override @@ -263,6 +267,17 @@ this.idleTimeout = idleTimeout; } + @ManagedAttribute("The stream idle timeout in milliseconds") + public long getStreamIdleTimeout() + { + return streamIdleTimeout; + } + + public void setStreamIdleTimeout(long streamIdleTimeout) + { + this.streamIdleTimeout = streamIdleTimeout; + } + @ManagedAttribute("The connect timeout in milliseconds") public long getConnectTimeout() { @@ -352,15 +367,28 @@ this.initialStreamRecvWindow = initialStreamRecvWindow; } + @Deprecated @ManagedAttribute("The max frame length in bytes") public int getMaxFrameLength() { - return maxFrameLength; + return getMaxFrameSize(); } + @Deprecated public void setMaxFrameLength(int maxFrameLength) { - this.maxFrameLength = maxFrameLength; + setMaxFrameSize(maxFrameLength); + } + + @ManagedAttribute("The max frame size in bytes") + public int getMaxFrameSize() + { + return maxFrameSize; + } + + public void setMaxFrameSize(int maxFrameSize) + { + this.maxFrameSize = maxFrameSize; } @ManagedAttribute("The max number of concurrent pushed streams") @@ -385,15 +413,45 @@ this.maxSettingsKeys = maxSettingsKeys; } + @ManagedAttribute("The HPACK encoder dynamic table maximum capacity") + public int getMaxEncoderTableCapacity() + { + return maxEncoderTableCapacity; + } + + /** + *

    Sets the limit for the encoder HPACK dynamic table capacity.

    + *

    Setting this value to {@code 0} disables the use of the dynamic table.

    + * + * @param maxEncoderTableCapacity The HPACK encoder dynamic table maximum capacity + */ + public void setMaxEncoderTableCapacity(int maxEncoderTableCapacity) + { + this.maxEncoderTableCapacity = maxEncoderTableCapacity; + } + + @ManagedAttribute("The HPACK decoder dynamic table maximum capacity") + public int getMaxDecoderTableCapacity() + { + return maxDecoderTableCapacity; + } + + public void setMaxDecoderTableCapacity(int maxDecoderTableCapacity) + { + this.maxDecoderTableCapacity = maxDecoderTableCapacity; + } + + @Deprecated @ManagedAttribute("The HPACK dynamic table maximum size") public int getMaxDynamicTableSize() { - return maxDynamicTableSize; + return getMaxDecoderTableCapacity(); } + @Deprecated public void setMaxDynamicTableSize(int maxDynamicTableSize) { - this.maxDynamicTableSize = maxDynamicTableSize; + setMaxDecoderTableCapacity(maxDynamicTableSize); } @ManagedAttribute("The max size of header block fragments") @@ -407,6 +465,17 @@ this.maxHeaderBlockFragment = maxHeaderBlockFragment; } + @ManagedAttribute("The max size of response headers") + public int getMaxResponseHeadersSize() + { + return maxResponseHeadersSize; + } + + public void setMaxResponseHeadersSize(int maxResponseHeadersSize) + { + this.maxResponseHeadersSize = maxResponseHeadersSize; + } + public void connect(InetSocketAddress address, Session.Listener listener, Promise promise) { connect(null, address, listener, promise); diff -Nru jetty9-9.4.50/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java jetty9-9.4.57/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java --- jetty9-9.4.50/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java 2024-12-19 21:51:26.000000000 +0000 @@ -27,10 +27,12 @@ import org.eclipse.jetty.http2.HTTP2Connection; import org.eclipse.jetty.http2.ISession; import org.eclipse.jetty.http2.api.Session; +import org.eclipse.jetty.http2.frames.Frame; import org.eclipse.jetty.http2.frames.PrefaceFrame; import org.eclipse.jetty.http2.frames.SettingsFrame; import org.eclipse.jetty.http2.frames.WindowUpdateFrame; import org.eclipse.jetty.http2.generator.Generator; +import org.eclipse.jetty.http2.hpack.HpackContext; import org.eclipse.jetty.http2.parser.Parser; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.ClientConnectionFactory; @@ -56,25 +58,32 @@ public Connection newConnection(EndPoint endPoint, Map context) { HTTP2Client client = (HTTP2Client)context.get(CLIENT_CONTEXT_KEY); - ByteBufferPool byteBufferPool = (ByteBufferPool)context.get(BYTE_BUFFER_POOL_CONTEXT_KEY); - Executor executor = (Executor)context.get(EXECUTOR_CONTEXT_KEY); - Scheduler scheduler = (Scheduler)context.get(SCHEDULER_CONTEXT_KEY); + ByteBufferPool byteBufferPool = client.getByteBufferPool(); + Executor executor = client.getExecutor(); + Scheduler scheduler = client.getScheduler(); Session.Listener listener = (Session.Listener)context.get(SESSION_LISTENER_CONTEXT_KEY); @SuppressWarnings("unchecked") - Promise promise = (Promise)context.get(SESSION_PROMISE_CONTEXT_KEY); + Promise sessionPromise = (Promise)context.get(SESSION_PROMISE_CONTEXT_KEY); - Generator generator = new Generator(byteBufferPool, client.getMaxDynamicTableSize(), client.getMaxHeaderBlockFragment()); + Generator generator = new Generator(byteBufferPool, client.getMaxHeaderBlockFragment()); FlowControlStrategy flowControl = client.getFlowControlStrategyFactory().newFlowControlStrategy(); - HTTP2ClientSession session = new HTTP2ClientSession(scheduler, endPoint, generator, listener, flowControl); - session.setMaxRemoteStreams(client.getMaxConcurrentPushedStreams()); - Parser parser = new Parser(byteBufferPool, session, 4096, 8192); - parser.setMaxFrameLength(client.getMaxFrameLength()); + Parser parser = new Parser(byteBufferPool, client.getMaxResponseHeadersSize()); + parser.setMaxFrameSize(client.getMaxFrameSize()); parser.setMaxSettingsKeys(client.getMaxSettingsKeys()); + HTTP2ClientSession session = new HTTP2ClientSession(scheduler, endPoint, parser, generator, listener, flowControl); + session.setMaxRemoteStreams(client.getMaxConcurrentPushedStreams()); + session.setMaxEncoderTableCapacity(client.getMaxEncoderTableCapacity()); + long streamIdleTimeout = client.getStreamIdleTimeout(); + if (streamIdleTimeout > 0) + session.setStreamIdleTimeout(streamIdleTimeout); + HTTP2ClientConnection connection = new HTTP2ClientConnection(client, byteBufferPool, executor, endPoint, - parser, session, client.getInputBufferSize(), promise, listener); + session, client.getInputBufferSize(), sessionPromise, listener); connection.addListener(connectionListener); + parser.init(connection.wrapParserListener(session)); + return customize(connection, context); } @@ -84,9 +93,9 @@ private final Promise promise; private final Session.Listener listener; - private HTTP2ClientConnection(HTTP2Client client, ByteBufferPool byteBufferPool, Executor executor, EndPoint endpoint, Parser parser, ISession session, int bufferSize, Promise promise, Session.Listener listener) + private HTTP2ClientConnection(HTTP2Client client, ByteBufferPool byteBufferPool, Executor executor, EndPoint endpoint, ISession session, int bufferSize, Promise promise, Session.Listener listener) { - super(byteBufferPool, executor, endpoint, parser, session, bufferSize); + super(byteBufferPool, executor, endpoint, session, bufferSize); this.client = client; this.promise = promise; this.listener = listener; @@ -98,12 +107,52 @@ Map settings = listener.onPreface(getSession()); if (settings == null) settings = new HashMap<>(); - settings.computeIfAbsent(SettingsFrame.INITIAL_WINDOW_SIZE, k -> client.getInitialStreamRecvWindow()); - settings.computeIfAbsent(SettingsFrame.MAX_CONCURRENT_STREAMS, k -> client.getMaxConcurrentPushedStreams()); - Integer maxFrameLength = settings.get(SettingsFrame.MAX_FRAME_SIZE); - if (maxFrameLength != null) - getParser().setMaxFrameLength(maxFrameLength); + // Below we want to populate any settings to send to the server + // that have a different default than what prescribed by the RFC. + // Changing the configuration is done when the SETTINGS is sent. + + settings.compute(SettingsFrame.HEADER_TABLE_SIZE, (k, v) -> + { + if (v == null) + { + v = client.getMaxDecoderTableCapacity(); + if (v == HpackContext.DEFAULT_MAX_TABLE_CAPACITY) + v = null; + } + return v; + }); + settings.computeIfAbsent(SettingsFrame.MAX_CONCURRENT_STREAMS, k -> client.getMaxConcurrentPushedStreams()); + settings.compute(SettingsFrame.INITIAL_WINDOW_SIZE, (k, v) -> + { + if (v == null) + { + v = client.getInitialStreamRecvWindow(); + if (v == FlowControlStrategy.DEFAULT_WINDOW_SIZE) + v = null; + } + return v; + }); + settings.compute(SettingsFrame.MAX_FRAME_SIZE, (k, v) -> + { + if (v == null) + { + v = client.getMaxFrameSize(); + if (v == Frame.DEFAULT_MAX_LENGTH) + v = null; + } + return v; + }); + settings.compute(SettingsFrame.MAX_HEADER_LIST_SIZE, (k, v) -> + { + if (v == null) + { + v = client.getMaxResponseHeadersSize(); + if (v <= 0) + v = null; + } + return v; + }); PrefaceFrame prefaceFrame = new PrefaceFrame(); SettingsFrame settingsFrame = new SettingsFrame(settings, false); diff -Nru jetty9-9.4.50/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientSession.java jetty9-9.4.57/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientSession.java --- jetty9-9.4.50/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientSession.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientSession.java 2024-12-19 21:51:26.000000000 +0000 @@ -29,6 +29,7 @@ import org.eclipse.jetty.http2.frames.HeadersFrame; import org.eclipse.jetty.http2.frames.PushPromiseFrame; import org.eclipse.jetty.http2.generator.Generator; +import org.eclipse.jetty.http2.parser.Parser; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.log.Log; @@ -39,9 +40,16 @@ { private static final Logger LOG = Log.getLogger(HTTP2ClientSession.class); + @Deprecated public HTTP2ClientSession(Scheduler scheduler, EndPoint endPoint, Generator generator, Session.Listener listener, FlowControlStrategy flowControl) { - super(scheduler, endPoint, generator, listener, flowControl, 1); + this(scheduler, endPoint, null, generator, listener, flowControl); + throw new UnsupportedOperationException(); + } + + public HTTP2ClientSession(Scheduler scheduler, EndPoint endPoint, Parser parser, Generator generator, Session.Listener listener, FlowControlStrategy flowControl) + { + super(scheduler, endPoint, parser, generator, listener, flowControl, 1); } @Override @@ -63,9 +71,10 @@ else { stream.process(frame, Callback.NOOP); - if (stream.updateClose(frame.isEndStream(), CloseState.Event.RECEIVED)) - removeStream(stream); + boolean closed = stream.updateClose(frame.isEndStream(), CloseState.Event.RECEIVED); notifyHeaders(stream, frame); + if (closed) + removeStream(stream); } } else diff -Nru jetty9-9.4.50/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/DynamicTableTest.java jetty9-9.4.57/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/DynamicTableTest.java --- jetty9-9.4.50/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/DynamicTableTest.java 1970-01-01 00:00:00.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/DynamicTableTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -0,0 +1,190 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// 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.http2.client; + +import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.MetaData; +import org.eclipse.jetty.http2.api.Session; +import org.eclipse.jetty.http2.api.Stream; +import org.eclipse.jetty.http2.frames.HeadersFrame; +import org.eclipse.jetty.http2.frames.SettingsFrame; +import org.eclipse.jetty.http2.server.AbstractHTTP2ServerConnectionFactory; +import org.eclipse.jetty.util.Promise; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class DynamicTableTest extends AbstractTest +{ + @ParameterizedTest + @CsvSource({"0,-1", "-1,0", "0,0"}) + public void testMaxEncoderTableCapacityZero(int clientMaxCapacity, int serverMaxCapacity) throws Exception + { + start(new HttpServlet() + { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException + { + resp.setStatus(200); + resp.getOutputStream().close(); + } + }); + + if (clientMaxCapacity >= 0) + client.setMaxEncoderTableCapacity(clientMaxCapacity); + if (serverMaxCapacity >= 0) + connector.getConnectionFactory(AbstractHTTP2ServerConnectionFactory.class).setMaxEncoderTableCapacity(serverMaxCapacity); + + CountDownLatch serverPreface = new CountDownLatch(1); + Session session = newClient(new Session.Listener.Adapter() + { + @Override + public void onSettings(Session session, SettingsFrame frame) + { + serverPreface.countDown(); + } + }); + assertTrue(serverPreface.await(5, TimeUnit.SECONDS)); + + MetaData.Request metaData = newRequest("GET", new HttpFields()); + HeadersFrame frame = new HeadersFrame(metaData, null, true); + CountDownLatch latch = new CountDownLatch(1); + session.newStream(frame, new Promise.Adapter<>(), new Stream.Listener.Adapter() + { + @Override + public void onHeaders(Stream stream, HeadersFrame frame) + { + MetaData.Response response = (MetaData.Response)frame.getMetaData(); + assertEquals(200, response.getStatus()); + latch.countDown(); + } + }); + + assertTrue(latch.await(5, TimeUnit.SECONDS)); + } + + @ParameterizedTest + @CsvSource({"0,-1", "-1,0", "0,0"}) + public void testMaxDecoderTableCapacityZero(int clientMaxCapacity, int serverMaxCapacity) throws Exception + { + start(new HttpServlet() + { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException + { + resp.setStatus(200); + resp.getOutputStream().close(); + } + }); + + if (clientMaxCapacity >= 0) + client.setMaxDecoderTableCapacity(clientMaxCapacity); + if (serverMaxCapacity >= 0) + connector.getConnectionFactory(AbstractHTTP2ServerConnectionFactory.class).setMaxDecoderTableCapacity(serverMaxCapacity); + + CountDownLatch serverPreface = new CountDownLatch(1); + Session session = newClient(new Session.Listener.Adapter() + { + @Override + public void onSettings(Session session, SettingsFrame frame) + { + serverPreface.countDown(); + } + }); + assertTrue(serverPreface.await(5, TimeUnit.SECONDS)); + + MetaData.Request metaData = newRequest("GET", new HttpFields()); + HeadersFrame frame = new HeadersFrame(metaData, null, true); + CountDownLatch latch = new CountDownLatch(1); + session.newStream(frame, new Promise.Adapter<>(), new Stream.Listener.Adapter() + { + @Override + public void onHeaders(Stream stream, HeadersFrame frame) + { + MetaData.Response response = (MetaData.Response)frame.getMetaData(); + assertEquals(200, response.getStatus()); + latch.countDown(); + } + }); + + assertTrue(latch.await(5, TimeUnit.SECONDS)); + } + + @ParameterizedTest + @CsvSource({"0,-1", "-1,0", "0,0"}) + public void testMaxTableCapacityZero(int clientMaxCapacity, int serverMaxCapacity) throws Exception + { + start(new HttpServlet() + { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException + { + resp.setStatus(200); + resp.getOutputStream().close(); + } + }); + + if (clientMaxCapacity >= 0) + { + client.setMaxDecoderTableCapacity(clientMaxCapacity); + client.setMaxEncoderTableCapacity(clientMaxCapacity); + } + if (serverMaxCapacity >= 0) + { + connector.getConnectionFactory(AbstractHTTP2ServerConnectionFactory.class).setMaxEncoderTableCapacity(serverMaxCapacity); + connector.getConnectionFactory(AbstractHTTP2ServerConnectionFactory.class).setMaxDecoderTableCapacity(serverMaxCapacity); + } + + CountDownLatch serverPreface = new CountDownLatch(1); + Session session = newClient(new Session.Listener.Adapter() + { + @Override + public void onSettings(Session session, SettingsFrame frame) + { + serverPreface.countDown(); + } + }); + assertTrue(serverPreface.await(5, TimeUnit.SECONDS)); + + MetaData.Request metaData = newRequest("GET", new HttpFields()); + HeadersFrame frame = new HeadersFrame(metaData, null, true); + CountDownLatch latch = new CountDownLatch(1); + session.newStream(frame, new Promise.Adapter<>(), new Stream.Listener.Adapter() + { + @Override + public void onHeaders(Stream stream, HeadersFrame frame) + { + MetaData.Response response = (MetaData.Response)frame.getMetaData(); + assertEquals(200, response.getStatus()); + latch.countDown(); + } + }); + + assertTrue(latch.await(5, TimeUnit.SECONDS)); + } +} diff -Nru jetty9-9.4.50/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/HTTP2Test.java jetty9-9.4.57/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/HTTP2Test.java --- jetty9-9.4.50/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/HTTP2Test.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/HTTP2Test.java 2024-12-19 21:51:26.000000000 +0000 @@ -22,9 +22,11 @@ import java.nio.ByteBuffer; import java.nio.channels.WritePendingException; import java.nio.charset.StandardCharsets; +import java.time.Duration; import java.util.HashMap; import java.util.Map; import java.util.Random; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -39,6 +41,7 @@ import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http2.ErrorCode; +import org.eclipse.jetty.http2.HTTP2Session; import org.eclipse.jetty.http2.api.Session; import org.eclipse.jetty.http2.api.Stream; import org.eclipse.jetty.http2.api.server.ServerSessionListener; @@ -48,10 +51,7 @@ import org.eclipse.jetty.http2.frames.ResetFrame; import org.eclipse.jetty.http2.frames.SettingsFrame; import org.eclipse.jetty.http2.hpack.HpackException; -import org.eclipse.jetty.http2.parser.RateControl; -import org.eclipse.jetty.http2.parser.ServerParser; import org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory; -import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; @@ -59,13 +59,19 @@ import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.Jetty; import org.eclipse.jetty.util.Promise; +import org.eclipse.jetty.util.StringUtil; import org.junit.jupiter.api.Test; +import static org.awaitility.Awaitility.await; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -511,7 +517,8 @@ } }); assertTrue(exchangeLatch4.await(5, TimeUnit.SECONDS)); - assertEquals(1, session.getStreams().size()); + // The stream is removed from the session just after returning from onHeaders(), so wait a little bit. + await().atMost(Duration.ofSeconds(1)).until(() -> session.getStreams().size(), is(1)); // End the first stream. stream1.data(new DataFrame(stream1.getId(), BufferUtil.EMPTY_BUFFER, true), new Callback() @@ -738,6 +745,7 @@ @Test public void testGoAwayRespondedWithGoAway() throws Exception { + CountDownLatch goAwayLatch = new CountDownLatch(1); ServerSessionListener.Adapter serverListener = new ServerSessionListener.Adapter() { @Override @@ -749,24 +757,15 @@ stream.getSession().close(ErrorCode.NO_ERROR.code, null, Callback.NOOP); return null; } - }; - CountDownLatch goAwayLatch = new CountDownLatch(1); - RawHTTP2ServerConnectionFactory connectionFactory = new RawHTTP2ServerConnectionFactory(new HttpConfiguration(), serverListener) - { + @Override - protected ServerParser newServerParser(Connector connector, ServerParser.Listener listener, RateControl rateControl) + public void onGoAway(Session session, GoAwayFrame frame) { - return super.newServerParser(connector, new ServerParser.Listener.Wrapper(listener) - { - @Override - public void onGoAway(GoAwayFrame frame) - { - super.onGoAway(frame); - goAwayLatch.countDown(); - } - }, rateControl); + goAwayLatch.countDown(); } }; + + RawHTTP2ServerConnectionFactory connectionFactory = new RawHTTP2ServerConnectionFactory(new HttpConfiguration(), serverListener); prepareServer(connectionFactory); server.start(); @@ -893,6 +892,150 @@ assertTrue(resetLatch.await(5, TimeUnit.SECONDS)); } + @Test + public void testClientSendsLargeHeader() throws Exception + { + CountDownLatch settingsLatch = new CountDownLatch(2); + + CompletableFuture serverFailureFuture = new CompletableFuture<>(); + CompletableFuture serverCloseReasonFuture = new CompletableFuture<>(); + start(new ServerSessionListener.Adapter() + { + @Override + public void onSettings(Session session, SettingsFrame frame) + { + settingsLatch.countDown(); + } + + @Override + public void onFailure(Session session, Throwable failure) + { + serverFailureFuture.complete(failure); + } + + @Override + public void onClose(Session session, GoAwayFrame frame) + { + serverCloseReasonFuture.complete(frame.tryConvertPayload()); + } + }); + + CompletableFuture clientFailureFuture = new CompletableFuture<>(); + CompletableFuture clientCloseReasonFuture = new CompletableFuture<>(); + Session.Listener.Adapter listener = new Session.Listener.Adapter() + { + @Override + public void onSettings(Session session, SettingsFrame frame) + { + settingsLatch.countDown(); + } + + @Override + public void onFailure(Session session, Throwable failure) + { + clientFailureFuture.complete(failure); + } + + @Override + public void onClose(Session session, GoAwayFrame frame) + { + clientCloseReasonFuture.complete(frame.tryConvertPayload()); + } + }; + + HTTP2Session session = (HTTP2Session)newClient(listener); + assertTrue(settingsLatch.await(5, TimeUnit.SECONDS)); + session.getGenerator().getHpackEncoder().setMaxHeaderListSize(1024 * 1024); + + String value = StringUtil.stringFrom("x", 8 * 1024); + HttpFields requestFields = new HttpFields(); + requestFields.put("custom", value); + MetaData.Request metaData = newRequest("GET", requestFields); + HeadersFrame request = new HeadersFrame(metaData, null, true); + session.newStream(request, new FuturePromise<>(), new Stream.Listener.Adapter()); + + // Test failure and close reason on client. + String closeReason = clientCloseReasonFuture.get(5, TimeUnit.SECONDS); + assertThat(closeReason, equalTo("invalid_hpack_block")); + assertNull(clientFailureFuture.getNow(null)); + + // Test failure and close reason on server. + closeReason = serverCloseReasonFuture.get(5, TimeUnit.SECONDS); + assertThat(closeReason, equalTo("invalid_hpack_block")); + Throwable failure = serverFailureFuture.get(5, TimeUnit.SECONDS); + assertThat(failure, instanceOf(IOException.class)); + assertThat(failure.getMessage(), containsString("invalid_hpack_block")); + } + + @Test + public void testServerSendsLargeHeader() throws Exception + { + CompletableFuture serverFailureFuture = new CompletableFuture<>(); + CompletableFuture serverCloseReasonFuture = new CompletableFuture<>(); + start(new ServerSessionListener.Adapter() + { + @Override + public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) + { + HTTP2Session session = (HTTP2Session)stream.getSession(); + session.getGenerator().getHpackEncoder().setMaxHeaderListSize(1024 * 1024); + + String value = StringUtil.stringFrom("x", 8 * 1024); + HttpFields fields = new HttpFields(); + fields.put("custom", value); + MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, fields); + stream.headers(new HeadersFrame(stream.getId(), response, null, true), Callback.NOOP); + return null; + } + + @Override + public void onFailure(Session session, Throwable failure) + { + serverFailureFuture.complete(failure); + } + + @Override + public void onClose(Session session, GoAwayFrame frame) + { + serverCloseReasonFuture.complete(frame.tryConvertPayload()); + } + }); + + CompletableFuture clientFailureFuture = new CompletableFuture<>(); + CompletableFuture clientCloseReasonFuture = new CompletableFuture<>(); + Session.Listener.Adapter listener = new Session.Listener.Adapter() + { + @Override + public void onFailure(Session session, Throwable failure) + { + clientFailureFuture.complete(failure); + } + + @Override + public void onClose(Session session, GoAwayFrame frame) + { + clientCloseReasonFuture.complete(frame.tryConvertPayload()); + } + }; + + Session session = newClient(listener); + MetaData.Request metaData = newRequest("GET", new HttpFields()); + HeadersFrame request = new HeadersFrame(metaData, null, true); + session.newStream(request, new FuturePromise<>(), new Stream.Listener.Adapter()); + + // Test failure and close reason on server. + String closeReason = serverCloseReasonFuture.get(5, TimeUnit.SECONDS); + assertThat(closeReason, equalTo("invalid_hpack_block")); + assertNull(serverFailureFuture.getNow(null)); + + // Test failure and close reason on client. + closeReason = clientCloseReasonFuture.get(5, TimeUnit.SECONDS); + assertThat(closeReason, equalTo("invalid_hpack_block")); + Throwable failure = clientFailureFuture.get(5, TimeUnit.SECONDS); + assertThat(failure, instanceOf(IOException.class)); + assertThat(failure.getMessage(), containsString("invalid_hpack_block")); + } + private static void sleep(long time) { try diff -Nru jetty9-9.4.50/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/IdleTimeoutTest.java jetty9-9.4.57/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/IdleTimeoutTest.java --- jetty9-9.4.50/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/IdleTimeoutTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/IdleTimeoutTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -19,7 +19,11 @@ package org.eclipse.jetty.http2.client; import java.io.IOException; +import java.net.InetSocketAddress; import java.nio.ByteBuffer; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; +import java.time.Duration; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -43,7 +47,10 @@ import org.eclipse.jetty.http2.frames.GoAwayFrame; import org.eclipse.jetty.http2.frames.HeadersFrame; import org.eclipse.jetty.http2.frames.ResetFrame; +import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory; import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory; +import org.eclipse.jetty.io.ManagedSelector; +import org.eclipse.jetty.io.SocketChannelEndPoint; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; @@ -57,7 +64,9 @@ import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; +import static org.awaitility.Awaitility.await; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -681,6 +690,53 @@ assertThat(((ISession)client).updateSendWindow(0), Matchers.greaterThan(0)); } + @Test + public void testIdleTimeoutWhenCongested() throws Exception + { + long idleTimeout = 1000; + HTTP2CServerConnectionFactory h2c = new HTTP2CServerConnectionFactory(new HttpConfiguration()); + prepareServer(h2c); + server.removeConnector(connector); + connector = new ServerConnector(server, 1, 1, h2c) + { + @Override + protected SocketChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) + { + SocketChannelEndPoint endpoint = new SocketChannelEndPoint(channel, selectSet, key, getScheduler()) + { + @Override + public boolean flush(ByteBuffer... buffers) + { + // Fake TCP congestion. + return false; + } + + @Override + protected void onIncompleteFlush() + { + // Do nothing here to avoid spin loop, + // since the network is actually writable, + // as we are only faking TCP congestion. + } + }; + endpoint.setIdleTimeout(getIdleTimeout()); + return endpoint; + } + }; + connector.setIdleTimeout(idleTimeout); + server.addConnector(connector); + server.start(); + + prepareClient(); + client.start(); + + InetSocketAddress address = new InetSocketAddress("localhost", connector.getLocalPort()); + // The connect() will complete exceptionally. + client.connect(address, new Session.Listener.Adapter(), new Promise.Completable<>()); + + await().atMost(Duration.ofMillis(5 * idleTimeout)).until(() -> connector.getConnectedEndPoints().size(), is(0)); + } + private void sleep(long value) { try diff -Nru jetty9-9.4.50/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PrefaceTest.java jetty9-9.4.57/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PrefaceTest.java --- jetty9-9.4.50/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PrefaceTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PrefaceTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -35,7 +35,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.UnaryOperator; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpStatus; @@ -169,15 +168,15 @@ socket.write(buffers.toArray(new ByteBuffer[buffers.size()])); Queue settings = new ArrayDeque<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onSettings(SettingsFrame frame) { settings.offer(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); ByteBuffer buffer = byteBufferPool.acquire(1024, true); while (true) @@ -302,7 +301,8 @@ CountDownLatch clientSettingsLatch = new CountDownLatch(1); AtomicBoolean responded = new AtomicBoolean(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onSettings(SettingsFrame frame) @@ -319,8 +319,7 @@ if (frame.isEndStream()) responded.set(true); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); // HTTP/2 parsing. while (true) diff -Nru jetty9-9.4.50/jetty-http2/http2-common/pom.xml jetty9-9.4.57/jetty-http2/http2-common/pom.xml --- jetty9-9.4.50/jetty-http2/http2-common/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Connection.java jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Connection.java --- jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Connection.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Connection.java 2024-12-19 21:51:26.000000000 +0000 @@ -27,6 +27,7 @@ import org.eclipse.jetty.http2.frames.DataFrame; import org.eclipse.jetty.http2.parser.Parser; +import org.eclipse.jetty.http2.parser.ServerParser; import org.eclipse.jetty.io.AbstractConnection; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.EndPoint; @@ -52,23 +53,26 @@ private final HTTP2Producer producer = new HTTP2Producer(); private final AtomicLong bytesIn = new AtomicLong(); private final ByteBufferPool byteBufferPool; - private final Parser parser; private final ISession session; private final int bufferSize; private final ExecutionStrategy strategy; + @Deprecated public HTTP2Connection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, Parser parser, ISession session, int bufferSize) { + this(byteBufferPool, executor, endPoint, session, bufferSize); + } + + public HTTP2Connection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, ISession session, int bufferSize) + { super(endPoint, executor); this.byteBufferPool = byteBufferPool; - this.parser = parser; this.session = session; this.bufferSize = bufferSize; if (PEC_MODE) executor = new TryExecutor.NoTryExecutor(executor); this.strategy = new EatWhatYouKill(producer, executor); LifeCycle.start(strategy); - parser.init(ParserListener::new); } @Override @@ -104,7 +108,8 @@ protected Parser getParser() { - return parser; + // TODO: can we downcast. + return ((HTTP2Session)session).getParser(); } protected void setInputBuffer(ByteBuffer buffer) @@ -112,6 +117,11 @@ producer.setInputBuffer(buffer); } + public Parser.Listener wrapParserListener(Parser.Listener listener) + { + return new ParserListener(listener); + } + @Override public void onOpen() { @@ -258,7 +268,7 @@ { while (networkBuffer.hasRemaining()) { - parser.parse(networkBuffer.getBuffer()); + getParser().parse(networkBuffer.getBuffer()); if (failed) return null; } @@ -378,7 +388,7 @@ { private ParserListener(Parser.Listener listener) { - super(listener); + super(listener == null ? new ServerParser.Listener.Adapter() : listener); } @Override diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java --- jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java 2024-12-19 21:51:26.000000000 +0000 @@ -55,6 +55,7 @@ import org.eclipse.jetty.http2.frames.StreamFrame; import org.eclipse.jetty.http2.frames.WindowUpdateFrame; import org.eclipse.jetty.http2.generator.Generator; +import org.eclipse.jetty.http2.hpack.HpackEncoder; import org.eclipse.jetty.http2.hpack.HpackException; import org.eclipse.jetty.http2.parser.Parser; import org.eclipse.jetty.io.ByteBufferPool; @@ -94,6 +95,7 @@ private final AtomicLong bytesWritten = new AtomicLong(); private final Scheduler scheduler; private final EndPoint endPoint; + private final Parser parser; private final Generator generator; private final Session.Listener listener; private final FlowControlStrategy flowControl; @@ -103,12 +105,21 @@ private long streamIdleTimeout; private int initialSessionRecvWindow; private int writeThreshold; + private int maxEncoderTableCapacity; private boolean pushEnabled; + @Deprecated public HTTP2Session(Scheduler scheduler, EndPoint endPoint, Generator generator, Session.Listener listener, FlowControlStrategy flowControl, int initialStreamId) { + this(scheduler, endPoint, null, generator, listener, flowControl, initialStreamId); + throw new UnsupportedOperationException(); + } + + public HTTP2Session(Scheduler scheduler, EndPoint endPoint, Parser parser, Generator generator, Session.Listener listener, FlowControlStrategy flowControl, int initialStreamId) + { this.scheduler = scheduler; this.endPoint = endPoint; + this.parser = parser; this.generator = generator; this.listener = listener; this.flowControl = flowControl; @@ -205,11 +216,27 @@ this.writeThreshold = writeThreshold; } + @ManagedAttribute("The HPACK encoder dynamic table maximum capacity") + public int getMaxEncoderTableCapacity() + { + return maxEncoderTableCapacity; + } + + public void setMaxEncoderTableCapacity(int maxEncoderTableCapacity) + { + this.maxEncoderTableCapacity = maxEncoderTableCapacity; + } + public EndPoint getEndPoint() { return endPoint; } + public Parser getParser() + { + return parser; + } + public Generator getGenerator() { return generator; @@ -346,8 +373,20 @@ if (frame.isReply()) return; - // Iterate over all settings - for (Map.Entry entry : frame.getSettings().entrySet()) + Map settings = frame.getSettings(); + configure(settings, false); + notifySettings(this, frame); + + if (reply) + { + SettingsFrame replyFrame = new SettingsFrame(Collections.emptyMap(), true); + settings(replyFrame, Callback.NOOP); + } + } + + private void configure(Map settings, boolean local) + { + for (Map.Entry entry : settings.entrySet()) { int key = entry.getKey(); int value = entry.getValue(); @@ -356,8 +395,17 @@ case SettingsFrame.HEADER_TABLE_SIZE: { if (LOG.isDebugEnabled()) - LOG.debug("Updating HPACK header table size to {} for {}", value, this); - generator.setHeaderTableSize(value); + LOG.debug("Updating HPACK {} max table capacity to {} for {}", local ? "decoder" : "encoder", value, this); + if (local) + { + parser.getHpackDecoder().setMaxTableCapacity(value); + } + else + { + HpackEncoder hpackEncoder = generator.getHpackEncoder(); + hpackEncoder.setMaxTableCapacity(value); + hpackEncoder.setTableCapacity(Math.min(value, getMaxEncoderTableCapacity())); + } break; } case SettingsFrame.ENABLE_PUSH: @@ -371,29 +419,38 @@ case SettingsFrame.MAX_CONCURRENT_STREAMS: { if (LOG.isDebugEnabled()) - LOG.debug("Updating max local concurrent streams to {} for {}", value, this); - maxLocalStreams = value; + LOG.debug("Updating max {} concurrent streams to {} for {}", local ? "remote" : "local", value, this); + if (local) + maxRemoteStreams = value; + else + maxLocalStreams = value; break; } case SettingsFrame.INITIAL_WINDOW_SIZE: { if (LOG.isDebugEnabled()) LOG.debug("Updating initial stream window size to {} for {}", value, this); - flowControl.updateInitialStreamWindow(this, value, false); + flowControl.updateInitialStreamWindow(this, value, local); break; } case SettingsFrame.MAX_FRAME_SIZE: { if (LOG.isDebugEnabled()) - LOG.debug("Updating max frame size to {} for {}", value, this); - generator.setMaxFrameSize(value); + LOG.debug("Updating {} max frame size to {} for {}", local ? "parser" : "generator", value, this); + if (local) + parser.setMaxFrameSize(value); + else + generator.setMaxFrameSize(value); break; } case SettingsFrame.MAX_HEADER_LIST_SIZE: { if (LOG.isDebugEnabled()) - LOG.debug("Updating max header list size to {} for {}", value, this); - generator.setMaxHeaderListSize(value); + LOG.debug("Updating {} max header list size to {} for {}", local ? "decoder" : "encoder", value, this); + if (local) + parser.getHpackDecoder().setMaxHeaderListSize(value); + else + generator.getHpackEncoder().setMaxHeaderListSize(value); break; } default: @@ -404,13 +461,6 @@ } } } - notifySettings(this, frame); - - if (reply) - { - SettingsFrame replyFrame = new SettingsFrame(Collections.emptyMap(), true); - settings(replyFrame, Callback.NOOP); - } } @Override @@ -487,6 +537,21 @@ } @Override + public void onWindowUpdate(IStream stream, WindowUpdateFrame frame) + { + // WindowUpdateFrames arrive concurrently with writes. + // Increasing (or reducing) the window size concurrently + // with writes requires coordination with the flusher, that + // decides how many frames to write depending on the available + // window sizes. If the window sizes vary concurrently, the + // flusher may take non-optimal or wrong decisions. + // Here, we "queue" window updates to the flusher, so it will + // be the only component responsible for window updates, for + // both increments and reductions. + flusher.window(stream, frame); + } + + @Override public void onStreamFailure(int streamId, int error, String reason) { Callback callback = Callback.from(() -> reset(getStream(streamId), new ResetFrame(streamId, error), Callback.NOOP)); @@ -889,21 +954,6 @@ } @Override - public void onWindowUpdate(IStream stream, WindowUpdateFrame frame) - { - // WindowUpdateFrames arrive concurrently with writes. - // Increasing (or reducing) the window size concurrently - // with writes requires coordination with the flusher, that - // decides how many frames to write depending on the available - // window sizes. If the window sizes vary concurrently, the - // flusher may take non-optimal or wrong decisions. - // Here, we "queue" window updates to the flusher, so it will - // be the only component responsible for window updates, for - // both increments and reductions. - flusher.window(stream, frame); - } - - @Override @ManagedAttribute(value = "Whether HTTP/2 push is enabled", readonly = true) public boolean isPushEnabled() { @@ -1005,7 +1055,7 @@ return lastRemoteStreamId.get(); } - private void updateLastRemoteStreamId(int streamId) + protected void updateLastRemoteStreamId(int streamId) { Atomics.updateMax(lastRemoteStreamId, streamId); } @@ -1208,9 +1258,8 @@ case SETTINGS: { SettingsFrame settingsFrame = (SettingsFrame)frame; - Integer initialWindow = settingsFrame.getSettings().get(SettingsFrame.INITIAL_WINDOW_SIZE); - if (initialWindow != null) - flowControl.updateInitialStreamWindow(HTTP2Session.this, initialWindow, true); + if (!settingsFrame.isReply()) + configure(settingsFrame.getSettings(), true); break; } default: @@ -1407,6 +1456,8 @@ @Override public void failed(Throwable x) { + if (LOG.isDebugEnabled()) + LOG.debug("OnReset failed", x); complete(); } @@ -1424,14 +1475,15 @@ /** *

    The HTTP/2 specification requires that stream ids are monotonically increasing, - * see https://tools.ietf.org/html/rfc7540#section-5.1.1.

    + * see RFC 7540, 5.1.1.

    *

    This implementation uses a queue to atomically reserve a stream id and claim * a slot in the queue; the slot is then assigned the entries to write.

    *

    Concurrent threads push slots in the queue but only one thread flushes * the slots, up to the slot that has a non-null entries to write, therefore * guaranteeing that frames are sent strictly in their stream id order.

    *

    This class also coordinates the creation of streams with the close of - * the session, see https://tools.ietf.org/html/rfc7540#section-6.8.

    + * the session, see + * RFC 7540, 6.8.

    */ private class StreamsState { @@ -1772,6 +1824,7 @@ { String reason = "idle_timeout"; boolean notify = false; + boolean terminate = false; boolean sendGoAway = false; GoAwayFrame goAwayFrame = null; Throwable cause = null; @@ -1815,11 +1868,22 @@ { if (LOG.isDebugEnabled()) LOG.debug("Already closed, ignored idle timeout for {}", HTTP2Session.this); - return false; + // Writes may be TCP congested, so termination never happened. + terminate = true; + goAwayFrame = goAwaySent; + if (goAwayFrame == null) + goAwayFrame = goAwayRecv; + break; } } } + if (terminate) + { + terminate(goAwayFrame); + return false; + } + if (notify) { boolean confirmed = notifyIdleTimeout(HTTP2Session.this); @@ -2036,14 +2100,15 @@ private boolean newRemoteStream(int streamId) { + boolean created = false; try (Locker.Lock l = lock.lock()) { switch (closed) { case NOT_CLOSED: { - HTTP2Session.this.onStreamCreated(streamId); - return true; + created = true; + break; } case LOCALLY_CLOSED: { @@ -2051,15 +2116,17 @@ if (streamId <= goAwaySent.getLastStreamId()) { // Allow creation of streams that may have been in-flight. - HTTP2Session.this.onStreamCreated(streamId); - return true; + created = true; } - return false; + break; } default: - return false; + break; } } + if (created) + HTTP2Session.this.onStreamCreated(streamId); + return created; } private void push(PushPromiseFrame frame, Promise promise, Stream.Listener listener) @@ -2108,14 +2175,16 @@ private int reserveSlot(Slot slot, int streamId, Consumer fail) { Throwable failure = null; + boolean reserved = false; try (Locker.Lock l = lock.lock()) { + // SPEC: cannot create new streams after receiving a GOAWAY. if (closed == CloseState.NOT_CLOSED) { if (streamId <= 0) { streamId = localStreamIds.getAndAdd(2); - HTTP2Session.this.onStreamCreated(streamId); + reserved = true; } slots.offer(slot); } @@ -2127,9 +2196,16 @@ } } if (failure == null) + { + if (reserved) + HTTP2Session.this.onStreamCreated(streamId); return streamId; - fail.accept(failure); - return 0; + } + else + { + fail.accept(failure); + return 0; + } } private void freeSlot(Slot slot, int streamId) @@ -2168,7 +2244,7 @@ if (flushing == null) flushing = thread; else if (flushing != thread) - return; // another thread is flushing + return; // Another thread is flushing. Slot slot = slots.peek(); entries = slot == null ? null : slot.entries; @@ -2176,7 +2252,8 @@ if (entries == null) { flushing = null; - break; // No more slots or null entries, so we may iterate on the flusher + // No more slots or null entries, so we may iterate on the flusher. + break; } slots.poll(); diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java --- jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java 2024-12-19 21:51:26.000000000 +0000 @@ -390,10 +390,10 @@ } } - if (updateClose(frame.isEndStream(), CloseState.Event.RECEIVED)) - session.removeStream(this); - + boolean closed = updateClose(frame.isEndStream(), CloseState.Event.RECEIVED); notifyData(this, frame, callback); + if (closed) + session.removeStream(this); } private void onReset(ResetFrame frame, Callback callback) diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/HeadersFrame.java jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/HeadersFrame.java --- jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/HeadersFrame.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/HeadersFrame.java 2024-12-19 21:51:26.000000000 +0000 @@ -84,7 +84,6 @@ @Override public String toString() { - return String.format("%s#%d{end=%b}%s", super.toString(), getStreamId(), endStream, - priority == null ? "" : String.format("+%s", priority)); + return String.format("%s#%d[end=%b,{%s},priority=%s]", super.toString(), getStreamId(), isEndStream(), getMetaData(), getPriority()); } } diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/Generator.java jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/Generator.java --- jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/Generator.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/Generator.java 2024-12-19 21:51:26.000000000 +0000 @@ -35,15 +35,21 @@ public Generator(ByteBufferPool byteBufferPool) { - this(byteBufferPool, 4096, 0); + this(byteBufferPool, 0); } + @Deprecated public Generator(ByteBufferPool byteBufferPool, int maxDynamicTableSize, int maxHeaderBlockFragment) { + this(byteBufferPool, maxHeaderBlockFragment); + } + + public Generator(ByteBufferPool byteBufferPool, int maxHeaderBlockFragment) + { this.byteBufferPool = byteBufferPool; headerGenerator = new HeaderGenerator(); - hpackEncoder = new HpackEncoder(maxDynamicTableSize); + hpackEncoder = new HpackEncoder(); this.generators = new FrameGenerator[FrameType.values().length]; this.generators[FrameType.HEADERS.getType()] = new HeadersGenerator(headerGenerator, hpackEncoder, maxHeaderBlockFragment); @@ -66,14 +72,21 @@ return byteBufferPool; } + public HpackEncoder getHpackEncoder() + { + return hpackEncoder; + } + + @Deprecated public void setValidateHpackEncoding(boolean validateEncoding) { - hpackEncoder.setValidateEncoding(validateEncoding); + getHpackEncoder().setValidateEncoding(validateEncoding); } - public void setHeaderTableSize(int headerTableSize) + @Deprecated + public void setHeaderTableSize(int maxTableSize) { - hpackEncoder.setRemoteMaxDynamicTableSize(headerTableSize); + getHpackEncoder().setTableCapacity(maxTableSize); } public void setMaxFrameSize(int maxFrameSize) @@ -91,8 +104,9 @@ return dataGenerator.generate(lease, frame, maxLength); } + @Deprecated public void setMaxHeaderListSize(int value) { - hpackEncoder.setMaxHeaderListSize(value); + getHpackEncoder().setMaxHeaderListSize(value); } } diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ContinuationBodyParser.java jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ContinuationBodyParser.java --- jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ContinuationBodyParser.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ContinuationBodyParser.java 2024-12-19 21:51:26.000000000 +0000 @@ -80,16 +80,28 @@ int remaining = buffer.remaining(); if (remaining < length) { - headerBlockFragments.storeFragment(buffer, remaining, false); + ContinuationFrame frame = new ContinuationFrame(getStreamId(), false); + if (!rateControlOnEvent(frame)) + return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_continuation_frame_rate"); + + if (!headerBlockFragments.storeFragment(buffer, remaining, false)) + return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_continuation_stream"); + length -= remaining; break; } else { - boolean last = hasFlag(Flags.END_HEADERS); - headerBlockFragments.storeFragment(buffer, length, last); + boolean endHeaders = hasFlag(Flags.END_HEADERS); + ContinuationFrame frame = new ContinuationFrame(getStreamId(), endHeaders); + if (!rateControlOnEvent(frame)) + return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_continuation_frame_rate"); + + if (!headerBlockFragments.storeFragment(buffer, length, endHeaders)) + return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_continuation_stream"); + reset(); - if (last) + if (endHeaders) return onHeaders(buffer); return true; } @@ -107,17 +119,21 @@ { ByteBuffer headerBlock = headerBlockFragments.complete(); MetaData metaData = headerBlockParser.parse(headerBlock, headerBlock.remaining()); - if (metaData == null) - return true; + HeadersFrame frame = new HeadersFrame(getStreamId(), metaData, headerBlockFragments.getPriorityFrame(), headerBlockFragments.isEndStream()); + headerBlockFragments.reset(); + if (metaData == HeaderBlockParser.SESSION_FAILURE) return false; - HeadersFrame frame = new HeadersFrame(getStreamId(), metaData, headerBlockFragments.getPriorityFrame(), headerBlockFragments.isEndStream()); - if (metaData == HeaderBlockParser.STREAM_FAILURE) + + if (metaData != HeaderBlockParser.STREAM_FAILURE) + { + notifyHeaders(frame); + } + else { if (!rateControlOnEvent(frame)) - return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_continuation_frame_rate"); + return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_headers_frame_rate"); } - notifyHeaders(frame); return true; } diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockFragments.java jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockFragments.java --- jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockFragments.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockFragments.java 2024-12-19 21:51:26.000000000 +0000 @@ -24,22 +24,40 @@ public class HeaderBlockFragments { + private final int maxCapacity; private PriorityFrame priorityFrame; - private boolean endStream; private int streamId; + private boolean endStream; private ByteBuffer storage; - public void storeFragment(ByteBuffer fragment, int length, boolean last) + public HeaderBlockFragments(int maxCapacity) + { + this.maxCapacity = maxCapacity; + } + + void reset() + { + priorityFrame = null; + streamId = 0; + endStream = false; + storage = null; + } + + public boolean storeFragment(ByteBuffer fragment, int length, boolean last) { if (storage == null) { - int space = last ? length : length * 2; - storage = ByteBuffer.allocate(space); + if (length > maxCapacity) + return false; + int capacity = last ? length : length * 2; + storage = ByteBuffer.allocate(capacity); } // Grow the storage if necessary. if (storage.remaining() < length) { + if (storage.position() + length > maxCapacity) + return false; int space = last ? length : length * 2; int capacity = storage.position() + space; ByteBuffer newStorage = ByteBuffer.allocate(capacity); @@ -53,6 +71,7 @@ fragment.limit(fragment.position() + length); storage.put(fragment); fragment.limit(limit); + return true; } public PriorityFrame getPriorityFrame() @@ -77,10 +96,8 @@ public ByteBuffer complete() { - ByteBuffer result = storage; - storage = null; - result.flip(); - return result; + storage.flip(); + return storage; } public int getStreamId() diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockParser.java jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockParser.java --- jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockParser.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockParser.java 2024-12-19 21:51:26.000000000 +0000 @@ -50,6 +50,11 @@ this.notifier = notifier; } + public int getMaxHeaderListSize() + { + return hpackDecoder.getMaxHeaderListSize(); + } + /** * Parses @{code blockLength} HPACK bytes from the given {@code buffer}. * diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeadersBodyParser.java jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeadersBodyParser.java --- jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeadersBodyParser.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeadersBodyParser.java 2024-12-19 21:51:26.000000000 +0000 @@ -76,8 +76,15 @@ } else { - headerBlockFragments.setStreamId(getStreamId()); - headerBlockFragments.setEndStream(isEndStream()); + if (headerBlockFragments.getStreamId() != 0) + { + connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_headers_frame"); + } + else + { + headerBlockFragments.setStreamId(getStreamId()); + headerBlockFragments.setEndStream(isEndStream()); + } } } @@ -173,8 +180,24 @@ } case HEADERS: { + if (!hasFlag(Flags.END_HEADERS)) + { + headerBlockFragments.setStreamId(getStreamId()); + headerBlockFragments.setEndStream(isEndStream()); + if (hasFlag(Flags.PRIORITY)) + headerBlockFragments.setPriorityFrame(new PriorityFrame(getStreamId(), parentStreamId, weight, exclusive)); + } + state = State.HEADER_BLOCK; + break; + } + case HEADER_BLOCK: + { if (hasFlag(Flags.END_HEADERS)) { + int maxLength = headerBlockParser.getMaxHeaderListSize(); + if (maxLength > 0 && length > maxLength) + return connectionFailure(buffer, ErrorCode.REFUSED_STREAM_ERROR.code, "invalid_headers_frame"); + MetaData metaData = headerBlockParser.parse(buffer, length); if (metaData == HeaderBlockParser.SESSION_FAILURE) return false; @@ -192,7 +215,7 @@ { HeadersFrame frame = new HeadersFrame(getStreamId(), metaData, null, isEndStream()); if (!rateControlOnEvent(frame)) - connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_headers_frame_rate"); + return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_headers_frame_rate"); } } } @@ -201,16 +224,14 @@ int remaining = buffer.remaining(); if (remaining < length) { - headerBlockFragments.storeFragment(buffer, remaining, false); + if (!headerBlockFragments.storeFragment(buffer, remaining, false)) + return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_headers_frame"); length -= remaining; } else { - headerBlockFragments.setStreamId(getStreamId()); - headerBlockFragments.setEndStream(isEndStream()); - if (hasFlag(Flags.PRIORITY)) - headerBlockFragments.setPriorityFrame(new PriorityFrame(getStreamId(), parentStreamId, weight, exclusive)); - headerBlockFragments.storeFragment(buffer, length, false); + if (!headerBlockFragments.storeFragment(buffer, length, false)) + return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_headers_frame"); state = State.PADDING; loop = paddingLength == 0; } @@ -254,6 +275,6 @@ private enum State { - PREPARE, PADDING_LENGTH, EXCLUSIVE, PARENT_STREAM_ID, PARENT_STREAM_ID_BYTES, WEIGHT, HEADERS, PADDING + PREPARE, PADDING_LENGTH, EXCLUSIVE, PARENT_STREAM_ID, PARENT_STREAM_ID_BYTES, WEIGHT, HEADERS, HEADER_BLOCK, PADDING } } diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java --- jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java 2024-12-19 21:51:26.000000000 +0000 @@ -49,36 +49,50 @@ private static final Logger LOG = Log.getLogger(Parser.class); private final ByteBufferPool byteBufferPool; - private final Listener listener; private final HeaderParser headerParser; private final HpackDecoder hpackDecoder; private final BodyParser[] bodyParsers; + private Listener listener; private UnknownBodyParser unknownBodyParser; - private int maxFrameLength = Frame.DEFAULT_MAX_LENGTH; + private int maxFrameSize = Frame.DEFAULT_MAX_LENGTH; private int maxSettingsKeys = SettingsFrame.DEFAULT_MAX_KEYS; private boolean continuation; private State state = State.HEADER; + @Deprecated public Parser(ByteBufferPool byteBufferPool, Listener listener, int maxDynamicTableSize, int maxHeaderSize) { - this(byteBufferPool, listener, maxDynamicTableSize, maxHeaderSize, RateControl.NO_RATE_CONTROL); + this(byteBufferPool, maxHeaderSize, RateControl.NO_RATE_CONTROL); } - public Parser(ByteBufferPool byteBufferPool, Listener listener, int maxDynamicTableSize, int maxHeaderSize, RateControl rateControl) + public Parser(ByteBufferPool byteBufferPool, int maxHeaderSize) + { + this(byteBufferPool, maxHeaderSize, RateControl.NO_RATE_CONTROL); + } + + public Parser(ByteBufferPool byteBufferPool, int maxHeaderSize, RateControl rateControl) { this.byteBufferPool = byteBufferPool; - this.listener = listener; this.headerParser = new HeaderParser(rateControl == null ? RateControl.NO_RATE_CONTROL : rateControl); - this.hpackDecoder = new HpackDecoder(maxDynamicTableSize, maxHeaderSize); + this.hpackDecoder = new HpackDecoder(maxHeaderSize); this.bodyParsers = new BodyParser[FrameType.values().length]; } + @Deprecated public void init(UnaryOperator wrapper) { - Listener listener = wrapper.apply(this.listener); + Listener listener = wrapper.apply(new Listener.Adapter()); + init(listener); + } + + public void init(Listener listener) + { + if (this.listener != null) + throw new IllegalStateException("Invalid parser initialization"); + this.listener = listener; unknownBodyParser = new UnknownBodyParser(headerParser, listener); HeaderBlockParser headerBlockParser = new HeaderBlockParser(headerParser, byteBufferPool, hpackDecoder, unknownBodyParser); - HeaderBlockFragments headerBlockFragments = new HeaderBlockFragments(); + HeaderBlockFragments headerBlockFragments = new HeaderBlockFragments(hpackDecoder.getMaxHeaderListSize()); bodyParsers[FrameType.DATA.getType()] = new DataBodyParser(headerParser, listener); bodyParsers[FrameType.HEADERS.getType()] = new HeadersBodyParser(headerParser, listener, headerBlockParser, headerBlockFragments); bodyParsers[FrameType.PRIORITY.getType()] = new PriorityBodyParser(headerParser, listener); @@ -91,6 +105,16 @@ bodyParsers[FrameType.CONTINUATION.getType()] = new ContinuationBodyParser(headerParser, listener, headerBlockParser, headerBlockFragments); } + protected Listener getListener() + { + return listener; + } + + public HpackDecoder getHpackDecoder() + { + return hpackDecoder; + } + private void reset() { headerParser.reset(); @@ -151,7 +175,7 @@ if (LOG.isDebugEnabled()) LOG.debug("Parsed {} frame header from {}@{}", headerParser, buffer, Integer.toHexString(buffer.hashCode())); - if (headerParser.getLength() > getMaxFrameLength()) + if (headerParser.getLength() > getMaxFrameSize()) return connectionFailure(buffer, ErrorCode.FRAME_SIZE_ERROR, "invalid_frame_length"); FrameType frameType = FrameType.from(getFrameType()); @@ -219,14 +243,26 @@ return headerParser.hasFlag(bit); } + @Deprecated public int getMaxFrameLength() { - return maxFrameLength; + return getMaxFrameSize(); + } + + @Deprecated + public void setMaxFrameLength(int maxFrameSize) + { + setMaxFrameSize(maxFrameSize); + } + + public int getMaxFrameSize() + { + return maxFrameSize; } - public void setMaxFrameLength(int maxFrameLength) + public void setMaxFrameSize(int maxFrameSize) { - this.maxFrameLength = maxFrameLength; + this.maxFrameSize = maxFrameSize; } public int getMaxSettingsKeys() diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PushPromiseBodyParser.java jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PushPromiseBodyParser.java --- jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PushPromiseBodyParser.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PushPromiseBodyParser.java 2024-12-19 21:51:26.000000000 +0000 @@ -23,6 +23,7 @@ import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http2.ErrorCode; import org.eclipse.jetty.http2.Flags; +import org.eclipse.jetty.http2.frames.HeadersFrame; import org.eclipse.jetty.http2.frames.PushPromiseFrame; public class PushPromiseBodyParser extends BodyParser @@ -70,13 +71,9 @@ length = getBodyLength(); if (isPadding()) - { state = State.PADDING_LENGTH; - } else - { state = State.STREAM_ID; - } break; } case PADDING_LENGTH: @@ -124,6 +121,10 @@ } case HEADERS: { + int maxLength = headerBlockParser.getMaxHeaderListSize(); + if (maxLength > 0 && length > maxLength) + return connectionFailure(buffer, ErrorCode.REFUSED_STREAM_ERROR.code, "invalid_headers_frame"); + MetaData metaData = headerBlockParser.parse(buffer, length); if (metaData == HeaderBlockParser.SESSION_FAILURE) return false; @@ -132,7 +133,15 @@ state = State.PADDING; loop = paddingLength == 0; if (metaData != HeaderBlockParser.STREAM_FAILURE) + { onPushPromise(streamId, metaData); + } + else + { + HeadersFrame frame = new HeadersFrame(getStreamId(), metaData, null, isEndStream()); + if (!rateControlOnEvent(frame)) + return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_headers_frame_rate"); + } } break; } diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ResetBodyParser.java jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ResetBodyParser.java --- jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ResetBodyParser.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ResetBodyParser.java 2024-12-19 21:51:26.000000000 +0000 @@ -63,7 +63,7 @@ { if (buffer.remaining() >= 4) { - return onReset(buffer.getInt()); + return onReset(buffer, buffer.getInt()); } else { @@ -78,7 +78,7 @@ --cursor; error += currByte << (8 * cursor); if (cursor == 0) - return onReset(error); + return onReset(buffer, error); break; } default: @@ -90,9 +90,11 @@ return false; } - private boolean onReset(int error) + private boolean onReset(ByteBuffer buffer, int error) { ResetFrame frame = new ResetFrame(getStreamId(), error); + if (!rateControlOnEvent(frame)) + return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_rst_stream_frame_rate"); reset(); notifyReset(frame); return true; diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ServerParser.java jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ServerParser.java --- jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ServerParser.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ServerParser.java 2024-12-19 21:51:26.000000000 +0000 @@ -32,15 +32,30 @@ { private static final Logger LOG = Log.getLogger(ServerParser.class); - private final Listener listener; - private final PrefaceParser prefaceParser; + private PrefaceParser prefaceParser; private State state = State.PREFACE; private boolean notifyPreface = true; + @Deprecated public ServerParser(ByteBufferPool byteBufferPool, Listener listener, int maxDynamicTableSize, int maxHeaderSize, RateControl rateControl) { - super(byteBufferPool, listener, maxDynamicTableSize, maxHeaderSize, rateControl); - this.listener = listener; + this(byteBufferPool, maxHeaderSize, rateControl); + } + + public ServerParser(ByteBufferPool byteBufferPool, int maxHeaderSize) + { + super(byteBufferPool, maxHeaderSize); + } + + public ServerParser(ByteBufferPool byteBufferPool, int maxHeaderSize, RateControl rateControl) + { + super(byteBufferPool, maxHeaderSize, rateControl); + } + + @Override + public void init(Parser.Listener listener) + { + super.init(listener); this.prefaceParser = new PrefaceParser(listener); } @@ -137,9 +152,23 @@ private void notifyPreface() { + Parser.Listener listener = getListener(); try { - listener.onPreface(); + while (true) + { + if (listener instanceof ServerParser.Listener) + { + ((ServerParser.Listener)listener).onPreface(); + break; + } + + // Unwrap to try and find a ServerParser.Listener. + if (listener instanceof Parser.Listener.Wrapper) + listener = ((Parser.Listener.Wrapper)listener).getParserListener(); + else + break; + } } catch (Throwable x) { diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/SettingsBodyParser.java jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/SettingsBodyParser.java --- jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/SettingsBodyParser.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/SettingsBodyParser.java 2024-12-19 21:51:26.000000000 +0000 @@ -73,12 +73,22 @@ @Override protected void emptyBody(ByteBuffer buffer) { + if (!validateFrame(buffer, getStreamId(), 0)) + return; boolean isReply = hasFlag(Flags.ACK); SettingsFrame frame = new SettingsFrame(Collections.emptyMap(), isReply); - if (!isReply && !rateControlOnEvent(frame)) - connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_settings_frame_rate"); - else - onSettings(frame); + onSettings(buffer, frame); + } + + private boolean validateFrame(ByteBuffer buffer, int streamId, int bodyLength) + { + // SPEC: wrong streamId is treated as connection error. + if (streamId != 0) + return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_settings_frame"); + // SPEC: reply with body is treated as connection error. + if (hasFlag(Flags.ACK) && bodyLength > 0) + return connectionFailure(buffer, ErrorCode.FRAME_SIZE_ERROR.code, "invalid_settings_frame"); + return true; } @Override @@ -95,9 +105,8 @@ { case PREPARE: { - // SPEC: wrong streamId is treated as connection error. - if (streamId != 0) - return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_settings_frame"); + if (!validateFrame(buffer, streamId, bodyLength)) + return false; length = bodyLength; settings = new HashMap<>(); state = State.SETTING_ID; @@ -211,11 +220,13 @@ return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_settings_max_frame_size"); SettingsFrame frame = new SettingsFrame(settings, hasFlag(Flags.ACK)); - return onSettings(frame); + return onSettings(buffer, frame); } - private boolean onSettings(SettingsFrame frame) + private boolean onSettings(ByteBuffer buffer, SettingsFrame frame) { + if (!rateControlOnEvent(frame)) + return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_settings_frame_rate"); reset(); notifySettings(frame); return true; diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/UnknownBodyParser.java jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/UnknownBodyParser.java --- jetty9-9.4.50/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/UnknownBodyParser.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/UnknownBodyParser.java 2024-12-19 21:51:26.000000000 +0000 @@ -40,7 +40,6 @@ boolean parsed = cursor == 0; if (parsed && !rateControlOnEvent(new UnknownFrame(getFrameType()))) return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_unknown_frame_rate"); - return parsed; } diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java --- jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -21,7 +21,8 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; -import java.util.function.UnaryOperator; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.IntStream; import org.eclipse.jetty.http.HostPortHttpField; import org.eclipse.jetty.http.HttpField; @@ -38,6 +39,8 @@ import org.eclipse.jetty.io.MappedByteBufferPool; import org.junit.jupiter.api.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.greaterThan; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -51,7 +54,8 @@ HeadersGenerator generator = new HeadersGenerator(new HeaderGenerator(), new HpackEncoder()); final List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onHeaders(HeadersFrame frame) @@ -64,8 +68,7 @@ { frames.add(new HeadersFrame(null, null, false)); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); // Iterate a few times to be sure the parser is properly reset. for (int i = 0; i < 2; ++i) @@ -160,4 +163,54 @@ assertNull(priority); } } + + @Test + public void testLargeHeadersBlock() throws Exception + { + // Use a ByteBufferPool with a small factor, so that the accumulation buffer is not too large. + ByteBufferPool byteBufferPool = new MappedByteBufferPool(128); + // A small max headers size, used for both accumulation and decoding. + int maxHeadersSize = 512; + Parser parser = new Parser(byteBufferPool, maxHeadersSize); + // Specify headers block size to generate CONTINUATION frames. + int maxHeadersBlockFragment = 128; + HeadersGenerator generator = new HeadersGenerator(new HeaderGenerator(), new HpackEncoder(), maxHeadersBlockFragment); + + int streamId = 13; + HttpFields fields = new HttpFields(); + fields.put("Accept", "text/html"); + // Large header that generates a large headers block. + StringBuilder large = new StringBuilder(); + IntStream.range(0, 256).forEach(i -> large.append("Jetty")); + fields.put("User-Agent", large.toString()); + + MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP.asString(), new HostPortHttpField("localhost:8080"), "/path", HttpVersion.HTTP_2, fields, -1); + + ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool); + generator.generateHeaders(lease, streamId, metaData, null, true); + List byteBuffers = lease.getByteBuffers(); + assertThat(byteBuffers.stream().mapToInt(ByteBuffer::remaining).sum(), greaterThan(maxHeadersSize)); + + AtomicBoolean failed = new AtomicBoolean(); + parser.init(new Parser.Listener.Adapter() + { + @Override + public void onConnectionFailure(int error, String reason) + { + failed.set(true); + } + }); + // Set a large max headers size for decoding, to ensure + // the failure is due to accumulation, not decoding. + parser.getHpackDecoder().setMaxHeaderListSize(10 * maxHeadersSize); + + for (ByteBuffer byteBuffer : byteBuffers) + { + parser.parse(byteBuffer); + if (failed.get()) + break; + } + + assertTrue(failed.get()); + } } diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/DataGenerateParseTest.java jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/DataGenerateParseTest.java --- jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/DataGenerateParseTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/DataGenerateParseTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -22,7 +22,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; -import java.util.function.UnaryOperator; import org.eclipse.jetty.http2.generator.DataGenerator; import org.eclipse.jetty.http2.generator.HeaderGenerator; @@ -93,15 +92,15 @@ DataGenerator generator = new DataGenerator(new HeaderGenerator()); final List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onData(DataFrame frame) { frames.add(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); // Iterate a few times to be sure generator and parser are properly reset. for (int i = 0; i < 2; ++i) @@ -133,15 +132,15 @@ DataGenerator generator = new DataGenerator(new HeaderGenerator()); final List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onData(DataFrame frame) { frames.add(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); // Iterate a few times to be sure generator and parser are properly reset. for (int i = 0; i < 2; ++i) diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java --- jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -21,7 +21,6 @@ import java.nio.ByteBuffer; import java.time.Duration; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.UnaryOperator; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MetaData; @@ -95,21 +94,29 @@ } @Test - public void testSettingsFrameFlood() + public void testEmptySettingsFrameFlood() { byte[] payload = new byte[0]; testFrameFlood(null, frameFrom(payload.length, FrameType.SETTINGS.getType(), 0, 0, payload)); } @Test + public void testSettingsFrameFlood() + { + // | Key0 | Key1 | Value0 | Value1 | Value2 | Value3 | + byte[] payload = new byte[]{0, 8, 0, 0, 0, 1}; + testFrameFlood(null, frameFrom(payload.length, FrameType.SETTINGS.getType(), 0, 0, payload)); + } + + @Test public void testPingFrameFlood() { byte[] payload = {0, 0, 0, 0, 0, 0, 0, 0}; testFrameFlood(null, frameFrom(payload.length, FrameType.PING.getType(), 0, 0, payload)); } - + @Test - public void testContinuationFrameFlood() + public void testEmptyContinuationFrameFlood() { int streamId = 13; byte[] headersPayload = new byte[0]; @@ -119,6 +126,23 @@ } @Test + public void testContinuationFrameFlood() + { + int streamId = 13; + byte[] headersPayload = new byte[0]; + byte[] headersBytes = frameFrom(headersPayload.length, FrameType.HEADERS.getType(), 0, streamId, headersPayload); + byte[] continuationPayload = new byte[1]; + testFrameFlood(headersBytes, frameFrom(continuationPayload.length, FrameType.CONTINUATION.getType(), 0, streamId, continuationPayload)); + } + + @Test + public void testResetStreamFrameFlood() + { + byte[] payload = {0, 0, 0, 0}; + testFrameFlood(null, frameFrom(payload.length, FrameType.RST_STREAM.getType(), 0, 13, payload)); + } + + @Test public void testUnknownFrameFlood() { byte[] payload = {0, 0, 0, 0}; @@ -128,15 +152,15 @@ private void testFrameFlood(byte[] preamble, byte[] bytes) { AtomicBoolean failed = new AtomicBoolean(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 8192, new WindowRateControl(8, Duration.ofSeconds(1))); + parser.init(new Parser.Listener.Adapter() { @Override public void onConnectionFailure(int error, String reason) { failed.set(true); } - }, 4096, 8192, new WindowRateControl(8, Duration.ofSeconds(1))); - parser.init(UnaryOperator.identity()); + }); if (preamble != null) { diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/GoAwayGenerateParseTest.java jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/GoAwayGenerateParseTest.java --- jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/GoAwayGenerateParseTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/GoAwayGenerateParseTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -22,7 +22,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; -import java.util.function.UnaryOperator; import org.eclipse.jetty.http2.generator.GoAwayGenerator; import org.eclipse.jetty.http2.generator.HeaderGenerator; @@ -45,15 +44,15 @@ GoAwayGenerator generator = new GoAwayGenerator(new HeaderGenerator()); final List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onGoAway(GoAwayFrame frame) { frames.add(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); int lastStreamId = 13; int error = 17; @@ -87,15 +86,15 @@ GoAwayGenerator generator = new GoAwayGenerator(new HeaderGenerator()); final List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onGoAway(GoAwayFrame frame) { frames.add(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); int lastStreamId = 13; int error = 17; diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersGenerateParseTest.java jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersGenerateParseTest.java --- jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersGenerateParseTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersGenerateParseTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -21,7 +21,6 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; -import java.util.function.UnaryOperator; import org.eclipse.jetty.http.HostPortHttpField; import org.eclipse.jetty.http.HttpField; @@ -57,15 +56,15 @@ MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP, new HostPortHttpField("localhost:8080"), "/path", HttpVersion.HTTP_2, fields); final List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onHeaders(HeadersFrame frame) { frames.add(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); // Iterate a few times to be sure generator and parser are properly reset. for (int i = 0; i < 2; ++i) @@ -110,15 +109,15 @@ HeadersGenerator generator = new HeadersGenerator(new HeaderGenerator(), new HpackEncoder()); final List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onHeaders(HeadersFrame frame) { frames.add(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); // Iterate a few times to be sure generator and parser are properly reset. for (int i = 0; i < 2; ++i) diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/MaxFrameSizeParseTest.java jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/MaxFrameSizeParseTest.java --- jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/MaxFrameSizeParseTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/MaxFrameSizeParseTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -20,7 +20,6 @@ import java.nio.ByteBuffer; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.UnaryOperator; import org.eclipse.jetty.http2.ErrorCode; import org.eclipse.jetty.http2.parser.Parser; @@ -40,16 +39,16 @@ int maxFrameLength = Frame.DEFAULT_MAX_LENGTH + 16; AtomicInteger failure = new AtomicInteger(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.setMaxFrameSize(maxFrameLength); + parser.init(new Parser.Listener.Adapter() { @Override public void onConnectionFailure(int error, String reason) { failure.set(error); } - }, 4096, 8192); - parser.setMaxFrameLength(maxFrameLength); - parser.init(UnaryOperator.identity()); + }); // Iterate a few times to be sure the parser is properly reset. for (int i = 0; i < 2; ++i) diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PingGenerateParseTest.java jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PingGenerateParseTest.java --- jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PingGenerateParseTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PingGenerateParseTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -22,7 +22,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; -import java.util.function.UnaryOperator; import org.eclipse.jetty.http2.generator.HeaderGenerator; import org.eclipse.jetty.http2.generator.PingGenerator; @@ -45,15 +44,15 @@ PingGenerator generator = new PingGenerator(new HeaderGenerator()); final List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onPing(PingFrame frame) { frames.add(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); byte[] payload = new byte[8]; new Random().nextBytes(payload); @@ -86,15 +85,15 @@ PingGenerator generator = new PingGenerator(new HeaderGenerator()); final List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onPing(PingFrame frame) { frames.add(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); byte[] payload = new byte[8]; new Random().nextBytes(payload); @@ -127,15 +126,15 @@ PingGenerator generator = new PingGenerator(new HeaderGenerator()); final List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onPing(PingFrame frame) { frames.add(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool); PingFrame ping = new PingFrame(System.nanoTime(), true); diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PriorityGenerateParseTest.java jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PriorityGenerateParseTest.java --- jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PriorityGenerateParseTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PriorityGenerateParseTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -21,7 +21,6 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; -import java.util.function.UnaryOperator; import org.eclipse.jetty.http2.generator.HeaderGenerator; import org.eclipse.jetty.http2.generator.PriorityGenerator; @@ -42,15 +41,15 @@ PriorityGenerator generator = new PriorityGenerator(new HeaderGenerator()); final List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onPriority(PriorityFrame frame) { frames.add(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); int streamId = 13; int parentStreamId = 17; @@ -87,15 +86,15 @@ PriorityGenerator generator = new PriorityGenerator(new HeaderGenerator()); final List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onPriority(PriorityFrame frame) { frames.add(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); int streamId = 13; int parentStreamId = 17; diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PushPromiseGenerateParseTest.java jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PushPromiseGenerateParseTest.java --- jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PushPromiseGenerateParseTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PushPromiseGenerateParseTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -21,7 +21,6 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; -import java.util.function.UnaryOperator; import org.eclipse.jetty.http.HostPortHttpField; import org.eclipse.jetty.http.HttpField; @@ -50,15 +49,15 @@ PushPromiseGenerator generator = new PushPromiseGenerator(new HeaderGenerator(), new HpackEncoder()); final List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onPushPromise(PushPromiseFrame frame) { frames.add(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); int streamId = 13; int promisedStreamId = 17; @@ -103,15 +102,15 @@ PushPromiseGenerator generator = new PushPromiseGenerator(new HeaderGenerator(), new HpackEncoder()); final List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onPushPromise(PushPromiseFrame frame) { frames.add(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); int streamId = 13; int promisedStreamId = 17; diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ResetGenerateParseTest.java jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ResetGenerateParseTest.java --- jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ResetGenerateParseTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ResetGenerateParseTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -21,7 +21,6 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; -import java.util.function.UnaryOperator; import org.eclipse.jetty.http2.generator.HeaderGenerator; import org.eclipse.jetty.http2.generator.ResetGenerator; @@ -42,15 +41,15 @@ ResetGenerator generator = new ResetGenerator(new HeaderGenerator()); final List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onReset(ResetFrame frame) { frames.add(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); int streamId = 13; int error = 17; @@ -83,15 +82,15 @@ ResetGenerator generator = new ResetGenerator(new HeaderGenerator()); final List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onReset(ResetFrame frame) { frames.add(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); int streamId = 13; int error = 17; diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java --- jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -25,7 +25,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.UnaryOperator; import org.eclipse.jetty.http2.ErrorCode; import org.eclipse.jetty.http2.generator.HeaderGenerator; @@ -36,6 +35,7 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; public class SettingsGenerateParseTest @@ -45,8 +45,7 @@ @Test public void testGenerateParseNoSettings() { - - List frames = testGenerateParse(Collections.emptyMap()); + List frames = testGenerateParse(Collections.emptyMap(), true); assertEquals(1, frames.size()); SettingsFrame frame = frames.get(0); assertEquals(0, frame.getSettings().size()); @@ -63,7 +62,7 @@ int key2 = 19; Integer value2 = 23; settings1.put(key2, value2); - List frames = testGenerateParse(settings1); + List frames = testGenerateParse(settings1, false); assertEquals(1, frames.size()); SettingsFrame frame = frames.get(0); Map settings2 = frame.getSettings(); @@ -72,26 +71,26 @@ assertEquals(value2, settings2.get(key2)); } - private List testGenerateParse(Map settings) + private List testGenerateParse(Map settings, boolean reply) { SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator()); List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 8192); + parser.init(new Parser.Listener.Adapter() { @Override public void onSettings(SettingsFrame frame) { frames.add(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); // Iterate a few times to be sure generator and parser are properly reset. for (int i = 0; i < 2; ++i) { ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool); - generator.generateSettings(lease, settings, true); + generator.generateSettings(lease, settings, reply); frames.clear(); for (ByteBuffer buffer : lease.getByteBuffers()) @@ -112,20 +111,20 @@ SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator()); AtomicInteger errorRef = new AtomicInteger(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 8192); + parser.init(new Parser.Listener.Adapter() { @Override public void onConnectionFailure(int error, String reason) { errorRef.set(error); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); Map settings1 = new HashMap<>(); settings1.put(13, 17); ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool); - generator.generateSettings(lease, settings1, true); + generator.generateSettings(lease, settings1, false); // Modify the length of the frame to make it invalid ByteBuffer bytes = lease.getByteBuffers().get(0); bytes.putShort(1, (short)(bytes.getShort(1) - 1)); @@ -147,15 +146,15 @@ SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator()); List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 8192); + parser.init(new Parser.Listener.Adapter() { @Override public void onSettings(SettingsFrame frame) { frames.add(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); Map settings1 = new HashMap<>(); int key = 13; @@ -166,7 +165,7 @@ for (int i = 0; i < 2; ++i) { ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool); - generator.generateSettings(lease, settings1, true); + generator.generateSettings(lease, settings1, false); frames.clear(); for (ByteBuffer buffer : lease.getByteBuffers()) @@ -182,7 +181,7 @@ Map settings2 = frame.getSettings(); assertEquals(1, settings2.size()); assertEquals(value, settings2.get(key)); - assertTrue(frame.isReply()); + assertFalse(frame.isReply()); } } @@ -192,17 +191,17 @@ SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator()); AtomicInteger errorRef = new AtomicInteger(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 8192); + int maxSettingsKeys = 32; + parser.setMaxSettingsKeys(maxSettingsKeys); + parser.init(new Parser.Listener.Adapter() { @Override public void onConnectionFailure(int error, String reason) { errorRef.set(error); } - }, 4096, 8192); - int maxSettingsKeys = 32; - parser.setMaxSettingsKeys(maxSettingsKeys); - parser.init(UnaryOperator.identity()); + }); Map settings = new HashMap<>(); for (int i = 0; i < maxSettingsKeys + 1; ++i) @@ -232,10 +231,10 @@ int maxSettingsKeys = pairs / 2; AtomicInteger errorRef = new AtomicInteger(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter(), 4096, 8192); + Parser parser = new Parser(byteBufferPool, 8192); parser.setMaxSettingsKeys(maxSettingsKeys); - parser.setMaxFrameLength(Frame.DEFAULT_MAX_LENGTH); - parser.init(listener -> new Parser.Listener.Wrapper(listener) + parser.setMaxFrameSize(Frame.DEFAULT_MAX_LENGTH); + parser.init(new Parser.Listener.Adapter() { @Override public void onConnectionFailure(int error, String reason) @@ -273,17 +272,17 @@ SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator()); AtomicInteger errorRef = new AtomicInteger(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 8192); + int maxSettingsKeys = 32; + parser.setMaxSettingsKeys(maxSettingsKeys); + parser.init(new Parser.Listener.Adapter() { @Override public void onConnectionFailure(int error, String reason) { errorRef.set(error); } - }, 4096, 8192); - int maxSettingsKeys = 32; - parser.setMaxSettingsKeys(maxSettingsKeys); - parser.init(UnaryOperator.identity()); + }); Map settings = new HashMap<>(); settings.put(13, 17); diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/UnknownParseTest.java jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/UnknownParseTest.java --- jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/UnknownParseTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/UnknownParseTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -22,7 +22,6 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; -import java.util.function.UnaryOperator; import org.eclipse.jetty.http2.ErrorCode; import org.eclipse.jetty.http2.parser.Parser; @@ -53,8 +52,8 @@ public void testInvalidFrameSize() { AtomicInteger failure = new AtomicInteger(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter(), 4096, 8192); - parser.init(listener -> new Parser.Listener.Wrapper(listener) + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onConnectionFailure(int error, String reason) @@ -62,7 +61,7 @@ failure.set(error); } }); - parser.setMaxFrameLength(Frame.DEFAULT_MAX_LENGTH); + parser.setMaxFrameSize(Frame.DEFAULT_MAX_LENGTH); // 0x4001 == 16385 which is > Frame.DEFAULT_MAX_LENGTH. byte[] bytes = new byte[]{0, 0x40, 0x01, 64, 0, 0, 0, 0, 0}; @@ -78,15 +77,15 @@ private void testParse(Function fn) { AtomicBoolean failure = new AtomicBoolean(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onConnectionFailure(int error, String reason) { failure.set(true); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); // Iterate a few times to be sure the parser is properly reset. for (int i = 0; i < 2; ++i) diff -Nru jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/WindowUpdateGenerateParseTest.java jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/WindowUpdateGenerateParseTest.java --- jetty9-9.4.50/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/WindowUpdateGenerateParseTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/WindowUpdateGenerateParseTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -21,7 +21,6 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; -import java.util.function.UnaryOperator; import org.eclipse.jetty.http2.generator.HeaderGenerator; import org.eclipse.jetty.http2.generator.WindowUpdateGenerator; @@ -42,15 +41,15 @@ WindowUpdateGenerator generator = new WindowUpdateGenerator(new HeaderGenerator()); final List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onWindowUpdate(WindowUpdateFrame frame) { frames.add(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); int streamId = 13; int windowUpdate = 17; @@ -83,15 +82,15 @@ WindowUpdateGenerator generator = new WindowUpdateGenerator(new HeaderGenerator()); final List frames = new ArrayList<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onWindowUpdate(WindowUpdateFrame frame) { frames.add(frame); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); int streamId = 13; int windowUpdate = 17; diff -Nru jetty9-9.4.50/jetty-http2/http2-hpack/pom.xml jetty9-9.4.57/jetty-http2/http2-hpack/pom.xml --- jetty9-9.4.50/jetty-http2/http2-hpack/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-hpack/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java jetty9-9.4.57/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java --- jetty9-9.4.50/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java 2024-12-19 21:51:26.000000000 +0000 @@ -29,6 +29,8 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpScheme; +import org.eclipse.jetty.http.compression.HuffmanEncoder; +import org.eclipse.jetty.http.compression.NBitIntegerEncoder; import org.eclipse.jetty.util.ArrayTernaryTrie; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.Trie; @@ -118,6 +120,7 @@ private static final StaticEntry[] __staticTableByHeader = new StaticEntry[HttpHeader.UNKNOWN.ordinal()]; private static final StaticEntry[] __staticTable = new StaticEntry[STATIC_TABLE.length]; public static final int STATIC_SIZE = STATIC_TABLE.length - 1; + public static final int DEFAULT_MAX_TABLE_CAPACITY = 4096; static { @@ -153,7 +156,7 @@ case C_STATUS: { - entry = new StaticEntry(i, new StaticTableHttpField(header, name, value, Integer.valueOf(value))); + entry = new StaticEntry(i, new StaticTableHttpField(header, name, value, value)); break; } @@ -187,26 +190,26 @@ } } - private int _maxDynamicTableSizeInBytes; - private int _dynamicTableSizeInBytes; private final DynamicTable _dynamicTable; private final Map _fieldMap = new HashMap<>(); private final Map _nameMap = new HashMap<>(); + private int _maxTableSize; + private int _tableSize; - HpackContext(int maxDynamicTableSize) + HpackContext(int maxTableSize) { - _maxDynamicTableSizeInBytes = maxDynamicTableSize; - int guesstimateEntries = 10 + maxDynamicTableSize / (32 + 10 + 10); + _maxTableSize = maxTableSize; + int guesstimateEntries = 10 + maxTableSize / (32 + 10 + 10); _dynamicTable = new DynamicTable(guesstimateEntries); if (LOG.isDebugEnabled()) - LOG.debug(String.format("HdrTbl[%x] created max=%d", hashCode(), maxDynamicTableSize)); + LOG.debug(String.format("HdrTbl[%x] created max=%d", hashCode(), maxTableSize)); } public void resize(int newMaxDynamicTableSize) { if (LOG.isDebugEnabled()) - LOG.debug(String.format("HdrTbl[%x] resized max=%d->%d", hashCode(), _maxDynamicTableSizeInBytes, newMaxDynamicTableSize)); - _maxDynamicTableSizeInBytes = newMaxDynamicTableSize; + LOG.debug(String.format("HdrTbl[%x] resized max=%d->%d", hashCode(), _maxTableSize, newMaxDynamicTableSize)); + _maxTableSize = newMaxDynamicTableSize; _dynamicTable.evict(); } @@ -251,14 +254,14 @@ { Entry entry = new Entry(field); int size = entry.getSize(); - if (size > _maxDynamicTableSizeInBytes) + if (size > _maxTableSize) { if (LOG.isDebugEnabled()) - LOG.debug(String.format("HdrTbl[%x] !added size %d>%d", hashCode(), size, _maxDynamicTableSizeInBytes)); + LOG.debug(String.format("HdrTbl[%x] !added size %d>%d", hashCode(), size, _maxTableSize)); _dynamicTable.evictAll(); return null; } - _dynamicTableSizeInBytes += size; + _tableSize += size; _dynamicTable.add(entry); _fieldMap.put(field, entry); _nameMap.put(field.getLowerCaseName(), entry); @@ -282,7 +285,7 @@ */ public int getDynamicTableSize() { - return _dynamicTableSizeInBytes; + return _tableSize; } /** @@ -290,7 +293,7 @@ */ public int getMaxDynamicTableSize() { - return _maxDynamicTableSizeInBytes; + return _maxTableSize; } public int index(Entry entry) @@ -316,15 +319,15 @@ @Override public String toString() { - return String.format("HpackContext@%x{entries=%d,size=%d,max=%d}", hashCode(), _dynamicTable.size(), _dynamicTableSizeInBytes, _maxDynamicTableSizeInBytes); + return String.format("HpackContext@%x{entries=%d,size=%d,max=%d}", hashCode(), _dynamicTable.size(), _tableSize, _maxTableSize); } private class DynamicTable { - Entry[] _entries; - int _size; - int _offset; - int _growby; + private Entry[] _entries; + private final int _growby; + private int _size; + private int _offset; private DynamicTable(int initCapacity) { @@ -372,7 +375,7 @@ private void evict() { - while (_dynamicTableSizeInBytes > _maxDynamicTableSizeInBytes) + while (_tableSize > _maxTableSize) { Entry entry = _entries[_offset]; _entries[_offset] = null; @@ -380,7 +383,7 @@ _size--; if (LOG.isDebugEnabled()) LOG.debug(String.format("HdrTbl[%x] evict %s", HpackContext.this.hashCode(), entry)); - _dynamicTableSizeInBytes -= entry.getSize(); + _tableSize -= entry.getSize(); entry._slot = -1; _fieldMap.remove(entry.getHttpField()); String lc = entry.getHttpField().getLowerCaseName(); @@ -388,7 +391,7 @@ _nameMap.remove(lc); } if (LOG.isDebugEnabled()) - LOG.debug(String.format("HdrTbl[%x] entries=%d, size=%d, max=%d", HpackContext.this.hashCode(), _dynamicTable.size(), _dynamicTableSizeInBytes, _maxDynamicTableSizeInBytes)); + LOG.debug(String.format("HdrTbl[%x] entries=%d, size=%d, max=%d", HpackContext.this.hashCode(), _dynamicTable.size(), _tableSize, _maxTableSize)); } private void evictAll() @@ -401,7 +404,7 @@ _nameMap.clear(); _offset = 0; _size = 0; - _dynamicTableSizeInBytes = 0; + _tableSize = 0; Arrays.fill(_entries, null); } } @@ -461,21 +464,21 @@ super(field); _slot = index; String value = field.getValue(); - if (value != null && value.length() > 0) + if (value != null && !value.isEmpty()) { - int huffmanLen = Huffman.octetsNeeded(value); + int huffmanLen = HuffmanEncoder.octetsNeeded(value); if (huffmanLen < 0) throw new IllegalStateException("bad value"); - int lenLen = NBitInteger.octectsNeeded(7, huffmanLen); - _huffmanValue = new byte[1 + lenLen + huffmanLen]; + int lenLen = NBitIntegerEncoder.octetsNeeded(7, huffmanLen); + _huffmanValue = new byte[lenLen + huffmanLen]; ByteBuffer buffer = ByteBuffer.wrap(_huffmanValue); // Indicate Huffman buffer.put((byte)0x80); // Add huffman length - NBitInteger.encode(buffer, 7, huffmanLen); + NBitIntegerEncoder.encode(buffer, 7, huffmanLen); // Encode value - Huffman.encode(buffer, value); + HuffmanEncoder.encode(buffer, value); } else _huffmanValue = null; diff -Nru jetty9-9.4.50/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java jetty9-9.4.57/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java --- jetty9-9.4.50/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java 2024-12-19 21:51:26.000000000 +0000 @@ -24,8 +24,12 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpTokens; import org.eclipse.jetty.http.MetaData; +import org.eclipse.jetty.http.compression.EncodingException; +import org.eclipse.jetty.http.compression.HuffmanDecoder; +import org.eclipse.jetty.http.compression.NBitIntegerDecoder; import org.eclipse.jetty.http2.hpack.HpackContext.Entry; -import org.eclipse.jetty.util.TypeUtil; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.CharsetStringBuilder; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -41,17 +45,27 @@ private final HpackContext _context; private final MetaDataBuilder _builder; - private int _localMaxDynamicTableSize; + private final HuffmanDecoder _huffmanDecoder; + private final NBitIntegerDecoder _integerDecoder; + private int _maxTableCapacity; + + @Deprecated + public HpackDecoder(int localMaxDynamicTableSize, int maxHeaderSize) + { + this(maxHeaderSize); + } /** - * @param localMaxDynamicTableSize The maximum allowed size of the local dynamic header field table. - * @param maxHeaderSize The maximum allowed size of a headers block, expressed as total of all name and value characters, plus 32 per field + * @param maxHeaderSize The maximum allowed size of a decoded headers block, + * expressed as total of all name and value bytes, plus 32 bytes per field */ - public HpackDecoder(int localMaxDynamicTableSize, int maxHeaderSize) + public HpackDecoder(int maxHeaderSize) { - _context = new HpackContext(localMaxDynamicTableSize); - _localMaxDynamicTableSize = localMaxDynamicTableSize; + _context = new HpackContext(HpackContext.DEFAULT_MAX_TABLE_CAPACITY); _builder = new MetaDataBuilder(maxHeaderSize); + _huffmanDecoder = new HuffmanDecoder(); + _integerDecoder = new NBitIntegerDecoder(); + setMaxTableCapacity(HpackContext.DEFAULT_MAX_TABLE_CAPACITY); } public HpackContext getHpackContext() @@ -59,9 +73,44 @@ return _context; } - public void setLocalMaxDynamicTableSize(int localMaxdynamciTableSize) + public int getMaxTableCapacity() + { + return _maxTableCapacity; + } + + /** + *

    Sets the limit for the capacity of the dynamic header table.

    + *

    This value acts as a limit for the values received from the + * remote peer via the HPACK dynamic table size update instruction.

    + *

    After calling this method, a SETTINGS frame must be sent to the other + * peer, containing the {@code SETTINGS_HEADER_TABLE_SIZE} setting with + * the value passed as argument to this method.

    + * + * @param maxTableCapacity the limit for capacity of the dynamic header table + */ + public void setMaxTableCapacity(int maxTableCapacity) + { + _maxTableCapacity = maxTableCapacity; + } + + /** + * @param maxTableSizeLimit the local dynamic table max size + * @deprecated use {@link #setMaxTableCapacity(int)} instead + */ + @Deprecated + public void setLocalMaxDynamicTableSize(int maxTableSizeLimit) { - _localMaxDynamicTableSize = localMaxdynamciTableSize; + setMaxTableCapacity(maxTableSizeLimit); + } + + public int getMaxHeaderListSize() + { + return _builder.getMaxSize(); + } + + public void setMaxHeaderListSize(int maxHeaderListSize) + { + _builder.setMaxSize(maxHeaderListSize); } public MetaData decode(ByteBuffer buffer) throws HpackException.SessionException, HpackException.StreamException @@ -69,27 +118,22 @@ if (LOG.isDebugEnabled()) LOG.debug(String.format("CtxTbl[%x] decoding %d octets", _context.hashCode(), buffer.remaining())); - // If the buffer is big, don't even think about decoding it - if (buffer.remaining() > _builder.getMaxSize()) - throw new HpackException.SessionException("431 Request Header Fields too large"); + // If the buffer is larger than the max headers size, don't even start decoding it. + int maxSize = _builder.getMaxSize(); + if (maxSize > 0 && buffer.remaining() > maxSize) + throw new HpackException.SessionException("Header fields size too large"); boolean emitted = false; - while (buffer.hasRemaining()) { - if (LOG.isDebugEnabled() && buffer.hasArray()) - { - int l = Math.min(buffer.remaining(), 32); - LOG.debug("decode {}{}", - TypeUtil.toHexString(buffer.array(), buffer.arrayOffset() + buffer.position(), l), - l < buffer.remaining() ? "..." : ""); - } + if (LOG.isDebugEnabled()) + LOG.debug("decode {}", BufferUtil.toHexString(buffer)); byte b = buffer.get(); if (b < 0) { // 7.1 indexed if the high bit is set - int index = NBitInteger.decode(buffer, 7); + int index = integerDecode(buffer, 7); Entry entry = _context.get(index); if (entry == null) throw new HpackException.SessionException("Unknown index %d", index); @@ -130,11 +174,11 @@ case 2: // 7.3 case 3: // 7.3 // change table size - int size = NBitInteger.decode(buffer, 5); + int size = integerDecode(buffer, 5); if (LOG.isDebugEnabled()) - LOG.debug("decode resize=" + size); - if (size > _localMaxDynamicTableSize) - throw new IllegalArgumentException(); + LOG.debug("decode resize={}", size); + if (size > getMaxTableCapacity()) + throw new HpackException.CompressionException("Dynamic table resize exceeded max limit"); if (emitted) throw new HpackException.CompressionException("Dynamic table resize after fields"); _context.resize(size); @@ -143,7 +187,7 @@ case 0: // 7.2.2 case 1: // 7.2.3 indexed = false; - nameIndex = NBitInteger.decode(buffer, 4); + nameIndex = integerDecode(buffer, 4); break; case 4: // 7.2.1 @@ -151,7 +195,7 @@ case 6: // 7.2.1 case 7: // 7.2.1 indexed = true; - nameIndex = NBitInteger.decode(buffer, 6); + nameIndex = integerDecode(buffer, 6); break; default: @@ -170,12 +214,11 @@ else { huffmanName = (buffer.get() & 0x80) == 0x80; - int length = NBitInteger.decode(buffer, 7); - _builder.checkSize(length, huffmanName); + int length = integerDecode(buffer, 7); if (huffmanName) - name = Huffman.decode(buffer, length); + name = huffmanDecode(buffer, length); else - name = toASCIIString(buffer, length); + name = toISO88591String(buffer, length); check: for (int i = name.length(); i-- > 0; ) { @@ -211,12 +254,11 @@ // decode the value boolean huffmanValue = (buffer.get() & 0x80) == 0x80; - int length = NBitInteger.decode(buffer, 7); - _builder.checkSize(length, huffmanValue); + int length = integerDecode(buffer, 7); if (huffmanValue) - value = Huffman.decode(buffer, length); + value = huffmanDecode(buffer, length); else - value = toASCIIString(buffer, length); + value = toISO88591String(buffer, length); // Make the new field HttpField field; @@ -277,19 +319,61 @@ return _builder.build(); } - public static String toASCIIString(ByteBuffer buffer, int length) + private int integerDecode(ByteBuffer buffer, int prefix) throws HpackException.CompressionException + { + try + { + if (prefix != 8) + buffer.position(buffer.position() - 1); + + _integerDecoder.setPrefix(prefix); + int decodedInt = _integerDecoder.decodeInt(buffer); + if (decodedInt < 0) + throw new EncodingException("invalid integer encoding"); + return decodedInt; + } + catch (EncodingException e) + { + HpackException.CompressionException compressionException = new HpackException.CompressionException(e.getMessage()); + compressionException.initCause(e); + throw compressionException; + } + finally + { + _integerDecoder.reset(); + } + } + + private String huffmanDecode(ByteBuffer buffer, int length) throws HpackException.CompressionException + { + try + { + _huffmanDecoder.setLength(length); + String decoded = _huffmanDecoder.decode(buffer); + if (decoded == null) + throw new HpackException.CompressionException("invalid string encoding"); + return decoded; + } + catch (EncodingException e) + { + HpackException.CompressionException compressionException = new HpackException.CompressionException(e.getMessage()); + compressionException.initCause(e); + throw compressionException; + } + finally + { + _huffmanDecoder.reset(); + } + } + + public static String toISO88591String(ByteBuffer buffer, int length) { - StringBuilder builder = new StringBuilder(length); - int position = buffer.position(); - int start = buffer.arrayOffset() + position; - int end = start + length; - buffer.position(position + length); - byte[] array = buffer.array(); - for (int i = start; i < end; i++) + CharsetStringBuilder.Iso88591StringBuilder builder = new CharsetStringBuilder.Iso88591StringBuilder(); + for (int i = 0; i < length; ++i) { - builder.append((char)(0x7f & array[i])); + builder.append(HttpTokens.sanitizeFieldVchar((char)buffer.get())); } - return builder.toString(); + return builder.build(); } @Override diff -Nru jetty9-9.4.50/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackEncoder.java jetty9-9.4.57/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackEncoder.java --- jetty9-9.4.50/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackEncoder.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackEncoder.java 2024-12-19 21:51:26.000000000 +0000 @@ -19,7 +19,6 @@ package org.eclipse.jetty.http2.hpack; import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; import java.util.EnumMap; import java.util.EnumSet; import java.util.HashSet; @@ -34,10 +33,13 @@ import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http.PreEncodedHttpField; +import org.eclipse.jetty.http.compression.HuffmanEncoder; +import org.eclipse.jetty.http.compression.NBitIntegerEncoder; +import org.eclipse.jetty.http.compression.NBitStringEncoder; import org.eclipse.jetty.http2.hpack.HpackContext.Entry; import org.eclipse.jetty.http2.hpack.HpackContext.StaticEntry; +import org.eclipse.jetty.util.BufferUtil; 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; @@ -97,34 +99,79 @@ private final HpackContext _context; private final boolean _debug; - private int _remoteMaxDynamicTableSize; - private int _localMaxDynamicTableSize; + private int _maxTableCapacity; + private int _tableCapacity; private int _maxHeaderListSize; private int _headerListSize; private boolean _validateEncoding = true; + private boolean _maxDynamicTableSizeSent = false; - public HpackEncoder() - { - this(4096, 4096, -1); - } - + @Deprecated public HpackEncoder(int localMaxDynamicTableSize) { this(localMaxDynamicTableSize, 4096, -1); } + @Deprecated public HpackEncoder(int localMaxDynamicTableSize, int remoteMaxDynamicTableSize) { this(localMaxDynamicTableSize, remoteMaxDynamicTableSize, -1); } + @Deprecated public HpackEncoder(int localMaxDynamicTableSize, int remoteMaxDynamicTableSize, int maxHeaderListSize) { - _context = new HpackContext(remoteMaxDynamicTableSize); - _remoteMaxDynamicTableSize = remoteMaxDynamicTableSize; - _localMaxDynamicTableSize = localMaxDynamicTableSize; - _maxHeaderListSize = maxHeaderListSize; + this(); + setLocalMaxDynamicTableSize(localMaxDynamicTableSize); + setRemoteMaxDynamicTableSize(remoteMaxDynamicTableSize); + setMaxHeaderListSize(maxHeaderListSize); + } + + public HpackEncoder() + { + _context = new HpackContext(HpackContext.DEFAULT_MAX_TABLE_CAPACITY); _debug = LOG.isDebugEnabled(); + setMaxTableCapacity(HpackContext.DEFAULT_MAX_TABLE_CAPACITY); + setTableCapacity(HpackContext.DEFAULT_MAX_TABLE_CAPACITY); + } + + public int getMaxTableCapacity() + { + return _maxTableCapacity; + } + + /** + *

    Sets the limit for the capacity of the dynamic header table.

    + *

    This value is set by the remote peer via the + * {@code SETTINGS_HEADER_TABLE_SIZE} setting.

    + * + * @param maxTableSizeLimit the limit for capacity of the dynamic header table + */ + public void setMaxTableCapacity(int maxTableSizeLimit) + { + _maxTableCapacity = maxTableSizeLimit; + } + + public int getTableCapacity() + { + return _tableCapacity; + } + + /** + *

    Sets the capacity of the dynamic header table.

    + *

    The value of the capacity may be changed from {@code 0} + * up to {@link #getMaxTableCapacity()}. + * An HPACK instruction with the new capacity value will + * be sent to the decoder when the next call to + * {@link #encode(ByteBuffer, MetaData)} is made.

    + * + * @param tableCapacity the capacity of the dynamic header table + */ + public void setTableCapacity(int tableCapacity) + { + if (tableCapacity > getMaxTableCapacity()) + throw new IllegalArgumentException("Max table capacity exceeded"); + _tableCapacity = tableCapacity; } public int getMaxHeaderListSize() @@ -142,14 +189,16 @@ return _context; } - public void setRemoteMaxDynamicTableSize(int remoteMaxDynamicTableSize) + @Deprecated + public void setRemoteMaxDynamicTableSize(int maxTableSize) { - _remoteMaxDynamicTableSize = remoteMaxDynamicTableSize; + setTableCapacity(maxTableSize); } - public void setLocalMaxDynamicTableSize(int localMaxDynamicTableSize) + @Deprecated + public void setLocalMaxDynamicTableSize(int maxTableSizeLimit) { - _localMaxDynamicTableSize = localMaxDynamicTableSize; + setMaxTableCapacity(maxTableSizeLimit); } public boolean isValidateEncoding() @@ -185,10 +234,13 @@ _headerListSize = 0; int pos = buffer.position(); - // Check the dynamic table sizes! - int maxDynamicTableSize = Math.min(_remoteMaxDynamicTableSize, _localMaxDynamicTableSize); - if (maxDynamicTableSize != _context.getMaxDynamicTableSize()) - encodeMaxDynamicTableSize(buffer, maxDynamicTableSize); + // If max table size changed, send the correspondent instruction. + int tableCapacity = getTableCapacity(); + if (!_maxDynamicTableSizeSent || tableCapacity != _context.getMaxDynamicTableSize()) + { + _maxDynamicTableSizeSent = true; + encodeMaxDynamicTableSize(buffer, tableCapacity); + } // Add Request/response meta fields if (metadata.isRequest()) @@ -255,13 +307,9 @@ } } - // Check size - if (_maxHeaderListSize > 0 && _headerListSize > _maxHeaderListSize) - { - LOG.warn("Header list size too large {} > {} for {}", _headerListSize, _maxHeaderListSize); - if (LOG.isDebugEnabled()) - LOG.debug("metadata={}", metadata); - } + int maxHeaderListSize = getMaxHeaderListSize(); + if (maxHeaderListSize > 0 && _headerListSize > maxHeaderListSize) + throw new HpackException.SessionException("Header size %d > %d", _headerListSize, maxHeaderListSize); if (LOG.isDebugEnabled()) LOG.debug(String.format("CtxTbl[%x] encoded %d octets", _context.hashCode(), buffer.position() - pos)); @@ -278,13 +326,11 @@ } } - public void encodeMaxDynamicTableSize(ByteBuffer buffer, int maxDynamicTableSize) + public void encodeMaxDynamicTableSize(ByteBuffer buffer, int maxTableSize) { - if (maxDynamicTableSize > _remoteMaxDynamicTableSize) - throw new IllegalArgumentException(); buffer.put((byte)0x20); - NBitInteger.encode(buffer, 5, maxDynamicTableSize); - _context.resize(maxDynamicTableSize); + NBitIntegerEncoder.encode(buffer, 5, maxTableSize); + _context.resize(maxTableSize); } public void encode(ByteBuffer buffer, HttpField field) @@ -295,8 +341,6 @@ int fieldSize = field.getName().length() + field.getValue().length(); _headerListSize += fieldSize + 32; - final int p = _debug ? buffer.position() : -1; - String encoding = null; // Is there an index entry for the field? @@ -314,9 +358,9 @@ { int index = _context.index(entry); buffer.put((byte)0x80); - NBitInteger.encode(buffer, 7, index); + NBitIntegerEncoder.encode(buffer, 7, index); if (_debug) - encoding = "IdxField" + (entry.isStatic() ? "S" : "") + (1 + NBitInteger.octectsNeeded(7, index)); + encoding = "IdxField" + (entry.isStatic() ? "S" : "") + NBitIntegerEncoder.octetsNeeded(7, index); } } else @@ -390,19 +434,19 @@ if (_debug) encoding = "Lit" + - ((name == null) ? "HuffN" : ("IdxN" + (name.isStatic() ? "S" : "") + (1 + NBitInteger.octectsNeeded(4, _context.index(name))))) + + ((name == null) ? "HuffN" : ("IdxN" + (name.isStatic() ? "S" : "") + (1 + NBitIntegerEncoder.octetsNeeded(4, _context.index(name))))) + (huffman ? "HuffV" : "LitV") + (neverIndex ? "!!Idx" : "!Idx"); } else if (fieldSize >= _context.getMaxDynamicTableSize() || header == HttpHeader.CONTENT_LENGTH && !"0".equals(field.getValue())) { - // The field is too large or a non zero content length, so do not index. + // The field is too large or a non-zero content length, so do not index. indexed = false; encodeName(buffer, (byte)0x00, 4, header.asString(), name); encodeValue(buffer, true, field.getValue()); if (_debug) encoding = "Lit" + - ((name == null) ? "HuffN" : "IdxNS" + (1 + NBitInteger.octectsNeeded(4, _context.index(name)))) + + ((name == null) ? "HuffN" : "IdxNS" + (1 + NBitIntegerEncoder.octetsNeeded(4, _context.index(name)))) + "HuffV!Idx"; } else @@ -413,7 +457,7 @@ encodeName(buffer, (byte)0x40, 6, header.asString(), name); encodeValue(buffer, huffman, field.getValue()); if (_debug) - encoding = ((name == null) ? "LitHuffN" : ("LitIdxN" + (name.isStatic() ? "S" : "") + (1 + NBitInteger.octectsNeeded(6, _context.index(name))))) + + encoding = ((name == null) ? "LitHuffN" : ("LitIdxN" + (name.isStatic() ? "S" : "") + (1 + NBitIntegerEncoder.octetsNeeded(6, _context.index(name))))) + (huffman ? "HuffVIdx" : "LitVIdx"); } } @@ -425,10 +469,8 @@ if (_debug) { - byte[] bytes = new byte[buffer.position() - p]; - buffer.position(p); - buffer.get(bytes); - LOG.debug("encode {}:'{}' to '{}'", encoding, field, TypeUtil.toHexString(bytes)); + if (LOG.isDebugEnabled()) + LOG.debug("encode {}:'{}' to '{}'", encoding, field, BufferUtil.toHexString((ByteBuffer)buffer.duplicate().flip())); } } @@ -440,55 +482,17 @@ // leave name index bits as 0 // Encode the name always with lowercase huffman buffer.put((byte)0x80); - NBitInteger.encode(buffer, 7, Huffman.octetsNeededLC(name)); - Huffman.encodeLC(buffer, name); + NBitIntegerEncoder.encode(buffer, 7, HuffmanEncoder.octetsNeededLowerCase(name)); + HuffmanEncoder.encodeLowerCase(buffer, name); } else { - NBitInteger.encode(buffer, bits, _context.index(entry)); + NBitIntegerEncoder.encode(buffer, bits, _context.index(entry)); } } static void encodeValue(ByteBuffer buffer, boolean huffman, String value) { - if (huffman) - { - // huffman literal value - buffer.put((byte)0x80); - - int needed = Huffman.octetsNeeded(value); - if (needed >= 0) - { - NBitInteger.encode(buffer, 7, needed); - Huffman.encode(buffer, value); - } - else - { - // Not iso_8859_1 - byte[] bytes = value.getBytes(StandardCharsets.UTF_8); - NBitInteger.encode(buffer, 7, Huffman.octetsNeeded(bytes)); - Huffman.encode(buffer, bytes); - } - } - else - { - // add literal assuming iso_8859_1 - buffer.put((byte)0x00).mark(); - NBitInteger.encode(buffer, 7, value.length()); - for (int i = 0; i < value.length(); i++) - { - char c = value.charAt(i); - if (c < ' ' || c > 127) - { - // Not iso_8859_1, so re-encode as UTF-8 - buffer.reset(); - byte[] bytes = value.getBytes(StandardCharsets.UTF_8); - NBitInteger.encode(buffer, 7, bytes.length); - buffer.put(bytes, 0, bytes.length); - return; - } - buffer.put((byte)c); - } - } + NBitStringEncoder.encode(buffer, 8, value, huffman); } } diff -Nru jetty9-9.4.50/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackException.java jetty9-9.4.57/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackException.java --- jetty9-9.4.50/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackException.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackException.java 2024-12-19 21:51:26.000000000 +0000 @@ -18,7 +18,6 @@ package org.eclipse.jetty.http2.hpack; -@SuppressWarnings("serial") public abstract class HpackException extends Exception { HpackException(String messageFormat, Object... args) @@ -35,7 +34,7 @@ */ public static class StreamException extends HpackException { - StreamException(String messageFormat, Object... args) + public StreamException(String messageFormat, Object... args) { super(messageFormat, args); } @@ -48,7 +47,7 @@ */ public static class SessionException extends HpackException { - SessionException(String messageFormat, Object... args) + public SessionException(String messageFormat, Object... args) { super(messageFormat, args); } diff -Nru jetty9-9.4.50/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackFieldPreEncoder.java jetty9-9.4.57/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackFieldPreEncoder.java --- jetty9-9.4.50/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackFieldPreEncoder.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackFieldPreEncoder.java 2024-12-19 21:51:26.000000000 +0000 @@ -23,6 +23,8 @@ import org.eclipse.jetty.http.HttpFieldPreEncoder; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.http.compression.HuffmanEncoder; +import org.eclipse.jetty.http.compression.NBitIntegerEncoder; import org.eclipse.jetty.util.BufferUtil; /** @@ -31,18 +33,12 @@ public class HpackFieldPreEncoder implements HttpFieldPreEncoder { - /** - * @see org.eclipse.jetty.http.HttpFieldPreEncoder#getHttpVersion() - */ @Override public HttpVersion getHttpVersion() { return HttpVersion.HTTP_2; } - /** - * @see org.eclipse.jetty.http.HttpFieldPreEncoder#getEncodedField(org.eclipse.jetty.http.HttpHeader, java.lang.String, java.lang.String) - */ @Override public byte[] getEncodedField(HttpHeader header, String name, String value) { @@ -78,12 +74,12 @@ int nameIdx = HpackContext.staticIndex(header); if (nameIdx > 0) - NBitInteger.encode(buffer, bits, nameIdx); + NBitIntegerEncoder.encode(buffer, bits, nameIdx); else { buffer.put((byte)0x80); - NBitInteger.encode(buffer, 7, Huffman.octetsNeededLC(name)); - Huffman.encodeLC(buffer, name); + NBitIntegerEncoder.encode(buffer, 7, HuffmanEncoder.octetsNeededLowerCase(name)); + HuffmanEncoder.encodeLowerCase(buffer, name); } HpackEncoder.encodeValue(buffer, huffman, value); diff -Nru jetty9-9.4.50/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/Huffman.java jetty9-9.4.57/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/Huffman.java --- jetty9-9.4.50/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/Huffman.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/Huffman.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,551 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// ------------------------------------------------------------------------ -// 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.http2.hpack; - -import java.nio.ByteBuffer; - -import org.eclipse.jetty.util.Utf8StringBuilder; - -public class Huffman -{ - - // Appendix C: Huffman Codes - // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-12#appendix-C - static final int[][] CODES = - { - /* ( 0) |11111111|11000 */ {0x1ff8, 13}, - /* ( 1) |11111111|11111111|1011000 */ {0x7fffd8, 23}, - /* ( 2) |11111111|11111111|11111110|0010 */ {0xfffffe2, 28}, - /* ( 3) |11111111|11111111|11111110|0011 */ {0xfffffe3, 28}, - /* ( 4) |11111111|11111111|11111110|0100 */ {0xfffffe4, 28}, - /* ( 5) |11111111|11111111|11111110|0101 */ {0xfffffe5, 28}, - /* ( 6) |11111111|11111111|11111110|0110 */ {0xfffffe6, 28}, - /* ( 7) |11111111|11111111|11111110|0111 */ {0xfffffe7, 28}, - /* ( 8) |11111111|11111111|11111110|1000 */ {0xfffffe8, 28}, - /* ( 9) |11111111|11111111|11101010 */ {0xffffea, 24}, - /* ( 10) |11111111|11111111|11111111|111100 */ {0x3ffffffc, 30}, - /* ( 11) |11111111|11111111|11111110|1001 */ {0xfffffe9, 28}, - /* ( 12) |11111111|11111111|11111110|1010 */ {0xfffffea, 28}, - /* ( 13) |11111111|11111111|11111111|111101 */ {0x3ffffffd, 30}, - /* ( 14) |11111111|11111111|11111110|1011 */ {0xfffffeb, 28}, - /* ( 15) |11111111|11111111|11111110|1100 */ {0xfffffec, 28}, - /* ( 16) |11111111|11111111|11111110|1101 */ {0xfffffed, 28}, - /* ( 17) |11111111|11111111|11111110|1110 */ {0xfffffee, 28}, - /* ( 18) |11111111|11111111|11111110|1111 */ {0xfffffef, 28}, - /* ( 19) |11111111|11111111|11111111|0000 */ {0xffffff0, 28}, - /* ( 20) |11111111|11111111|11111111|0001 */ {0xffffff1, 28}, - /* ( 21) |11111111|11111111|11111111|0010 */ {0xffffff2, 28}, - /* ( 22) |11111111|11111111|11111111|111110 */ {0x3ffffffe, 30}, - /* ( 23) |11111111|11111111|11111111|0011 */ {0xffffff3, 28}, - /* ( 24) |11111111|11111111|11111111|0100 */ {0xffffff4, 28}, - /* ( 25) |11111111|11111111|11111111|0101 */ {0xffffff5, 28}, - /* ( 26) |11111111|11111111|11111111|0110 */ {0xffffff6, 28}, - /* ( 27) |11111111|11111111|11111111|0111 */ {0xffffff7, 28}, - /* ( 28) |11111111|11111111|11111111|1000 */ {0xffffff8, 28}, - /* ( 29) |11111111|11111111|11111111|1001 */ {0xffffff9, 28}, - /* ( 30) |11111111|11111111|11111111|1010 */ {0xffffffa, 28}, - /* ( 31) |11111111|11111111|11111111|1011 */ {0xffffffb, 28}, - /*' ' ( 32) |010100 */ {0x14, 6}, - /*'!' ( 33) |11111110|00 */ {0x3f8, 10}, - /*'"' ( 34) |11111110|01 */ {0x3f9, 10}, - /*'#' ( 35) |11111111|1010 */ {0xffa, 12}, - /*'$' ( 36) |11111111|11001 */ {0x1ff9, 13}, - /*'%' ( 37) |010101 */ {0x15, 6}, - /*'&' ( 38) |11111000 */ {0xf8, 8}, - /*''' ( 39) |11111111|010 */ {0x7fa, 11}, - /*'(' ( 40) |11111110|10 */ {0x3fa, 10}, - /*')' ( 41) |11111110|11 */ {0x3fb, 10}, - /*'*' ( 42) |11111001 */ {0xf9, 8}, - /*'+' ( 43) |11111111|011 */ {0x7fb, 11}, - /*',' ( 44) |11111010 */ {0xfa, 8}, - /*'-' ( 45) |010110 */ {0x16, 6}, - /*'.' ( 46) |010111 */ {0x17, 6}, - /*'/' ( 47) |011000 */ {0x18, 6}, - /*'0' ( 48) |00000 */ {0x0, 5}, - /*'1' ( 49) |00001 */ {0x1, 5}, - /*'2' ( 50) |00010 */ {0x2, 5}, - /*'3' ( 51) |011001 */ {0x19, 6}, - /*'4' ( 52) |011010 */ {0x1a, 6}, - /*'5' ( 53) |011011 */ {0x1b, 6}, - /*'6' ( 54) |011100 */ {0x1c, 6}, - /*'7' ( 55) |011101 */ {0x1d, 6}, - /*'8' ( 56) |011110 */ {0x1e, 6}, - /*'9' ( 57) |011111 */ {0x1f, 6}, - /*':' ( 58) |1011100 */ {0x5c, 7}, - /*';' ( 59) |11111011 */ {0xfb, 8}, - /*'<' ( 60) |11111111|1111100 */ {0x7ffc, 15}, - /*'=' ( 61) |100000 */ {0x20, 6}, - /*'>' ( 62) |11111111|1011 */ {0xffb, 12}, - /*'?' ( 63) |11111111|00 */ {0x3fc, 10}, - /*'@' ( 64) |11111111|11010 */ {0x1ffa, 13}, - /*'A' ( 65) |100001 */ {0x21, 6}, - /*'B' ( 66) |1011101 */ {0x5d, 7}, - /*'C' ( 67) |1011110 */ {0x5e, 7}, - /*'D' ( 68) |1011111 */ {0x5f, 7}, - /*'E' ( 69) |1100000 */ {0x60, 7}, - /*'F' ( 70) |1100001 */ {0x61, 7}, - /*'G' ( 71) |1100010 */ {0x62, 7}, - /*'H' ( 72) |1100011 */ {0x63, 7}, - /*'I' ( 73) |1100100 */ {0x64, 7}, - /*'J' ( 74) |1100101 */ {0x65, 7}, - /*'K' ( 75) |1100110 */ {0x66, 7}, - /*'L' ( 76) |1100111 */ {0x67, 7}, - /*'M' ( 77) |1101000 */ {0x68, 7}, - /*'N' ( 78) |1101001 */ {0x69, 7}, - /*'O' ( 79) |1101010 */ {0x6a, 7}, - /*'P' ( 80) |1101011 */ {0x6b, 7}, - /*'Q' ( 81) |1101100 */ {0x6c, 7}, - /*'R' ( 82) |1101101 */ {0x6d, 7}, - /*'S' ( 83) |1101110 */ {0x6e, 7}, - /*'T' ( 84) |1101111 */ {0x6f, 7}, - /*'U' ( 85) |1110000 */ {0x70, 7}, - /*'V' ( 86) |1110001 */ {0x71, 7}, - /*'W' ( 87) |1110010 */ {0x72, 7}, - /*'X' ( 88) |11111100 */ {0xfc, 8}, - /*'Y' ( 89) |1110011 */ {0x73, 7}, - /*'Z' ( 90) |11111101 */ {0xfd, 8}, - /*'[' ( 91) |11111111|11011 */ {0x1ffb, 13}, - /*'\' ( 92) |11111111|11111110|000 */ {0x7fff0, 19}, - /*']' ( 93) |11111111|11100 */ {0x1ffc, 13}, - /*'^' ( 94) |11111111|111100 */ {0x3ffc, 14}, - /*'_' ( 95) |100010 */ {0x22, 6}, - /*'`' ( 96) |11111111|1111101 */ {0x7ffd, 15}, - /*'a' ( 97) |00011 */ {0x3, 5}, - /*'b' ( 98) |100011 */ {0x23, 6}, - /*'c' ( 99) |00100 */ {0x4, 5}, - /*'d' (100) |100100 */ {0x24, 6}, - /*'e' (101) |00101 */ {0x5, 5}, - /*'f' (102) |100101 */ {0x25, 6}, - /*'g' (103) |100110 */ {0x26, 6}, - /*'h' (104) |100111 */ {0x27, 6}, - /*'i' (105) |00110 */ {0x6, 5}, - /*'j' (106) |1110100 */ {0x74, 7}, - /*'k' (107) |1110101 */ {0x75, 7}, - /*'l' (108) |101000 */ {0x28, 6}, - /*'m' (109) |101001 */ {0x29, 6}, - /*'n' (110) |101010 */ {0x2a, 6}, - /*'o' (111) |00111 */ {0x7, 5}, - /*'p' (112) |101011 */ {0x2b, 6}, - /*'q' (113) |1110110 */ {0x76, 7}, - /*'r' (114) |101100 */ {0x2c, 6}, - /*'s' (115) |01000 */ {0x8, 5}, - /*'t' (116) |01001 */ {0x9, 5}, - /*'u' (117) |101101 */ {0x2d, 6}, - /*'v' (118) |1110111 */ {0x77, 7}, - /*'w' (119) |1111000 */ {0x78, 7}, - /*'x' (120) |1111001 */ {0x79, 7}, - /*'y' (121) |1111010 */ {0x7a, 7}, - /*'z' (122) |1111011 */ {0x7b, 7}, - /*'{' (123) |11111111|1111110 */ {0x7ffe, 15}, - /*'|' (124) |11111111|100 */ {0x7fc, 11}, - /*'}' (125) |11111111|111101 */ {0x3ffd, 14}, - /*'~' (126) |11111111|11101 */ {0x1ffd, 13}, - /* (127) |11111111|11111111|11111111|1100 */ {0xffffffc, 28}, - /* (128) |11111111|11111110|0110 */ {0xfffe6, 20}, - /* (129) |11111111|11111111|010010 */ {0x3fffd2, 22}, - /* (130) |11111111|11111110|0111 */ {0xfffe7, 20}, - /* (131) |11111111|11111110|1000 */ {0xfffe8, 20}, - /* (132) |11111111|11111111|010011 */ {0x3fffd3, 22}, - /* (133) |11111111|11111111|010100 */ {0x3fffd4, 22}, - /* (134) |11111111|11111111|010101 */ {0x3fffd5, 22}, - /* (135) |11111111|11111111|1011001 */ {0x7fffd9, 23}, - /* (136) |11111111|11111111|010110 */ {0x3fffd6, 22}, - /* (137) |11111111|11111111|1011010 */ {0x7fffda, 23}, - /* (138) |11111111|11111111|1011011 */ {0x7fffdb, 23}, - /* (139) |11111111|11111111|1011100 */ {0x7fffdc, 23}, - /* (140) |11111111|11111111|1011101 */ {0x7fffdd, 23}, - /* (141) |11111111|11111111|1011110 */ {0x7fffde, 23}, - /* (142) |11111111|11111111|11101011 */ {0xffffeb, 24}, - /* (143) |11111111|11111111|1011111 */ {0x7fffdf, 23}, - /* (144) |11111111|11111111|11101100 */ {0xffffec, 24}, - /* (145) |11111111|11111111|11101101 */ {0xffffed, 24}, - /* (146) |11111111|11111111|010111 */ {0x3fffd7, 22}, - /* (147) |11111111|11111111|1100000 */ {0x7fffe0, 23}, - /* (148) |11111111|11111111|11101110 */ {0xffffee, 24}, - /* (149) |11111111|11111111|1100001 */ {0x7fffe1, 23}, - /* (150) |11111111|11111111|1100010 */ {0x7fffe2, 23}, - /* (151) |11111111|11111111|1100011 */ {0x7fffe3, 23}, - /* (152) |11111111|11111111|1100100 */ {0x7fffe4, 23}, - /* (153) |11111111|11111110|11100 */ {0x1fffdc, 21}, - /* (154) |11111111|11111111|011000 */ {0x3fffd8, 22}, - /* (155) |11111111|11111111|1100101 */ {0x7fffe5, 23}, - /* (156) |11111111|11111111|011001 */ {0x3fffd9, 22}, - /* (157) |11111111|11111111|1100110 */ {0x7fffe6, 23}, - /* (158) |11111111|11111111|1100111 */ {0x7fffe7, 23}, - /* (159) |11111111|11111111|11101111 */ {0xffffef, 24}, - /* (160) |11111111|11111111|011010 */ {0x3fffda, 22}, - /* (161) |11111111|11111110|11101 */ {0x1fffdd, 21}, - /* (162) |11111111|11111110|1001 */ {0xfffe9, 20}, - /* (163) |11111111|11111111|011011 */ {0x3fffdb, 22}, - /* (164) |11111111|11111111|011100 */ {0x3fffdc, 22}, - /* (165) |11111111|11111111|1101000 */ {0x7fffe8, 23}, - /* (166) |11111111|11111111|1101001 */ {0x7fffe9, 23}, - /* (167) |11111111|11111110|11110 */ {0x1fffde, 21}, - /* (168) |11111111|11111111|1101010 */ {0x7fffea, 23}, - /* (169) |11111111|11111111|011101 */ {0x3fffdd, 22}, - /* (170) |11111111|11111111|011110 */ {0x3fffde, 22}, - /* (171) |11111111|11111111|11110000 */ {0xfffff0, 24}, - /* (172) |11111111|11111110|11111 */ {0x1fffdf, 21}, - /* (173) |11111111|11111111|011111 */ {0x3fffdf, 22}, - /* (174) |11111111|11111111|1101011 */ {0x7fffeb, 23}, - /* (175) |11111111|11111111|1101100 */ {0x7fffec, 23}, - /* (176) |11111111|11111111|00000 */ {0x1fffe0, 21}, - /* (177) |11111111|11111111|00001 */ {0x1fffe1, 21}, - /* (178) |11111111|11111111|100000 */ {0x3fffe0, 22}, - /* (179) |11111111|11111111|00010 */ {0x1fffe2, 21}, - /* (180) |11111111|11111111|1101101 */ {0x7fffed, 23}, - /* (181) |11111111|11111111|100001 */ {0x3fffe1, 22}, - /* (182) |11111111|11111111|1101110 */ {0x7fffee, 23}, - /* (183) |11111111|11111111|1101111 */ {0x7fffef, 23}, - /* (184) |11111111|11111110|1010 */ {0xfffea, 20}, - /* (185) |11111111|11111111|100010 */ {0x3fffe2, 22}, - /* (186) |11111111|11111111|100011 */ {0x3fffe3, 22}, - /* (187) |11111111|11111111|100100 */ {0x3fffe4, 22}, - /* (188) |11111111|11111111|1110000 */ {0x7ffff0, 23}, - /* (189) |11111111|11111111|100101 */ {0x3fffe5, 22}, - /* (190) |11111111|11111111|100110 */ {0x3fffe6, 22}, - /* (191) |11111111|11111111|1110001 */ {0x7ffff1, 23}, - /* (192) |11111111|11111111|11111000|00 */ {0x3ffffe0, 26}, - /* (193) |11111111|11111111|11111000|01 */ {0x3ffffe1, 26}, - /* (194) |11111111|11111110|1011 */ {0xfffeb, 20}, - /* (195) |11111111|11111110|001 */ {0x7fff1, 19}, - /* (196) |11111111|11111111|100111 */ {0x3fffe7, 22}, - /* (197) |11111111|11111111|1110010 */ {0x7ffff2, 23}, - /* (198) |11111111|11111111|101000 */ {0x3fffe8, 22}, - /* (199) |11111111|11111111|11110110|0 */ {0x1ffffec, 25}, - /* (200) |11111111|11111111|11111000|10 */ {0x3ffffe2, 26}, - /* (201) |11111111|11111111|11111000|11 */ {0x3ffffe3, 26}, - /* (202) |11111111|11111111|11111001|00 */ {0x3ffffe4, 26}, - /* (203) |11111111|11111111|11111011|110 */ {0x7ffffde, 27}, - /* (204) |11111111|11111111|11111011|111 */ {0x7ffffdf, 27}, - /* (205) |11111111|11111111|11111001|01 */ {0x3ffffe5, 26}, - /* (206) |11111111|11111111|11110001 */ {0xfffff1, 24}, - /* (207) |11111111|11111111|11110110|1 */ {0x1ffffed, 25}, - /* (208) |11111111|11111110|010 */ {0x7fff2, 19}, - /* (209) |11111111|11111111|00011 */ {0x1fffe3, 21}, - /* (210) |11111111|11111111|11111001|10 */ {0x3ffffe6, 26}, - /* (211) |11111111|11111111|11111100|000 */ {0x7ffffe0, 27}, - /* (212) |11111111|11111111|11111100|001 */ {0x7ffffe1, 27}, - /* (213) |11111111|11111111|11111001|11 */ {0x3ffffe7, 26}, - /* (214) |11111111|11111111|11111100|010 */ {0x7ffffe2, 27}, - /* (215) |11111111|11111111|11110010 */ {0xfffff2, 24}, - /* (216) |11111111|11111111|00100 */ {0x1fffe4, 21}, - /* (217) |11111111|11111111|00101 */ {0x1fffe5, 21}, - /* (218) |11111111|11111111|11111010|00 */ {0x3ffffe8, 26}, - /* (219) |11111111|11111111|11111010|01 */ {0x3ffffe9, 26}, - /* (220) |11111111|11111111|11111111|1101 */ {0xffffffd, 28}, - /* (221) |11111111|11111111|11111100|011 */ {0x7ffffe3, 27}, - /* (222) |11111111|11111111|11111100|100 */ {0x7ffffe4, 27}, - /* (223) |11111111|11111111|11111100|101 */ {0x7ffffe5, 27}, - /* (224) |11111111|11111110|1100 */ {0xfffec, 20}, - /* (225) |11111111|11111111|11110011 */ {0xfffff3, 24}, - /* (226) |11111111|11111110|1101 */ {0xfffed, 20}, - /* (227) |11111111|11111111|00110 */ {0x1fffe6, 21}, - /* (228) |11111111|11111111|101001 */ {0x3fffe9, 22}, - /* (229) |11111111|11111111|00111 */ {0x1fffe7, 21}, - /* (230) |11111111|11111111|01000 */ {0x1fffe8, 21}, - /* (231) |11111111|11111111|1110011 */ {0x7ffff3, 23}, - /* (232) |11111111|11111111|101010 */ {0x3fffea, 22}, - /* (233) |11111111|11111111|101011 */ {0x3fffeb, 22}, - /* (234) |11111111|11111111|11110111|0 */ {0x1ffffee, 25}, - /* (235) |11111111|11111111|11110111|1 */ {0x1ffffef, 25}, - /* (236) |11111111|11111111|11110100 */ {0xfffff4, 24}, - /* (237) |11111111|11111111|11110101 */ {0xfffff5, 24}, - /* (238) |11111111|11111111|11111010|10 */ {0x3ffffea, 26}, - /* (239) |11111111|11111111|1110100 */ {0x7ffff4, 23}, - /* (240) |11111111|11111111|11111010|11 */ {0x3ffffeb, 26}, - /* (241) |11111111|11111111|11111100|110 */ {0x7ffffe6, 27}, - /* (242) |11111111|11111111|11111011|00 */ {0x3ffffec, 26}, - /* (243) |11111111|11111111|11111011|01 */ {0x3ffffed, 26}, - /* (244) |11111111|11111111|11111100|111 */ {0x7ffffe7, 27}, - /* (245) |11111111|11111111|11111101|000 */ {0x7ffffe8, 27}, - /* (246) |11111111|11111111|11111101|001 */ {0x7ffffe9, 27}, - /* (247) |11111111|11111111|11111101|010 */ {0x7ffffea, 27}, - /* (248) |11111111|11111111|11111101|011 */ {0x7ffffeb, 27}, - /* (249) |11111111|11111111|11111111|1110 */ {0xffffffe, 28}, - /* (250) |11111111|11111111|11111101|100 */ {0x7ffffec, 27}, - /* (251) |11111111|11111111|11111101|101 */ {0x7ffffed, 27}, - /* (252) |11111111|11111111|11111101|110 */ {0x7ffffee, 27}, - /* (253) |11111111|11111111|11111101|111 */ {0x7ffffef, 27}, - /* (254) |11111111|11111111|11111110|000 */ {0x7fffff0, 27}, - /* (255) |11111111|11111111|11111011|10 */ {0x3ffffee, 26}, - /*EOS (256) |11111111|11111111|11111111|111111 */ {0x3fffffff, 30} - }; - - static final int[][] LCCODES = new int[CODES.length][]; - static final char EOS = 256; - - // Huffman decode tree stored in a flattened char array for good - // locality of reference. - static final char[] tree; - static final char[] rowsym; - static final byte[] rowbits; - - // Build the Huffman lookup tree and LC TABLE - static - { - System.arraycopy(CODES, 0, LCCODES, 0, CODES.length); - for (int i = 'A'; i <= 'Z'; i++) - { - LCCODES[i] = LCCODES['a' + i - 'A']; - } - - int r = 0; - for (int i = 0; i < CODES.length; i++) - { - r += (CODES[i][1] + 7) / 8; - } - tree = new char[r * 256]; - rowsym = new char[r]; - rowbits = new byte[r]; - - r = 0; - for (int sym = 0; sym < CODES.length; sym++) - { - int code = CODES[sym][0]; - int len = CODES[sym][1]; - - int current = 0; - - while (len > 8) - { - len -= 8; - int i = ((code >>> len) & 0xFF); - - int t = current * 256 + i; - current = tree[t]; - if (current == 0) - { - tree[t] = (char)++r; - current = r; - } - } - - int terminal = ++r; - rowsym[r] = (char)sym; - int b = len & 0x07; - int terminalBits = b == 0 ? 8 : b; - - rowbits[r] = (byte)terminalBits; - int shift = 8 - len; - int start = current * 256 + ((code << shift) & 0xFF); - int end = start + (1 << shift); - for (int i = start; i < end; i++) - { - tree[i] = (char)terminal; - } - } - } - - public static String decode(ByteBuffer buffer) throws HpackException.CompressionException - { - return decode(buffer, buffer.remaining()); - } - - public static String decode(ByteBuffer buffer, int length) throws HpackException.CompressionException - { - Utf8StringBuilder utf8 = new Utf8StringBuilder(length * 2); - int node = 0; - int current = 0; - int bits = 0; - - for (int i = 0; i < length; i++) - { - int b = buffer.get() & 0xFF; - current = (current << 8) | b; - bits += 8; - while (bits >= 8) - { - int c = (current >>> (bits - 8)) & 0xFF; - node = tree[node * 256 + c]; - if (rowbits[node] != 0) - { - if (rowsym[node] == EOS) - throw new HpackException.CompressionException("EOS in content"); - - // terminal node - utf8.append((byte)(0xFF & rowsym[node])); - bits -= rowbits[node]; - node = 0; - } - else - { - // non-terminal node - bits -= 8; - } - } - } - - while (bits > 0) - { - int c = (current << (8 - bits)) & 0xFF; - int lastNode = node; - node = tree[node * 256 + c]; - - if (rowbits[node] == 0 || rowbits[node] > bits) - { - int requiredPadding = 0; - for (int i = 0; i < bits; i++) - { - requiredPadding = (requiredPadding << 1) | 1; - } - - if ((c >> (8 - bits)) != requiredPadding) - throw new HpackException.CompressionException("Incorrect padding"); - - node = lastNode; - break; - } - - utf8.append((byte)(0xFF & rowsym[node])); - bits -= rowbits[node]; - node = 0; - } - - if (node != 0) - throw new HpackException.CompressionException("Bad termination"); - - return utf8.toString(); - } - - public static int octetsNeeded(String s) - { - return octetsNeeded(CODES, s); - } - - public static int octetsNeeded(byte[] b) - { - return octetsNeeded(CODES, b); - } - - public static void encode(ByteBuffer buffer, String s) - { - encode(CODES, buffer, s); - } - - public static void encode(ByteBuffer buffer, byte[] b) - { - encode(CODES, buffer, b); - } - - public static int octetsNeededLC(String s) - { - return octetsNeeded(LCCODES, s); - } - - public static void encodeLC(ByteBuffer buffer, String s) - { - encode(LCCODES, buffer, s); - } - - private static int octetsNeeded(final int[][] table, String s) - { - int needed = 0; - int len = s.length(); - for (int i = 0; i < len; i++) - { - char c = s.charAt(i); - if (c >= 128 || c < ' ') - return -1; - needed += table[c][1]; - } - - return (needed + 7) / 8; - } - - private static int octetsNeeded(final int[][] table, byte[] b) - { - int needed = 0; - int len = b.length; - for (int i = 0; i < len; i++) - { - int c = 0xFF & b[i]; - needed += table[c][1]; - } - return (needed + 7) / 8; - } - - /** - * @param table The table to encode by - * @param buffer The buffer to encode to - * @param s The string to encode - */ - private static void encode(final int[][] table, ByteBuffer buffer, String s) - { - long current = 0; - int n = 0; - int len = s.length(); - for (int i = 0; i < len; i++) - { - char c = s.charAt(i); - if (c >= 128 || c < ' ') - throw new IllegalArgumentException(); - int code = table[c][0]; - int bits = table[c][1]; - - current <<= bits; - current |= code; - n += bits; - - while (n >= 8) - { - n -= 8; - buffer.put((byte)(current >> n)); - } - } - - if (n > 0) - { - current <<= (8 - n); - current |= (0xFF >>> n); - buffer.put((byte)(current)); - } - } - - private static void encode(final int[][] table, ByteBuffer buffer, byte[] b) - { - long current = 0; - int n = 0; - - int len = b.length; - for (int i = 0; i < len; i++) - { - int c = 0xFF & b[i]; - int code = table[c][0]; - int bits = table[c][1]; - - current <<= bits; - current |= code; - n += bits; - - while (n >= 8) - { - n -= 8; - buffer.put((byte)(current >> n)); - } - } - - if (n > 0) - { - current <<= (8 - n); - current |= (0xFF >>> n); - buffer.put((byte)(current)); - } - } -} diff -Nru jetty9-9.4.50/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java jetty9-9.4.57/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java --- jetty9-9.4.50/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java 2024-12-19 21:51:26.000000000 +0000 @@ -29,7 +29,7 @@ public class MetaDataBuilder { - private final int _maxSize; + private int _maxSize; private int _size; private Integer _status; private String _method; @@ -60,6 +60,11 @@ return _maxSize; } + public void setMaxSize(int maxSize) + { + _maxSize = maxSize; + } + /** * Get the size. * @@ -70,17 +75,18 @@ return _size; } - public void emit(HttpField field) throws HpackException.SessionException + public void emit(HttpField field) throws SessionException { HttpHeader header = field.getHeader(); String name = field.getName(); - if (name == null || name.length() == 0) - throw new HpackException.SessionException("Header size 0"); + if (name == null || name.isEmpty()) + throw new SessionException("Header size 0"); String value = field.getValue(); int fieldSize = name.length() + (value == null ? 0 : value.length()); _size += fieldSize + 32; - if (_size > _maxSize) - throw new HpackException.SessionException("Header size %d > %d", _size, _maxSize); + int maxSize = getMaxSize(); + if (maxSize > 0 && _size > maxSize) + throw new SessionException("Header size %d > %d", _size, maxSize); if (field instanceof StaticTableHttpField) { @@ -89,7 +95,7 @@ { case C_STATUS: if (checkPseudoHeader(header, _status)) - _status = (Integer)staticField.getStaticValue(); + _status = staticField.getIntValue(); _response = true; break; @@ -157,7 +163,7 @@ case C_PATH: if (checkPseudoHeader(header, _path)) { - if (value != null && value.length() > 0) + if (value != null && !value.isEmpty()) _path = value; else streamException("No Path"); @@ -201,7 +207,7 @@ } } - protected void streamException(String messageFormat, Object... args) + public void streamException(String messageFormat, Object... args) { HpackException.StreamException stream = new HpackException.StreamException(messageFormat, args); if (_streamException == null) @@ -267,23 +273,7 @@ _authority = null; _path = null; _size = 0; - _contentLength = Long.MIN_VALUE; + _contentLength = -1; } } - - /** - * Check that the max size will not be exceeded. - * - * @param length the length - * @param huffman the huffman name - * @throws SessionException in case of size errors - */ - public void checkSize(int length, boolean huffman) throws SessionException - { - // Apply a huffman fudge factor - if (huffman) - length = (length * 4) / 3; - if ((_size + length) > _maxSize) - throw new HpackException.SessionException("Header too large %d > %d", _size + length, _maxSize); - } } diff -Nru jetty9-9.4.50/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/NBitInteger.java jetty9-9.4.57/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/NBitInteger.java --- jetty9-9.4.50/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/NBitInteger.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/NBitInteger.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,151 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// ------------------------------------------------------------------------ -// 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.http2.hpack; - -import java.nio.ByteBuffer; - -public class NBitInteger -{ - public static int octectsNeeded(int n, int i) - { - if (n == 8) - { - int nbits = 0xFF; - i = i - nbits; - if (i < 0) - return 1; - if (i == 0) - return 2; - int lz = Integer.numberOfLeadingZeros(i); - int log = 32 - lz; - return 1 + (log + 6) / 7; - } - - int nbits = 0xFF >>> (8 - n); - i = i - nbits; - if (i < 0) - return 0; - if (i == 0) - return 1; - int lz = Integer.numberOfLeadingZeros(i); - int log = 32 - lz; - return (log + 6) / 7; - } - - public static void encode(ByteBuffer buf, int n, int i) - { - if (n == 8) - { - if (i < 0xFF) - { - buf.put((byte)i); - } - else - { - buf.put((byte)0xFF); - - int length = i - 0xFF; - while (true) - { - if ((length & ~0x7F) == 0) - { - buf.put((byte)length); - return; - } - else - { - buf.put((byte)((length & 0x7F) | 0x80)); - length >>>= 7; - } - } - } - } - else - { - int p = buf.position() - 1; - int bits = 0xFF >>> (8 - n); - - if (i < bits) - { - buf.put(p, (byte)((buf.get(p) & ~bits) | i)); - } - else - { - buf.put(p, (byte)(buf.get(p) | bits)); - - int length = i - bits; - while (true) - { - if ((length & ~0x7F) == 0) - { - buf.put((byte)length); - return; - } - else - { - buf.put((byte)((length & 0x7F) | 0x80)); - length >>>= 7; - } - } - } - } - } - - public static int decode(ByteBuffer buffer, int n) - { - if (n == 8) - { - int nbits = 0xFF; - - int i = buffer.get() & 0xff; - - if (i == nbits) - { - int m = 1; - int b; - do - { - b = 0xff & buffer.get(); - i = i + (b & 127) * m; - m = m * 128; - } - while ((b & 128) == 128); - } - return i; - } - - int nbits = 0xFF >>> (8 - n); - - int i = buffer.get(buffer.position() - 1) & nbits; - - if (i == nbits) - { - int m = 1; - int b; - do - { - b = 0xff & buffer.get(); - i = i + (b & 127) * m; - m = m * 128; - } - while ((b & 128) == 128); - } - return i; - } -} diff -Nru jetty9-9.4.50/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackContextTest.java jetty9-9.4.57/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackContextTest.java --- jetty9-9.4.50/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackContextTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackContextTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -21,6 +21,9 @@ import java.nio.ByteBuffer; import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.compression.EncodingException; +import org.eclipse.jetty.http.compression.HuffmanDecoder; +import org.eclipse.jetty.http.compression.NBitIntegerDecoder; import org.eclipse.jetty.http2.hpack.HpackContext.Entry; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; @@ -37,6 +40,32 @@ */ public class HpackContextTest { + public static String decode(ByteBuffer buffer, int length) throws EncodingException + { + HuffmanDecoder huffmanDecoder = new HuffmanDecoder(); + huffmanDecoder.setLength(length); + String decoded = huffmanDecoder.decode(buffer); + if (decoded == null) + throw new EncodingException("invalid string encoding"); + + huffmanDecoder.reset(); + return decoded; + } + + public static int decodeInt(ByteBuffer buffer, int prefix) throws EncodingException + { + // This is a fix for HPACK as it already takes the first byte of the encoded integer. + if (prefix != 8) + buffer.position(buffer.position() - 1); + + NBitIntegerDecoder decoder = new NBitIntegerDecoder(); + decoder.setPrefix(prefix); + int decodedInt = decoder.decodeInt(buffer); + if (decodedInt < 0) + throw new EncodingException("invalid integer encoding"); + decoder.reset(); + return decodedInt; + } @Test public void testStaticName() @@ -428,10 +457,10 @@ int huff = 0xff & buffer.get(); assertTrue((0x80 & huff) == 0x80); - int len = NBitInteger.decode(buffer, 7); + int len = decodeInt(buffer, 7); assertEquals(len, buffer.remaining()); - String value = Huffman.decode(buffer); + String value = decode(buffer, buffer.remaining()); assertEquals(entry.getHttpField().getValue(), value); } diff -Nru jetty9-9.4.50/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java jetty9-9.4.57/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java --- jetty9-9.4.50/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -62,7 +62,7 @@ @Test public void testDecodeD3() throws Exception { - HpackDecoder decoder = new HpackDecoder(4096, 8192); + HpackDecoder decoder = new HpackDecoder(8192); // First request String encoded = "828684410f7777772e6578616d706c652e636f6d"; @@ -110,7 +110,7 @@ @Test public void testDecodeD4() throws Exception { - HpackDecoder decoder = new HpackDecoder(4096, 8192); + HpackDecoder decoder = new HpackDecoder(8192); // First request String encoded = "828684418cf1e3c2e5f23a6ba0ab90f4ff"; @@ -145,7 +145,7 @@ { String value = "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="; - HpackDecoder decoder = new HpackDecoder(4096, 8192); + HpackDecoder decoder = new HpackDecoder(8192); String encoded = "8682418cF1E3C2E5F23a6bA0Ab90F4Ff841f0822426173696320515778685a475270626a70766347567549484e6c633246745a513d3d"; byte[] bytes = TypeUtil.fromHexString(encoded); byte[] array = new byte[bytes.length + 1]; @@ -167,7 +167,7 @@ @Test public void testDecodeHuffmanWithArrayOffset() throws Exception { - HpackDecoder decoder = new HpackDecoder(4096, 8192); + HpackDecoder decoder = new HpackDecoder(8192); String encoded = "8286418cf1e3c2e5f23a6ba0ab90f4ff84"; byte[] bytes = TypeUtil.fromHexString(encoded); @@ -191,7 +191,7 @@ String encoded = "886196C361Be940b6a65B6850400B8A00571972e080a62D1Bf5f87497cA589D34d1f9a0f0d0234327690Aa69D29aFcA954D3A5358980Ae112e0f7c880aE152A9A74a6bF3"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); - HpackDecoder decoder = new HpackDecoder(4096, 8192); + HpackDecoder decoder = new HpackDecoder(8192); MetaData.Response response = (MetaData.Response)decoder.decode(buffer); assertThat(response.getStatus(), is(200)); @@ -209,7 +209,7 @@ { String encoded = "203f136687A0E41d139d090760881c6490B2Cd39Ba7f"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); - HpackDecoder decoder = new HpackDecoder(4096, 8192); + HpackDecoder decoder = new HpackDecoder(8192); MetaData metaData = decoder.decode(buffer); assertThat(metaData.getFields().get(HttpHeader.HOST), is("localhost0")); assertThat(metaData.getFields().get(HttpHeader.COOKIE), is("abcdefghij")); @@ -231,7 +231,7 @@ String encoded = "203f136687A0E41d139d090760881c6490B2Cd39Ba7f20"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); - HpackDecoder decoder = new HpackDecoder(4096, 8192); + HpackDecoder decoder = new HpackDecoder(8192); try { decoder.decode(buffer); @@ -249,7 +249,8 @@ String encoded = "3f610f17FfEc02Df3990A190A0D4Ee5b3d2940Ec98Aa4a62D127D29e273a0aA20dEcAa190a503b262d8a2671D4A2672a927aA874988a2471D05510750c951139EdA2452a3a548cAa1aA90bE4B228342864A9E0D450A5474a92992a1aA513395448E3A0Aa17B96cFe3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f14E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F3E7Cf9f3e7cF9F353F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F54f"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); - HpackDecoder decoder = new HpackDecoder(128, 8192); + HpackDecoder decoder = new HpackDecoder(8192); + decoder.setMaxTableCapacity(128); MetaData metaData = decoder.decode(buffer); assertThat(decoder.getHpackContext().getDynamicTableSize(), is(0)); @@ -262,7 +263,8 @@ String encoded = "BE"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); - HpackDecoder decoder = new HpackDecoder(128, 8192); + HpackDecoder decoder = new HpackDecoder(8192); + decoder.setMaxTableCapacity(128); try { @@ -447,7 +449,7 @@ @Test public void testHuffmanEncodedStandard() throws Exception { - HpackDecoder decoder = new HpackDecoder(4096, 8192); + HpackDecoder decoder = new HpackDecoder(8192); String encoded = "82868441" + "83" + "49509F"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); @@ -465,68 +467,68 @@ @Test public void testHuffmanEncodedExtraPadding() { - HpackDecoder decoder = new HpackDecoder(4096, 8192); + HpackDecoder decoder = new HpackDecoder(8192); String encoded = "82868441" + "84" + "49509FFF"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); CompressionException ex = assertThrows(CompressionException.class, () -> decoder.decode(buffer)); - assertThat(ex.getMessage(), Matchers.containsString("Bad termination")); + assertThat(ex.getMessage(), Matchers.containsString("bad_termination")); } /* 5.2.2: Sends a Huffman-encoded string literal representation padded by zero */ @Test public void testHuffmanEncodedZeroPadding() { - HpackDecoder decoder = new HpackDecoder(4096, 8192); + HpackDecoder decoder = new HpackDecoder(8192); String encoded = "82868441" + "83" + "495090"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); CompressionException ex = assertThrows(CompressionException.class, () -> decoder.decode(buffer)); - assertThat(ex.getMessage(), Matchers.containsString("Incorrect padding")); + assertThat(ex.getMessage(), Matchers.containsString("incorrect_padding")); } /* 5.2.3: Sends a Huffman-encoded string literal representation containing the EOS symbol */ @Test public void testHuffmanEncodedWithEOS() { - HpackDecoder decoder = new HpackDecoder(4096, 8192); + HpackDecoder decoder = new HpackDecoder(8192); String encoded = "82868441" + "87" + "497FFFFFFF427F"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); CompressionException ex = assertThrows(CompressionException.class, () -> decoder.decode(buffer)); - assertThat(ex.getMessage(), Matchers.containsString("EOS in content")); + assertThat(ex.getMessage(), Matchers.containsString("eos_in_content")); } @Test public void testHuffmanEncodedOneIncompleteOctet() { - HpackDecoder decoder = new HpackDecoder(4096, 8192); + HpackDecoder decoder = new HpackDecoder(8192); String encoded = "82868441" + "81" + "FE"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); CompressionException ex = assertThrows(CompressionException.class, () -> decoder.decode(buffer)); - assertThat(ex.getMessage(), Matchers.containsString("Bad termination")); + assertThat(ex.getMessage(), Matchers.containsString("bad_termination")); } @Test public void testHuffmanEncodedTwoIncompleteOctet() { - HpackDecoder decoder = new HpackDecoder(4096, 8192); + HpackDecoder decoder = new HpackDecoder(8192); String encoded = "82868441" + "82" + "FFFE"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); CompressionException ex = assertThrows(CompressionException.class, () -> decoder.decode(buffer)); - assertThat(ex.getMessage(), Matchers.containsString("Bad termination")); + assertThat(ex.getMessage(), Matchers.containsString("bad_termination")); } @Test public void testZeroLengthName() { - HpackDecoder decoder = new HpackDecoder(4096, 8192); + HpackDecoder decoder = new HpackDecoder(8192); String encoded = "00000130"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); @@ -537,7 +539,7 @@ @Test public void testZeroLengthValue() throws Exception { - HpackDecoder decoder = new HpackDecoder(4096, 8192); + HpackDecoder decoder = new HpackDecoder(8192); String encoded = "00016800"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); @@ -549,7 +551,7 @@ @Test public void testUpperCaseName() { - HpackDecoder decoder = new HpackDecoder(4096, 8192); + HpackDecoder decoder = new HpackDecoder(8192); String encoded = "0001480130"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); @@ -560,7 +562,7 @@ @Test public void testWhiteSpaceName() { - HpackDecoder decoder = new HpackDecoder(4096, 8192); + HpackDecoder decoder = new HpackDecoder(8192); String encoded = "0001200130"; ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); diff -Nru jetty9-9.4.50/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackEncoderTest.java jetty9-9.4.57/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackEncoderTest.java --- jetty9-9.4.50/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackEncoderTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackEncoderTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -38,7 +38,7 @@ @Test public void testUnknownFieldsContextManagement() throws Exception { - HpackEncoder encoder = new HpackEncoder(38 * 5); + HpackEncoder encoder = newHpackEncoder(38 * 5); HttpFields fields = new HttpFields(); HttpField[] field = @@ -149,8 +149,9 @@ @Test public void testLargeFieldsNotIndexed() { - HpackEncoder encoder = new HpackEncoder(38 * 5); + HpackEncoder encoder = newHpackEncoder(38 * 5); HpackContext ctx = encoder.getHpackContext(); + ctx.resize(encoder.getMaxTableCapacity()); ByteBuffer buffer = BufferUtil.allocate(4096); @@ -175,8 +176,9 @@ @Test public void testIndexContentLength() { - HpackEncoder encoder = new HpackEncoder(38 * 5); + HpackEncoder encoder = newHpackEncoder(38 * 5); HpackContext ctx = encoder.getHpackContext(); + ctx.resize(encoder.getMaxTableCapacity()); ByteBuffer buffer = BufferUtil.allocate(4096); @@ -197,7 +199,7 @@ @Test public void testNeverIndexSetCookie() throws Exception { - HpackEncoder encoder = new HpackEncoder(38 * 5); + HpackEncoder encoder = newHpackEncoder(38 * 5); ByteBuffer buffer = BufferUtil.allocate(4096); HttpFields fields = new HttpFields(); @@ -231,20 +233,20 @@ { HttpFields fields = new HttpFields(); - HpackEncoder encoder = new HpackEncoder(128); + HpackEncoder encoder = newHpackEncoder(128); ByteBuffer buffer0 = BufferUtil.allocate(4096); int pos = BufferUtil.flipToFill(buffer0); encoder.encode(buffer0, new MetaData(HttpVersion.HTTP_2, fields)); BufferUtil.flipToFlush(buffer0, pos); - encoder = new HpackEncoder(128); + encoder = newHpackEncoder(128); fields.add(new HttpField("user-agent", "jetty/test")); ByteBuffer buffer1 = BufferUtil.allocate(4096); pos = BufferUtil.flipToFill(buffer1); encoder.encode(buffer1, new MetaData(HttpVersion.HTTP_2, fields)); BufferUtil.flipToFlush(buffer1, pos); - encoder = new HpackEncoder(128); + encoder = newHpackEncoder(128); encoder.setValidateEncoding(false); fields.add(new HttpField(":path", "This is a very large field, whose size is larger than the dynamic table so it should not be indexed as it will not fit in the table ever!" + @@ -256,7 +258,7 @@ encoder.encode(buffer2, new MetaData(HttpVersion.HTTP_2, fields)); BufferUtil.flipToFlush(buffer2, pos); - encoder = new HpackEncoder(128); + encoder = newHpackEncoder(128); encoder.setValidateEncoding(false); fields.add(new HttpField("host", "somehost")); ByteBuffer buffer = BufferUtil.allocate(4096); @@ -297,12 +299,12 @@ fields.add("host", "localhost0"); fields.add("cookie", "abcdefghij"); - HpackEncoder encoder = new HpackEncoder(4096); + HpackEncoder encoder = newHpackEncoder(4096); ByteBuffer buffer = BufferUtil.allocate(4096); int pos = BufferUtil.flipToFill(buffer); encoder.encodeMaxDynamicTableSize(buffer, 0); - encoder.setRemoteMaxDynamicTableSize(50); + encoder.setTableCapacity(50); encoder.encode(buffer, new MetaData(HttpVersion.HTTP_2, fields)); BufferUtil.flipToFlush(buffer, pos); @@ -311,4 +313,12 @@ assertThat(context.getMaxDynamicTableSize(), Matchers.is(50)); assertThat(context.size(), Matchers.is(1)); } + + private static HpackEncoder newHpackEncoder(int tableCapacity) + { + HpackEncoder encoder = new HpackEncoder(); + encoder.setMaxTableCapacity(tableCapacity); + encoder.setTableCapacity(tableCapacity); + return encoder; + } } diff -Nru jetty9-9.4.50/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackPerfTest.java jetty9-9.4.57/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackPerfTest.java --- jetty9-9.4.50/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackPerfTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackPerfTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -37,7 +37,7 @@ public class HpackPerfTest { - int _maxDynamicTableSize = 4 * 1024; + int _tableCapacity = 4 * 1024; int _unencodedSize; int _encodedSize; @@ -51,7 +51,7 @@ @AfterEach public void after() { - System.err.printf("dynamictable=%d unencoded=%d encoded=%d p=%3.1f%%%n", _maxDynamicTableSize, _unencodedSize, _encodedSize, 100.0 * _encodedSize / _unencodedSize); + System.err.printf("dynamictable=%d unencoded=%d encoded=%d p=%3.1f%%%n", _tableCapacity, _unencodedSize, _encodedSize, 100.0 * _encodedSize / _unencodedSize); } @Test @@ -68,11 +68,14 @@ assertNotNull(files); // Parse JSON - Map[] stories = new Map[files.length]; + @SuppressWarnings("unchecked") + Map[] stories = new Map[files.length]; int i = 0; - for (String story : files) + for (String file : files) { - stories[i++] = (Map)JSON.parse(new FileReader(new File(data, story))); + @SuppressWarnings("unchecked") + Map story = (Map)JSON.parse(new FileReader(new File(data, file))); + stories[i++] = story; } ByteBuffer buffer = BufferUtil.allocate(256 * 1024); @@ -88,27 +91,29 @@ encodeStories(buffer, stories, "response"); } - private void encodeStories(ByteBuffer buffer, Map[] stories, String type) throws Exception + private void encodeStories(ByteBuffer buffer, Map[] stories, String type) throws Exception { - for (Map story : stories) + for (Map story : stories) { if (type.equals(story.get("context"))) { - HpackEncoder encoder = new HpackEncoder(_maxDynamicTableSize, _maxDynamicTableSize); + HpackEncoder encoder = new HpackEncoder(); + encoder.setMaxTableCapacity(_tableCapacity); + encoder.setTableCapacity(_tableCapacity); encoder.setValidateEncoding(false); - // System.err.println(story); Object[] cases = (Object[])story.get("cases"); for (Object c : cases) { - // System.err.println(" "+c); - Object[] headers = (Object[])((Map)c).get("headers"); + @SuppressWarnings("unchecked") + Map kase = (Map)c; + Object[] headers = (Object[])kase.get("headers"); // System.err.println(" "+headers); HttpFields fields = new HttpFields(); for (Object header : headers) { @SuppressWarnings("unchecked") - Map h = (Map)header; + Map h = (Map)header; Map.Entry e = h.entrySet().iterator().next(); fields.add(e.getKey(), e.getValue()); _unencodedSize += e.getKey().length() + e.getValue().length(); diff -Nru jetty9-9.4.50/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackTest.java jetty9-9.4.57/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackTest.java --- jetty9-9.4.50/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -19,7 +19,6 @@ package org.eclipse.jetty.http2.hpack; import java.nio.ByteBuffer; -import java.util.concurrent.TimeUnit; import org.eclipse.jetty.http.DateGenerator; import org.eclipse.jetty.http.HttpField; @@ -43,13 +42,13 @@ { static final HttpField ServerJetty = new PreEncodedHttpField(HttpHeader.SERVER, "jetty"); static final HttpField XPowerJetty = new PreEncodedHttpField(HttpHeader.X_POWERED_BY, "jetty"); - static final HttpField Date = new PreEncodedHttpField(HttpHeader.DATE, DateGenerator.formatDate(TimeUnit.NANOSECONDS.toMillis(System.nanoTime()))); + static final HttpField Date = new PreEncodedHttpField(HttpHeader.DATE, DateGenerator.formatDate(System.currentTimeMillis())); @Test public void encodeDecodeResponseTest() throws Exception { HpackEncoder encoder = new HpackEncoder(); - HpackDecoder decoder = new HpackDecoder(4096, 8192); + HpackDecoder decoder = new HpackDecoder(8192); ByteBuffer buffer = BufferUtil.allocateDirect(16 * 1024); HttpFields fields0 = new HttpFields(); @@ -102,7 +101,7 @@ public void encodeDecodeTooLargeTest() throws Exception { HpackEncoder encoder = new HpackEncoder(); - HpackDecoder decoder = new HpackDecoder(4096, 164); + HpackDecoder decoder = new HpackDecoder(164); ByteBuffer buffer = BufferUtil.allocateDirect(16 * 1024); HttpFields fields0 = new HttpFields(); @@ -133,36 +132,40 @@ } catch (HpackException.SessionException e) { - assertThat(e.getMessage(), containsString("Header too large")); + assertThat(e.getMessage(), containsString("Header size 198 > 164")); } } @Test - public void encodeDecodeNonAscii() throws Exception + public void encodeNonAscii() throws Exception { HpackEncoder encoder = new HpackEncoder(); - HpackDecoder decoder = new HpackDecoder(4096, 8192); ByteBuffer buffer = BufferUtil.allocate(16 * 1024); HttpFields fields0 = new HttpFields(); - // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck + // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck fields0.add("Cookie", "[\uD842\uDF9F]"); fields0.add("custom-key", "[\uD842\uDF9F]"); Response original0 = new MetaData.Response(HttpVersion.HTTP_2, 200, fields0); - BufferUtil.clearToFill(buffer); - encoder.encode(buffer, original0); - BufferUtil.flipToFlush(buffer, 0); - Response decoded0 = (Response)decoder.decode(buffer); + HpackException.SessionException throwable = assertThrows(HpackException.SessionException.class, () -> + { + BufferUtil.clearToFill(buffer); + encoder.encode(buffer, original0); + BufferUtil.flipToFlush(buffer, 0); + }); - assertMetaDataSame(original0, decoded0); + assertThat(throwable.getMessage(), containsString("Could not hpack encode")); } - + @Test public void evictReferencedFieldTest() throws Exception { - HpackEncoder encoder = new HpackEncoder(200, 200); - HpackDecoder decoder = new HpackDecoder(200, 1024); + HpackDecoder decoder = new HpackDecoder(1024); + decoder.setMaxTableCapacity(200); + HpackEncoder encoder = new HpackEncoder(); + encoder.setMaxTableCapacity(decoder.getMaxTableCapacity()); + encoder.setTableCapacity(decoder.getMaxTableCapacity()); ByteBuffer buffer = BufferUtil.allocateDirect(16 * 1024); String longEnoughToBeEvicted = "012345678901234567890123456789012345678901234567890"; @@ -205,7 +208,7 @@ public void testHopHeadersAreRemoved() throws Exception { HpackEncoder encoder = new HpackEncoder(); - HpackDecoder decoder = new HpackDecoder(4096, 16384); + HpackDecoder decoder = new HpackDecoder(16384); HttpFields input = new HttpFields(); input.put(HttpHeader.ACCEPT, "*"); @@ -232,14 +235,14 @@ public void testTETrailers() throws Exception { HpackEncoder encoder = new HpackEncoder(); - HpackDecoder decoder = new HpackDecoder(4096, 16384); + HpackDecoder decoder = new HpackDecoder(16384); - HttpFields input = new HttpFields(); - input.put(HttpHeader.CONNECTION, "TE"); String teValue = "trailers"; - input.put(HttpHeader.TE, teValue); String trailerValue = "Custom"; - input.put(HttpHeader.TRAILER, trailerValue); + HttpFields input = new HttpFields(); + input.add(HttpHeader.CONNECTION, "TE"); + input.add(HttpHeader.TE, teValue); + input.add(HttpHeader.TRAILER, trailerValue); ByteBuffer buffer = BufferUtil.allocate(2048); BufferUtil.clearToFill(buffer); @@ -257,7 +260,7 @@ public void testColonHeaders() throws Exception { HpackEncoder encoder = new HpackEncoder(); - HpackDecoder decoder = new HpackDecoder(4096, 16384); + HpackDecoder decoder = new HpackDecoder(16384); HttpFields input = new HttpFields(); input.put(":status", "200"); diff -Nru jetty9-9.4.50/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java jetty9-9.4.57/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java --- jetty9-9.4.50/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// ------------------------------------------------------------------------ -// 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.http2.hpack; - -import java.nio.BufferOverflowException; -import java.nio.ByteBuffer; -import java.util.Locale; -import java.util.stream.Stream; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.TypeUtil; -import org.hamcrest.Matchers; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -public class HuffmanTest -{ - public static Stream data() - { - return Stream.of( - new String[][]{ - {"D.4.1", "f1e3c2e5f23a6ba0ab90f4ff", "www.example.com"}, - {"D.4.2", "a8eb10649cbf", "no-cache"}, - {"D.6.1k", "6402", "302"}, - {"D.6.1v", "aec3771a4b", "private"}, - {"D.6.1d", "d07abe941054d444a8200595040b8166e082a62d1bff", "Mon, 21 Oct 2013 20:13:21 GMT"}, - {"D.6.1l", "9d29ad171863c78f0b97c8e9ae82ae43d3", "https://www.example.com"}, - {"D.6.2te", "640cff", "303"}, - }).map(Arguments::of); - } - - @ParameterizedTest(name = "[{index}] spec={0}") - @MethodSource("data") - public void testDecode(String specSection, String hex, String expected) throws Exception - { - byte[] encoded = TypeUtil.fromHexString(hex); - String decoded = Huffman.decode(ByteBuffer.wrap(encoded)); - assertEquals(expected, decoded, specSection); - } - - @ParameterizedTest(name = "[{index}] spec={0}") - @MethodSource("data") - public void testEncode(String specSection, String hex, String expected) - { - ByteBuffer buf = BufferUtil.allocate(1024); - int pos = BufferUtil.flipToFill(buf); - Huffman.encode(buf, expected); - BufferUtil.flipToFlush(buf, pos); - String encoded = TypeUtil.toHexString(BufferUtil.toArray(buf)).toLowerCase(Locale.ENGLISH); - assertEquals(hex, encoded, specSection); - assertEquals(hex.length() / 2, Huffman.octetsNeeded(expected)); - } - - @ParameterizedTest(name = "[{index}]") // don't include unprintable character in test display-name - @ValueSource(chars = {(char)128, (char)0, (char)-1, ' ' - 1}) - public void testEncode8859Only(char bad) - { - String s = "bad '" + bad + "'"; - - assertThat(Huffman.octetsNeeded(s), Matchers.is(-1)); - - assertThrows(BufferOverflowException.class, - () -> Huffman.encode(BufferUtil.allocate(32), s)); - } -} diff -Nru jetty9-9.4.50/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/NBitIntegerTest.java jetty9-9.4.57/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/NBitIntegerTest.java --- jetty9-9.4.50/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/NBitIntegerTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/NBitIntegerTest.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,204 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// ------------------------------------------------------------------------ -// 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.http2.hpack; - -import java.nio.ByteBuffer; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.TypeUtil; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class NBitIntegerTest -{ - - @Test - public void testOctetsNeeded() - { - assertEquals(0, NBitInteger.octectsNeeded(5, 10)); - assertEquals(2, NBitInteger.octectsNeeded(5, 1337)); - assertEquals(1, NBitInteger.octectsNeeded(8, 42)); - assertEquals(3, NBitInteger.octectsNeeded(8, 1337)); - - assertEquals(0, NBitInteger.octectsNeeded(6, 62)); - assertEquals(1, NBitInteger.octectsNeeded(6, 63)); - assertEquals(1, NBitInteger.octectsNeeded(6, 64)); - assertEquals(2, NBitInteger.octectsNeeded(6, 63 + 0x00 + 0x80 * 0x01)); - assertEquals(3, NBitInteger.octectsNeeded(6, 63 + 0x00 + 0x80 * 0x80)); - assertEquals(4, NBitInteger.octectsNeeded(6, 63 + 0x00 + 0x80 * 0x80 * 0x80)); - } - - @Test - public void testEncode() - { - testEncode(6, 0, "00"); - testEncode(6, 1, "01"); - testEncode(6, 62, "3e"); - testEncode(6, 63, "3f00"); - testEncode(6, 63 + 1, "3f01"); - testEncode(6, 63 + 0x7e, "3f7e"); - testEncode(6, 63 + 0x7f, "3f7f"); - testEncode(6, 63 + 0x00 + 0x80 * 0x01, "3f8001"); - testEncode(6, 63 + 0x01 + 0x80 * 0x01, "3f8101"); - testEncode(6, 63 + 0x7f + 0x80 * 0x01, "3fFf01"); - testEncode(6, 63 + 0x00 + 0x80 * 0x02, "3f8002"); - testEncode(6, 63 + 0x01 + 0x80 * 0x02, "3f8102"); - testEncode(6, 63 + 0x7f + 0x80 * 0x7f, "3fFf7f"); - testEncode(6, 63 + 0x00 + 0x80 * 0x80, "3f808001"); - testEncode(6, 63 + 0x7f + 0x80 * 0x80 * 0x7f, "3fFf807f"); - testEncode(6, 63 + 0x00 + 0x80 * 0x80 * 0x80, "3f80808001"); - - testEncode(8, 0, "00"); - testEncode(8, 1, "01"); - testEncode(8, 128, "80"); - testEncode(8, 254, "Fe"); - testEncode(8, 255, "Ff00"); - testEncode(8, 255 + 1, "Ff01"); - testEncode(8, 255 + 0x7e, "Ff7e"); - testEncode(8, 255 + 0x7f, "Ff7f"); - testEncode(8, 255 + 0x80, "Ff8001"); - testEncode(8, 255 + 0x00 + 0x80 * 0x80, "Ff808001"); - } - - public void testEncode(int n, int i, String expected) - { - ByteBuffer buf = BufferUtil.allocate(16); - int p = BufferUtil.flipToFill(buf); - if (n < 8) - buf.put((byte)0x00); - NBitInteger.encode(buf, n, i); - BufferUtil.flipToFlush(buf, p); - String r = TypeUtil.toHexString(BufferUtil.toArray(buf)); - assertEquals(expected, r); - - assertEquals(expected.length() / 2, (n < 8 ? 1 : 0) + NBitInteger.octectsNeeded(n, i)); - } - - @Test - public void testDecode() - { - testDecode(6, 0, "00"); - testDecode(6, 1, "01"); - testDecode(6, 62, "3e"); - testDecode(6, 63, "3f00"); - testDecode(6, 63 + 1, "3f01"); - testDecode(6, 63 + 0x7e, "3f7e"); - testDecode(6, 63 + 0x7f, "3f7f"); - testDecode(6, 63 + 0x80, "3f8001"); - testDecode(6, 63 + 0x81, "3f8101"); - testDecode(6, 63 + 0x7f + 0x80 * 0x01, "3fFf01"); - testDecode(6, 63 + 0x00 + 0x80 * 0x02, "3f8002"); - testDecode(6, 63 + 0x01 + 0x80 * 0x02, "3f8102"); - testDecode(6, 63 + 0x7f + 0x80 * 0x7f, "3fFf7f"); - testDecode(6, 63 + 0x00 + 0x80 * 0x80, "3f808001"); - testDecode(6, 63 + 0x7f + 0x80 * 0x80 * 0x7f, "3fFf807f"); - testDecode(6, 63 + 0x00 + 0x80 * 0x80 * 0x80, "3f80808001"); - - testDecode(8, 0, "00"); - testDecode(8, 1, "01"); - testDecode(8, 128, "80"); - testDecode(8, 254, "Fe"); - testDecode(8, 255, "Ff00"); - testDecode(8, 255 + 1, "Ff01"); - testDecode(8, 255 + 0x7e, "Ff7e"); - testDecode(8, 255 + 0x7f, "Ff7f"); - testDecode(8, 255 + 0x80, "Ff8001"); - testDecode(8, 255 + 0x00 + 0x80 * 0x80, "Ff808001"); - } - - public void testDecode(int n, int expected, String encoded) - { - ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); - buf.position(n == 8 ? 0 : 1); - assertEquals(expected, NBitInteger.decode(buf, n)); - } - - @Test - public void testEncodeExampleD11() - { - ByteBuffer buf = BufferUtil.allocate(16); - int p = BufferUtil.flipToFill(buf); - buf.put((byte)0x77); - buf.put((byte)0xFF); - NBitInteger.encode(buf, 5, 10); - BufferUtil.flipToFlush(buf, p); - - String r = TypeUtil.toHexString(BufferUtil.toArray(buf)); - - assertEquals("77Ea", r); - } - - @Test - public void testDecodeExampleD11() - { - ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("77EaFF")); - buf.position(2); - - assertEquals(10, NBitInteger.decode(buf, 5)); - } - - @Test - public void testEncodeExampleD12() - { - ByteBuffer buf = BufferUtil.allocate(16); - int p = BufferUtil.flipToFill(buf); - buf.put((byte)0x88); - buf.put((byte)0x00); - NBitInteger.encode(buf, 5, 1337); - BufferUtil.flipToFlush(buf, p); - - String r = TypeUtil.toHexString(BufferUtil.toArray(buf)); - - assertEquals("881f9a0a", r); - } - - @Test - public void testDecodeExampleD12() - { - ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("881f9a0aff")); - buf.position(2); - - assertEquals(1337, NBitInteger.decode(buf, 5)); - } - - @Test - public void testEncodeExampleD13() - { - ByteBuffer buf = BufferUtil.allocate(16); - int p = BufferUtil.flipToFill(buf); - buf.put((byte)0x88); - buf.put((byte)0xFF); - NBitInteger.encode(buf, 8, 42); - BufferUtil.flipToFlush(buf, p); - - String r = TypeUtil.toHexString(BufferUtil.toArray(buf)); - - assertEquals("88Ff2a", r); - } - - @Test - public void testDecodeExampleD13() - { - ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("882aFf")); - buf.position(1); - - assertEquals(42, NBitInteger.decode(buf, 8)); - } -} diff -Nru jetty9-9.4.50/jetty-http2/http2-http-client-transport/pom.xml jetty9-9.4.57/jetty-http2/http2-http-client-transport/pom.xml --- jetty9-9.4.50/jetty-http2/http2-http-client-transport/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-http-client-transport/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2.java jetty9-9.4.57/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2.java --- jetty9-9.4.50/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2.java 2024-12-19 21:51:26.000000000 +0000 @@ -225,11 +225,21 @@ } @Override + public void onGoAway(Session session, GoAwayFrame frame) + { + if (failConnectionPromise(new ClosedChannelException())) + return; + HttpConnectionOverHTTP2 connection = getConnection(); + if (connection != null) + connection.remove(); + } + + @Override public void onClose(Session session, GoAwayFrame frame) { if (failConnectionPromise(new ClosedChannelException())) return; - HttpConnectionOverHTTP2 connection = this.connection.getReference(); + HttpConnectionOverHTTP2 connection = getConnection(); if (connection != null) HttpClientTransportOverHTTP2.this.onClose(connection, frame); } @@ -240,7 +250,7 @@ long idleTimeout = ((HTTP2Session)session).getEndPoint().getIdleTimeout(); if (failConnectionPromise(new TimeoutException("Idle timeout expired: " + idleTimeout + " ms"))) return true; - HttpConnectionOverHTTP2 connection = this.connection.getReference(); + HttpConnectionOverHTTP2 connection = getConnection(); if (connection != null) return connection.onIdleTimeout(idleTimeout); return true; @@ -251,7 +261,7 @@ { if (failConnectionPromise(failure)) return; - HttpConnectionOverHTTP2 connection = this.connection.getReference(); + HttpConnectionOverHTTP2 connection = getConnection(); if (connection != null) connection.close(failure); } @@ -263,5 +273,10 @@ connectionPromise().failed(failure); return result; } + + private HttpConnectionOverHTTP2 getConnection() + { + return connection.getReference(); + } } } diff -Nru jetty9-9.4.50/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java jetty9-9.4.57/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java --- jetty9-9.4.50/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java 2024-12-19 21:51:26.000000000 +0000 @@ -144,6 +144,11 @@ return false; } + void remove() + { + getHttpDestination().remove(this); + } + @Override public void close() { diff -Nru jetty9-9.4.50/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/GoAwayTest.java jetty9-9.4.57/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/GoAwayTest.java --- jetty9-9.4.50/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/GoAwayTest.java 1970-01-01 00:00:00.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/GoAwayTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -0,0 +1,151 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// 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.http2.client.http; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +import org.eclipse.jetty.client.api.Response; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.http.MetaData; +import org.eclipse.jetty.http2.ErrorCode; +import org.eclipse.jetty.http2.HTTP2Session; +import org.eclipse.jetty.http2.api.Stream; +import org.eclipse.jetty.http2.api.server.ServerSessionListener; +import org.eclipse.jetty.http2.frames.GoAwayFrame; +import org.eclipse.jetty.http2.frames.HeadersFrame; +import org.eclipse.jetty.util.Callback; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class GoAwayTest extends AbstractTest +{ + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void testConnectionIsRemovedFromPoolOnGracefulGoAwayReceived(boolean graceful) throws Exception + { + long timeout = 5000; + AtomicReference responseRef = new AtomicReference<>(); + CountDownLatch responseLatch = new CountDownLatch(1); + start(new ServerSessionListener.Adapter() + { + private Stream goAwayStream; + + @Override + public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) + { + MetaData.Request request = (MetaData.Request)frame.getMetaData(); + String path = request.getURI().getPath(); + + if ("/prime".equals(path)) + { + respond(stream); + } + else if ("/goaway".equals(path)) + { + try + { + goAwayStream = stream; + + if (graceful) + { + // Send to the client a graceful GOAWAY. + ((HTTP2Session)stream.getSession()).goAway(GoAwayFrame.GRACEFUL, Callback.NOOP); + } + else + { + // Send to the client a non-graceful GOAWAY. + stream.getSession().close(ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, null, Callback.NOOP); + } + + // Wait for the client to receive the GOAWAY. + Thread.sleep(1000); + + // This request will be performed on a different connection. + client.newRequest("localhost", connector.getLocalPort()) + .path("/after") + .timeout(timeout / 2, TimeUnit.MILLISECONDS) + .send(result -> + { + responseRef.set(result.getResponse()); + responseLatch.countDown(); + }); + } + catch (Exception x) + { + throw new RuntimeException(x); + } + } + else if ("/after".equals(path)) + { + // Wait for the /after request to arrive to the server + // before answering to the /goaway request. + // The /goaway request must succeed because it's in + // flight and seen by the server when the GOAWAY happens, + // so it will be completed before closing the connection. + respond(goAwayStream); + respond(stream); + } + return null; + } + + private void respond(Stream stream) + { + HTTP2Session session = (HTTP2Session)stream.getSession(); + long remotePort = session.getEndPoint().getRemoteAddress().getPort(); + HttpFields responseHeaders = new HttpFields(); + responseHeaders.putLongField("X-Remote-Port", remotePort); + MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, responseHeaders); + stream.headers(new HeadersFrame(stream.getId(), response, null, true), Callback.NOOP); + } + }); + + Response response = client.newRequest("localhost", connector.getLocalPort()) + .path("/prime") + .timeout(timeout, TimeUnit.MILLISECONDS) + .send(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + long primePort = response.getHeaders().getLongField("X-Remote-Port"); + + response = client.newRequest("localhost", connector.getLocalPort()) + .path("/goaway") + .timeout(timeout, TimeUnit.MILLISECONDS) + .send(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + long goAwayPort = response.getHeaders().getLongField("X-Remote-Port"); + assertEquals(primePort, goAwayPort); + + assertTrue(responseLatch.await(timeout, TimeUnit.MILLISECONDS)); + response = responseRef.get(); + assertNotNull(response); + assertEquals(HttpStatus.OK_200, response.getStatus()); + // The /after request must happen on a different port + // because the first connection has been removed from the pool. + long afterPort = response.getHeaders().getLongField("X-Remote-Port"); + assertNotEquals(primePort, afterPort); + } +} diff -Nru jetty9-9.4.50/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java jetty9-9.4.57/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java --- jetty9-9.4.50/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java 2024-12-19 21:51:26.000000000 +0000 @@ -36,7 +36,6 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.UnaryOperator; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -62,7 +61,6 @@ import org.eclipse.jetty.http2.frames.SettingsFrame; import org.eclipse.jetty.http2.generator.Generator; import org.eclipse.jetty.http2.hpack.HpackException; -import org.eclipse.jetty.http2.parser.RateControl; import org.eclipse.jetty.http2.parser.ServerParser; import org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory; import org.eclipse.jetty.io.ByteBufferPool; @@ -456,7 +454,8 @@ OutputStream output = socket.getOutputStream(); InputStream input = socket.getInputStream(); - ServerParser parser = new ServerParser(byteBufferPool, new ServerParser.Listener.Adapter() + ServerParser parser = new ServerParser(byteBufferPool, 4096); + parser.init(new ServerParser.Listener.Adapter() { @Override public void onPreface() @@ -508,8 +507,7 @@ x.printStackTrace(); } } - }, 4096, 8192, RateControl.NO_RATE_CONTROL); - parser.init(UnaryOperator.identity()); + }); byte[] bytes = new byte[1024]; while (true) diff -Nru jetty9-9.4.50/jetty-http2/http2-server/pom.xml jetty9-9.4.57/jetty-http2/http2-server/pom.xml --- jetty9-9.4.50/jetty-http2/http2-server/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-server/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-http2/http2-server/src/main/config/etc/jetty-http2.xml jetty9-9.4.57/jetty-http2/http2-server/src/main/config/etc/jetty-http2.xml --- jetty9-9.4.50/jetty-http2/http2-server/src/main/config/etc/jetty-http2.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-server/src/main/config/etc/jetty-http2.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ - + diff -Nru jetty9-9.4.50/jetty-http2/http2-server/src/main/config/etc/jetty-http2c.xml jetty9-9.4.57/jetty-http2/http2-server/src/main/config/etc/jetty-http2c.xml --- jetty9-9.4.50/jetty-http2/http2-server/src/main/config/etc/jetty-http2c.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-server/src/main/config/etc/jetty-http2c.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ - + diff -Nru jetty9-9.4.50/jetty-http2/http2-server/src/main/config/modules/http2.mod jetty9-9.4.57/jetty-http2/http2-server/src/main/config/modules/http2.mod --- jetty9-9.4.50/jetty-http2/http2-server/src/main/config/modules/http2.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-server/src/main/config/modules/http2.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables HTTP2 protocol support on the TLS(SSL) Connector, diff -Nru jetty9-9.4.50/jetty-http2/http2-server/src/main/config/modules/http2c.mod jetty9-9.4.57/jetty-http2/http2-server/src/main/config/modules/http2c.mod --- jetty9-9.4.50/jetty-http2/http2-server/src/main/config/modules/http2c.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-server/src/main/config/modules/http2c.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables the HTTP2C protocol on the HTTP Connector diff -Nru jetty9-9.4.50/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java jetty9-9.4.57/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java --- jetty9-9.4.50/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java 2024-12-19 21:51:26.000000000 +0000 @@ -34,6 +34,7 @@ import org.eclipse.jetty.http2.frames.Frame; import org.eclipse.jetty.http2.frames.SettingsFrame; import org.eclipse.jetty.http2.generator.Generator; +import org.eclipse.jetty.http2.hpack.HpackContext; import org.eclipse.jetty.http2.parser.RateControl; import org.eclipse.jetty.http2.parser.ServerParser; import org.eclipse.jetty.http2.parser.WindowRateControl; @@ -53,14 +54,15 @@ { private final HTTP2SessionContainer sessionContainer = new HTTP2SessionContainer(); private final HttpConfiguration httpConfiguration; - private int maxDynamicTableSize = 4096; + private int maxDecoderTableCapacity = HpackContext.DEFAULT_MAX_TABLE_CAPACITY; + private int maxEncoderTableCapacity = HpackContext.DEFAULT_MAX_TABLE_CAPACITY; private int initialSessionRecvWindow = 1024 * 1024; private int initialStreamRecvWindow = 512 * 1024; private int maxConcurrentStreams = 128; private int maxHeaderBlockFragment = 0; - private int maxFrameLength = Frame.DEFAULT_MAX_LENGTH; + private int maxFrameSize = Frame.DEFAULT_MAX_LENGTH; private int maxSettingsKeys = SettingsFrame.DEFAULT_MAX_KEYS; - private RateControl.Factory rateControlFactory = new WindowRateControl.Factory(50); + private RateControl.Factory rateControlFactory = new WindowRateControl.Factory(128); private FlowControlStrategy.Factory flowControlStrategyFactory = () -> new BufferingFlowControlStrategy(0.5F); private long streamIdleTimeout; @@ -83,15 +85,45 @@ setInputBufferSize(Frame.DEFAULT_MAX_LENGTH + Frame.HEADER_LENGTH); } + @Deprecated @ManagedAttribute("The HPACK dynamic table maximum size") public int getMaxDynamicTableSize() { - return maxDynamicTableSize; + return getMaxDecoderTableCapacity(); } + @Deprecated public void setMaxDynamicTableSize(int maxDynamicTableSize) { - this.maxDynamicTableSize = maxDynamicTableSize; + setMaxDecoderTableCapacity(maxDynamicTableSize); + } + + @ManagedAttribute("The HPACK encoder dynamic table maximum capacity") + public int getMaxEncoderTableCapacity() + { + return maxEncoderTableCapacity; + } + + /** + *

    Sets the limit for the encoder HPACK dynamic table capacity.

    + *

    Setting this value to {@code 0} disables the use of the dynamic table.

    + * + * @param maxEncoderTableCapacity The HPACK encoder dynamic table maximum capacity + */ + public void setMaxEncoderTableCapacity(int maxEncoderTableCapacity) + { + this.maxEncoderTableCapacity = maxEncoderTableCapacity; + } + + @ManagedAttribute("The HPACK decoder dynamic table maximum capacity") + public int getMaxDecoderTableCapacity() + { + return maxDecoderTableCapacity; + } + + public void setMaxDecoderTableCapacity(int maxDecoderTableCapacity) + { + this.maxDecoderTableCapacity = maxDecoderTableCapacity; } @ManagedAttribute("The initial size of session's flow control receive window") @@ -159,15 +191,28 @@ this.streamIdleTimeout = streamIdleTimeout; } + @Deprecated @ManagedAttribute("The max frame length in bytes") public int getMaxFrameLength() { - return maxFrameLength; + return getMaxFrameSize(); } + @Deprecated public void setMaxFrameLength(int maxFrameLength) { - this.maxFrameLength = maxFrameLength; + setMaxFrameSize(maxFrameLength); + } + + @ManagedAttribute("The max frame size in bytes") + public int getMaxFrameSize() + { + return maxFrameSize; + } + + public void setMaxFrameSize(int maxFrameSize) + { + this.maxFrameSize = maxFrameSize; } @ManagedAttribute("The max number of keys in all SETTINGS frames") @@ -267,37 +312,47 @@ { ServerSessionListener listener = newSessionListener(connector, endPoint); - Generator generator = new Generator(connector.getByteBufferPool(), getMaxDynamicTableSize(), getMaxHeaderBlockFragment()); + Generator generator = new Generator(connector.getByteBufferPool(), getMaxHeaderBlockFragment()); FlowControlStrategy flowControl = getFlowControlStrategyFactory().newFlowControlStrategy(); - HTTP2ServerSession session = new HTTP2ServerSession(connector.getScheduler(), endPoint, generator, listener, flowControl); + + ServerParser parser = newServerParser(connector, getRateControlFactory().newRateControl(endPoint)); + parser.setMaxFrameSize(getMaxFrameSize()); + parser.setMaxSettingsKeys(getMaxSettingsKeys()); + + HTTP2ServerSession session = new HTTP2ServerSession(connector.getScheduler(), endPoint, parser, generator, listener, flowControl); session.setMaxLocalStreams(getMaxConcurrentStreams()); session.setMaxRemoteStreams(getMaxConcurrentStreams()); + session.setMaxEncoderTableCapacity(getMaxEncoderTableCapacity()); // For a single stream in a connection, there will be a race between // the stream idle timeout and the connection idle timeout. However, // the typical case is that the connection will be busier and the // stream idle timeout will expire earlier than the connection's. long streamIdleTimeout = getStreamIdleTimeout(); - if (streamIdleTimeout <= 0) + if (streamIdleTimeout == 0) streamIdleTimeout = endPoint.getIdleTimeout(); session.setStreamIdleTimeout(streamIdleTimeout); session.setInitialSessionRecvWindow(getInitialSessionRecvWindow()); session.setWriteThreshold(getHttpConfiguration().getOutputBufferSize()); - ServerParser parser = newServerParser(connector, session, getRateControlFactory().newRateControl(endPoint)); - parser.setMaxFrameLength(getMaxFrameLength()); - parser.setMaxSettingsKeys(getMaxSettingsKeys()); - HTTP2Connection connection = new HTTP2ServerConnection(connector.getByteBufferPool(), connector.getExecutor(), - endPoint, httpConfiguration, parser, session, getInputBufferSize(), listener); + endPoint, httpConfiguration, session, getInputBufferSize(), listener); connection.addListener(sessionContainer); + parser.init(connection.wrapParserListener(session)); + return configure(connection, connector, endPoint); } protected abstract ServerSessionListener newSessionListener(Connector connector, EndPoint endPoint); + @Deprecated protected ServerParser newServerParser(Connector connector, ServerParser.Listener listener, RateControl rateControl) { - return new ServerParser(connector.getByteBufferPool(), listener, getMaxDynamicTableSize(), getHttpConfiguration().getRequestHeaderSize(), rateControl); + return newServerParser(connector, rateControl); + } + + protected ServerParser newServerParser(Connector connector, RateControl rateControl) + { + return new ServerParser(connector.getByteBufferPool(), getHttpConfiguration().getRequestHeaderSize(), rateControl); } @ManagedObject("The container of HTTP/2 sessions") diff -Nru jetty9-9.4.50/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java jetty9-9.4.57/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java --- jetty9-9.4.50/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java 2024-12-19 21:51:26.000000000 +0000 @@ -89,9 +89,15 @@ private final HttpConfiguration httpConfig; private boolean recycleHttpChannels = true; + @Deprecated public HTTP2ServerConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, HttpConfiguration httpConfig, ServerParser parser, ISession session, int inputBufferSize, ServerSessionListener listener) { - super(byteBufferPool, executor, endPoint, parser, session, inputBufferSize); + this(byteBufferPool, executor, endPoint, httpConfig, session, inputBufferSize, listener); + } + + public HTTP2ServerConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, HttpConfiguration httpConfig, ISession session, int inputBufferSize, ServerSessionListener listener) + { + super(byteBufferPool, executor, endPoint, session, inputBufferSize); this.listener = listener; this.httpConfig = httpConfig; } diff -Nru jetty9-9.4.50/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerSession.java jetty9-9.4.57/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerSession.java --- jetty9-9.4.50/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerSession.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerSession.java 2024-12-19 21:51:26.000000000 +0000 @@ -37,6 +37,7 @@ import org.eclipse.jetty.http2.frames.SettingsFrame; import org.eclipse.jetty.http2.frames.WindowUpdateFrame; import org.eclipse.jetty.http2.generator.Generator; +import org.eclipse.jetty.http2.parser.Parser; import org.eclipse.jetty.http2.parser.ServerParser; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.Callback; @@ -50,9 +51,16 @@ private final ServerSessionListener listener; + @Deprecated public HTTP2ServerSession(Scheduler scheduler, EndPoint endPoint, Generator generator, ServerSessionListener listener, FlowControlStrategy flowControl) { - super(scheduler, endPoint, generator, listener, flowControl, 2); + this(scheduler, endPoint, null, generator, listener, flowControl); + throw new UnsupportedOperationException(); + } + + public HTTP2ServerSession(Scheduler scheduler, EndPoint endPoint, Parser parser, Generator generator, ServerSessionListener listener, FlowControlStrategy flowControl) + { + super(scheduler, endPoint, parser, generator, listener, flowControl, 2); this.listener = listener; } @@ -104,10 +112,11 @@ { onStreamOpened(stream); stream.process(frame, Callback.NOOP); - if (stream.updateClose(frame.isEndStream(), CloseState.Event.RECEIVED)) - removeStream(stream); + boolean closed = stream.updateClose(frame.isEndStream(), CloseState.Event.RECEIVED); Stream.Listener listener = notifyNewStream(stream, frame); stream.setListener(listener); + if (closed) + removeStream(stream); } } } @@ -126,9 +135,10 @@ if (stream != null) { stream.process(frame, Callback.NOOP); - if (stream.updateClose(frame.isEndStream(), CloseState.Event.RECEIVED)) - removeStream(stream); + boolean closed = stream.updateClose(frame.isEndStream(), CloseState.Event.RECEIVED); notifyHeaders(stream, frame); + if (closed) + removeStream(stream); } else { diff -Nru jetty9-9.4.50/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/CloseTest.java jetty9-9.4.57/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/CloseTest.java --- jetty9-9.4.50/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/CloseTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/CloseTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -26,7 +26,6 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.UnaryOperator; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpVersion; @@ -92,7 +91,8 @@ output.write(BufferUtil.toArray(buffer)); } - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onHeaders(HeadersFrame frame) @@ -109,8 +109,7 @@ throw new RuntimeIOException(x); } } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); parseResponse(client, parser); @@ -157,7 +156,8 @@ // Don't close the connection; the server should close. final CountDownLatch responseLatch = new CountDownLatch(1); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onHeaders(HeadersFrame frame) @@ -166,8 +166,7 @@ // HEADERS, the server is able to send us the response. responseLatch.countDown(); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); parseResponse(client, parser); @@ -222,7 +221,8 @@ final CountDownLatch responseLatch = new CountDownLatch(1); final CountDownLatch closeLatch = new CountDownLatch(1); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onHeaders(HeadersFrame frame) @@ -235,8 +235,7 @@ { closeLatch.countDown(); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); parseResponse(client, parser); diff -Nru jetty9-9.4.50/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2CServerTest.java jetty9-9.4.57/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2CServerTest.java --- jetty9-9.4.50/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2CServerTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2CServerTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -30,7 +30,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.UnaryOperator; import org.eclipse.jetty.http.HostPortHttpField; import org.eclipse.jetty.http.HttpFields; @@ -152,7 +151,8 @@ final AtomicReference headersRef = new AtomicReference<>(); final AtomicReference dataRef = new AtomicReference<>(); final AtomicReference latchRef = new AtomicReference<>(new CountDownLatch(2)); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onHeaders(HeadersFrame frame) @@ -167,8 +167,7 @@ dataRef.set(frame); latchRef.get().countDown(); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); parseResponse(client, parser); @@ -246,7 +245,8 @@ final AtomicReference headersRef = new AtomicReference<>(); final AtomicReference dataRef = new AtomicReference<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onSettings(SettingsFrame frame) @@ -267,8 +267,7 @@ dataRef.set(frame); latch.countDown(); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); parseResponse(client, parser); diff -Nru jetty9-9.4.50/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2ServerTest.java jetty9-9.4.57/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2ServerTest.java --- jetty9-9.4.50/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2ServerTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2ServerTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -33,7 +33,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.UnaryOperator; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -95,15 +94,15 @@ } final CountDownLatch latch = new CountDownLatch(1); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onGoAway(GoAwayFrame frame) { latch.countDown(); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); parseResponse(client, parser); @@ -139,7 +138,8 @@ } final AtomicReference frameRef = new AtomicReference<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onSettings(SettingsFrame frame) @@ -153,8 +153,7 @@ frameRef.set(frame); latch.countDown(); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); parseResponse(client, parser); @@ -198,7 +197,8 @@ final AtomicReference headersRef = new AtomicReference<>(); final AtomicReference dataRef = new AtomicReference<>(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onSettings(SettingsFrame frame) @@ -219,8 +219,7 @@ dataRef.set(frame); latch.countDown(); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); parseResponse(client, parser); @@ -258,7 +257,8 @@ output.write(BufferUtil.toArray(buffer)); } - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onGoAway(GoAwayFrame frame) @@ -266,8 +266,7 @@ assertEquals(ErrorCode.FRAME_SIZE_ERROR.code, frame.getError()); latch.countDown(); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); parseResponse(client, parser); @@ -296,7 +295,8 @@ output.write(BufferUtil.toArray(buffer)); } - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onGoAway(GoAwayFrame frame) @@ -304,8 +304,7 @@ assertEquals(ErrorCode.PROTOCOL_ERROR.code, frame.getError()); latch.countDown(); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); parseResponse(client, parser); @@ -373,8 +372,8 @@ // The server will close the connection abruptly since it // cannot write and therefore cannot even send the GO_AWAY. - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter(), 4096, 8192); - parser.init(UnaryOperator.identity()); + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter()); boolean closed = parseResponse(client, parser, 2 * delay); assertTrue(closed); } @@ -411,8 +410,8 @@ } output.flush(); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter(), 4096, 8192); - parser.init(UnaryOperator.identity()); + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter()); boolean closed = parseResponse(client, parser); assertTrue(closed); @@ -584,7 +583,8 @@ assertTrue(serverLatch.await(5, TimeUnit.SECONDS)); final CountDownLatch clientLatch = new CountDownLatch(1); - Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + Parser parser = new Parser(byteBufferPool, 4096); + parser.init(new Parser.Listener.Adapter() { @Override public void onHeaders(HeadersFrame frame) @@ -592,8 +592,7 @@ if (frame.isEndStream()) clientLatch.countDown(); } - }, 4096, 8192); - parser.init(UnaryOperator.identity()); + }); boolean closed = parseResponse(client, parser); assertTrue(clientLatch.await(5, TimeUnit.SECONDS)); diff -Nru jetty9-9.4.50/jetty-http2/pom.xml jetty9-9.4.57/jetty-http2/pom.xml --- jetty9-9.4.50/jetty-http2/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-http2/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-infinispan/infinispan-common/pom.xml jetty9-9.4.57/jetty-infinispan/infinispan-common/pom.xml --- jetty9-9.4.50/jetty-infinispan/infinispan-common/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-infinispan/infinispan-common/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 infinispan-common @@ -43,6 +43,10 @@ org.wildfly.common wildfly-common + + org.jboss.logging + jboss-logging + @@ -51,6 +55,16 @@ ${infinispan.protostream.version} true provided + + + org.jboss.logging + jboss-logging + + + + + org.jboss.logging + jboss-logging org.eclipse.jetty @@ -67,12 +81,22 @@ org.apache.logging.log4j * + + org.jboss.logging + jboss-logging + org.infinispan infinispan-remote-query-client provided + + + org.jboss.logging + jboss-logging + + diff -Nru jetty9-9.4.50/jetty-infinispan/infinispan-common/src/main/config/etc/sessions/infinispan/infinispan-common.xml jetty9-9.4.57/jetty-infinispan/infinispan-common/src/main/config/etc/sessions/infinispan/infinispan-common.xml --- jetty9-9.4.50/jetty-infinispan/infinispan-common/src/main/config/etc/sessions/infinispan/infinispan-common.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-infinispan/infinispan-common/src/main/config/etc/sessions/infinispan/infinispan-common.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-infinispan/infinispan-embedded/pom.xml jetty9-9.4.57/jetty-infinispan/infinispan-embedded/pom.xml --- jetty9-9.4.50/jetty-infinispan/infinispan-embedded/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-infinispan/infinispan-embedded/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 infinispan-embedded @@ -78,15 +78,5 @@ infinispan-common ${project.version} - - org.infinispan - infinispan-core - - - org.wildfly.common - wildfly-common - - - diff -Nru jetty9-9.4.50/jetty-infinispan/infinispan-embedded/src/main/config-template/etc/sessions/infinispan/infinispan-embedded.xml jetty9-9.4.57/jetty-infinispan/infinispan-embedded/src/main/config-template/etc/sessions/infinispan/infinispan-embedded.xml --- jetty9-9.4.50/jetty-infinispan/infinispan-embedded/src/main/config-template/etc/sessions/infinispan/infinispan-embedded.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-infinispan/infinispan-embedded/src/main/config-template/etc/sessions/infinispan/infinispan-embedded.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-infinispan/infinispan-embedded-query/pom.xml jetty9-9.4.57/jetty-infinispan/infinispan-embedded-query/pom.xml --- jetty9-9.4.50/jetty-infinispan/infinispan-embedded-query/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-infinispan/infinispan-embedded-query/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 infinispan-embedded-query @@ -89,11 +89,16 @@ org.infinispan infinispan-query + + + org.jboss.logging + jboss-logging + + - org.eclipse.jetty.toolchain - jetty-test-helper - test + org.jboss.logging + jboss-logging diff -Nru jetty9-9.4.50/jetty-infinispan/infinispan-embedded-query/src/main/config-template/etc/sessions/infinispan/infinispan-embedded-query.xml jetty9-9.4.57/jetty-infinispan/infinispan-embedded-query/src/main/config-template/etc/sessions/infinispan/infinispan-embedded-query.xml --- jetty9-9.4.50/jetty-infinispan/infinispan-embedded-query/src/main/config-template/etc/sessions/infinispan/infinispan-embedded-query.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-infinispan/infinispan-embedded-query/src/main/config-template/etc/sessions/infinispan/infinispan-embedded-query.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-infinispan/infinispan-remote/pom.xml jetty9-9.4.57/jetty-infinispan/infinispan-remote/pom.xml --- jetty9-9.4.50/jetty-infinispan/infinispan-remote/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-infinispan/infinispan-remote/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 infinispan-remote @@ -88,6 +88,10 @@ org.apache.logging.log4j * + + org.jboss.logging + jboss-logging + @@ -100,6 +104,12 @@ protostream ${infinispan.protostream.version} provided + + + org.jboss.logging + jboss-logging + + diff -Nru jetty9-9.4.50/jetty-infinispan/infinispan-remote/src/main/config-template/etc/sessions/infinispan/infinispan-remote.xml jetty9-9.4.57/jetty-infinispan/infinispan-remote/src/main/config-template/etc/sessions/infinispan/infinispan-remote.xml --- jetty9-9.4.50/jetty-infinispan/infinispan-remote/src/main/config-template/etc/sessions/infinispan/infinispan-remote.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-infinispan/infinispan-remote/src/main/config-template/etc/sessions/infinispan/infinispan-remote.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-infinispan/infinispan-remote-query/pom.xml jetty9-9.4.57/jetty-infinispan/infinispan-remote-query/pom.xml --- jetty9-9.4.50/jetty-infinispan/infinispan-remote-query/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-infinispan/infinispan-remote-query/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 infinispan-remote-query @@ -99,6 +99,12 @@ org.infinispan infinispan-query + + + org.jboss.logging + jboss-logging + + org.infinispan @@ -109,11 +115,21 @@ org.apache.logging.log4j * + + org.jboss.logging + jboss-logging + org.infinispan infinispan-remote-query-client + + + org.jboss.logging + jboss-logging + + com.google.code.gson @@ -131,6 +147,11 @@ test + commons-codec + commons-codec + test + + org.testcontainers junit-jupiter test diff -Nru jetty9-9.4.50/jetty-infinispan/infinispan-remote-query/src/main/config-template/etc/sessions/infinispan/infinispan-remote-query.xml jetty9-9.4.57/jetty-infinispan/infinispan-remote-query/src/main/config-template/etc/sessions/infinispan/infinispan-remote-query.xml --- jetty9-9.4.50/jetty-infinispan/infinispan-remote-query/src/main/config-template/etc/sessions/infinispan/infinispan-remote-query.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-infinispan/infinispan-remote-query/src/main/config-template/etc/sessions/infinispan/infinispan-remote-query.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-infinispan/pom.xml jetty9-9.4.57/jetty-infinispan/pom.xml --- jetty9-9.4.50/jetty-infinispan/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-infinispan/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-io/pom.xml jetty9-9.4.57/jetty-io/pom.xml --- jetty9-9.4.50/jetty-io/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-io/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-io diff -Nru jetty9-9.4.50/jetty-jaas/pom.xml jetty9-9.4.57/jetty-jaas/pom.xml --- jetty9-9.4.50/jetty-jaas/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-jaas/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-jaas @@ -12,7 +12,7 @@ ${project.groupId}.jaas 2.0.0.AM26 - 2.1.2 + 2.1.5 org.eclipse.jetty.jaas.* diff -Nru jetty9-9.4.50/jetty-jaas/src/main/config/etc/jetty-jaas.xml jetty9-9.4.57/jetty-jaas/src/main/config/etc/jetty-jaas.xml --- jetty9-9.4.50/jetty-jaas/src/main/config/etc/jetty-jaas.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-jaas/src/main/config/etc/jetty-jaas.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-jaas/src/main/config/modules/jaas.mod jetty9-9.4.57/jetty-jaas/src/main/config/modules/jaas.mod --- jetty9-9.4.50/jetty-jaas/src/main/config/modules/jaas.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-jaas/src/main/config/modules/jaas.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enable JAAS for deployed webapplications. diff -Nru jetty9-9.4.50/jetty-jaspi/pom.xml jetty9-9.4.57/jetty-jaspi/pom.xml --- jetty9-9.4.50/jetty-jaspi/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-jaspi/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 @@ -62,7 +62,8 @@ org.glassfish.jaxb jaxb-runtime - 2.3.3 + + 3.0.2 test diff -Nru jetty9-9.4.50/jetty-jaspi/src/main/config/modules/jaspi.mod jetty9-9.4.57/jetty-jaspi/src/main/config/modules/jaspi.mod --- jetty9-9.4.50/jetty-jaspi/src/main/config/modules/jaspi.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-jaspi/src/main/config/modules/jaspi.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enable JASPI authentication for deployed webapplications. diff -Nru jetty9-9.4.50/jetty-jmh/pom.xml jetty9-9.4.57/jetty-jmh/pom.xml --- jetty9-9.4.50/jetty-jmh/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-jmh/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 @@ -58,6 +58,24 @@ + + + + org.apache.maven.plugins + maven-jar-plugin + + + + + + + Jetty Jmh Support Classes + + + + + + diff -Nru jetty9-9.4.50/jetty-jmx/pom.xml jetty9-9.4.57/jetty-jmx/pom.xml --- jetty9-9.4.50/jetty-jmx/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-jmx/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-jmx diff -Nru jetty9-9.4.50/jetty-jmx/src/main/config/etc/jetty-jmx-remote.xml jetty9-9.4.57/jetty-jmx/src/main/config/etc/jetty-jmx-remote.xml --- jetty9-9.4.50/jetty-jmx/src/main/config/etc/jetty-jmx-remote.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-jmx/src/main/config/etc/jetty-jmx-remote.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-jmx/src/main/config/etc/jetty-jmx.xml jetty9-9.4.57/jetty-jmx/src/main/config/etc/jetty-jmx.xml --- jetty9-9.4.50/jetty-jmx/src/main/config/etc/jetty-jmx.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-jmx/src/main/config/etc/jetty-jmx.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ - + diff -Nru jetty9-9.4.50/jetty-jmx/src/main/config/modules/jmx-remote.mod jetty9-9.4.57/jetty-jmx/src/main/config/modules/jmx-remote.mod --- jetty9-9.4.50/jetty-jmx/src/main/config/modules/jmx-remote.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-jmx/src/main/config/modules/jmx-remote.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables remote RMI access to JMX diff -Nru jetty9-9.4.50/jetty-jmx/src/main/config/modules/jmx.mod jetty9-9.4.57/jetty-jmx/src/main/config/modules/jmx.mod --- jetty9-9.4.50/jetty-jmx/src/main/config/modules/jmx.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-jmx/src/main/config/modules/jmx.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables JMX instrumentation for server beans and diff -Nru jetty9-9.4.50/jetty-jndi/pom.xml jetty9-9.4.57/jetty-jndi/pom.xml --- jetty9-9.4.50/jetty-jndi/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-jndi/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-jndi diff -Nru jetty9-9.4.50/jetty-jndi/src/main/jndi-config/modules/jndi.mod jetty9-9.4.57/jetty-jndi/src/main/jndi-config/modules/jndi.mod --- jetty9-9.4.50/jetty-jndi/src/main/jndi-config/modules/jndi.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-jndi/src/main/jndi-config/modules/jndi.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Adds the Jetty JNDI implementation to the classpath. diff -Nru jetty9-9.4.50/jetty-jndi/src/main/jndi-config/modules/mail.mod jetty9-9.4.57/jetty-jndi/src/main/jndi-config/modules/mail.mod --- jetty9-9.4.50/jetty-jndi/src/main/jndi-config/modules/mail.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-jndi/src/main/jndi-config/modules/mail.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Adds the javax.mail implementation to the classpath. diff -Nru jetty9-9.4.50/jetty-jspc-maven-plugin/pom.xml jetty9-9.4.57/jetty-jspc-maven-plugin/pom.xml --- jetty9-9.4.50/jetty-jspc-maven-plugin/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-jspc-maven-plugin/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-jspc-maven-plugin diff -Nru jetty9-9.4.50/jetty-jspc-maven-plugin/src/main/java/org/eclipse/jetty/jspc/plugin/JspcMojo.java jetty9-9.4.57/jetty-jspc-maven-plugin/src/main/java/org/eclipse/jetty/jspc/plugin/JspcMojo.java --- jetty9-9.4.50/jetty-jspc-maven-plugin/src/main/java/org/eclipse/jetty/jspc/plugin/JspcMojo.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-jspc-maven-plugin/src/main/java/org/eclipse/jetty/jspc/plugin/JspcMojo.java 2024-12-19 21:51:26.000000000 +0000 @@ -65,7 +65,7 @@ * jsps, which will be the Eclipse java compiler. *

    * See Usage + * href="https://jetty.org/docs/9/jetty-jspc-maven-plugin.html">Usage * Guide for instructions on using this plugin. *

    * Runs jspc compiler to produce .java and .class files diff -Nru jetty9-9.4.50/jetty-jspc-maven-plugin/src/site/site.xml jetty9-9.4.57/jetty-jspc-maven-plugin/src/site/site.xml --- jetty9-9.4.50/jetty-jspc-maven-plugin/src/site/site.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-jspc-maven-plugin/src/site/site.xml 2024-12-19 21:51:26.000000000 +0000 @@ -6,8 +6,8 @@ ${project.name} - https://www.eclipse.org/jetty/images/jetty-logo-80x22.png - https://eclipse.org/jetty/ + https://jetty.org/images/jetty-logo-80x22.png + https://jetty.org/ https://www.eclipse.org/eclipse.org-common/themes/solstice/public/images/logo/eclipse-426x100.png diff -Nru jetty9-9.4.50/jetty-maven-plugin/pom.xml jetty9-9.4.57/jetty-maven-plugin/pom.xml --- jetty9-9.4.50/jetty-maven-plugin/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-maven-plugin @@ -54,6 +54,11 @@ integration-test verify + + + org.eclipse.jetty:jetty-home:${project.version}:zip + + @@ -110,6 +115,10 @@ maven-core
    + org.codehaus.plexus + plexus-xml + + org.apache.maven.plugin-tools maven-plugin-tools-api diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-cdi-run-forked/src/main/jetty/jetty-context.xml jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-cdi-run-forked/src/main/jetty/jetty-context.xml --- jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-cdi-run-forked/src/main/jetty/jetty-context.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-cdi-run-forked/src/main/jetty/jetty-context.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-cdi-run-forked/src/main/jetty/jetty.xml jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-cdi-run-forked/src/main/jetty/jetty.xml --- jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-cdi-run-forked/src/main/jetty/jetty.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-cdi-run-forked/src/main/jetty/jetty.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/src/config/jetty.xml jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/src/config/jetty.xml --- jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/src/config/jetty.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/src/config/jetty.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/src/config/jetty.xml jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/src/config/jetty.xml --- jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/src/config/jetty.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/src/config/jetty.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml --- jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/modules/testmod.mod jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/modules/testmod.mod --- jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/modules/testmod.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/modules/testmod.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables test setup diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/src/config/jetty.xml jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/src/config/jetty.xml --- jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/src/config/jetty.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/src/config/jetty.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/context.xml jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/context.xml --- jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/context.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/context.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/jetty.xml jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/jetty.xml --- jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/jetty.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/jetty.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyWebApp/src/config/context.xml jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyWebApp/src/config/context.xml --- jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyWebApp/src/config/context.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyWebApp/src/config/context.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyWebApp/src/config/jetty.xml jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyWebApp/src/config/jetty.xml --- jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyWebApp/src/config/jetty.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyWebApp/src/config/jetty.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/src/config/jetty.xml jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/src/config/jetty.xml --- jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/src/config/jetty.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/src/config/jetty.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/webapp-war/src/config/jetty.xml jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/webapp-war/src/config/jetty.xml --- jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/webapp-war/src/config/jetty.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/webapp-war/src/config/jetty.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/src/config/jetty.xml jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/src/config/jetty.xml --- jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/src/config/jetty.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/src/config/jetty.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/src/config/jetty.xml jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/src/config/jetty.xml --- jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/src/config/jetty.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/src/config/jetty.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/config/jetty.xml jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/config/jetty.xml --- jetty9-9.4.50/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/config/jetty.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/config/jetty.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/config/jetty.xml jetty9-9.4.57/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/config/jetty.xml --- jetty9-9.4.50/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/config/jetty.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/config/jetty.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,5 @@ - + + diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/jettyconf/context.xml jetty9-9.4.57/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/jettyconf/context.xml --- jetty9-9.4.50/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/jettyconf/context.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/jettyconf/context.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,3 +1,6 @@ + + + org.eclipse.jetty.servlet.Default.useFileMappedBuffer diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEffectiveWebXml.java jetty9-9.4.57/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEffectiveWebXml.java --- jetty9-9.4.50/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEffectiveWebXml.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEffectiveWebXml.java 2024-12-19 21:51:26.000000000 +0000 @@ -39,7 +39,7 @@ * files. By default, the web.xml is generated to the console output only. Use the effectiveWebXml parameter * to provide a file name into which to save the output. * - * See https://www.eclipse.org/jetty/documentation for more information on this and other jetty plugins. + * See https://jetty.org/docs/ for more information on this and other jetty plugins. * * Runs jetty on the unassembled webapp to generate the effective web.xml */ diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunDistro.java jetty9-9.4.57/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunDistro.java --- jetty9-9.4.50/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunDistro.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunDistro.java 2024-12-19 21:51:26.000000000 +0000 @@ -78,7 +78,7 @@ * * This goal does NOT support the scanIntervalSeconds parameter: the webapp will be deployed only once. * - * See https://www.eclipse.org/jetty/documentation for more information on this and other jetty plugins. + * See https://jetty.org/docs/ for more information on this and other jetty plugins. * * Runs unassembled webapp in a locally installed jetty distro */ diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunForkedMojo.java jetty9-9.4.57/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunForkedMojo.java --- jetty9-9.4.50/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunForkedMojo.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunForkedMojo.java 2024-12-19 21:51:26.000000000 +0000 @@ -62,7 +62,7 @@ * By setting the configuration element waitForChild to false, the plugin will terminate after having forked the jetty process. In this case * you can use the jetty:stop goal to terminate the process. *

    - * See https://www.eclipse.org/jetty/documentation for more information on this and other jetty plugins. + * See https://jetty.org/docs/ for more information on this and other jetty plugins. * * Runs Jetty in forked JVM on an unassembled webapp */ diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunMojo.java jetty9-9.4.57/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunMojo.java --- jetty9-9.4.50/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunMojo.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunMojo.java 2024-12-19 21:51:26.000000000 +0000 @@ -61,7 +61,7 @@ * You may also specify the location of a jetty.xml file whose contents will be applied before any plugin configuration. * This can be used, for example, to deploy a static webapp that is not part of your maven build. *

    - * There is a reference guide to the configuration parameters for this plugin. + * There is a reference guide to the configuration parameters for this plugin. * * Runs jetty directly from a maven project */ diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/main/resources/jetty-maven.xml jetty9-9.4.57/jetty-maven-plugin/src/main/resources/jetty-maven.xml --- jetty9-9.4.50/jetty-maven-plugin/src/main/resources/jetty-maven.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/main/resources/jetty-maven.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/main/resources/maven.mod jetty9-9.4.57/jetty-maven-plugin/src/main/resources/maven.mod --- jetty9-9.4.50/jetty-maven-plugin/src/main/resources/maven.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/main/resources/maven.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables an unassembled maven webapp to run in a jetty distro diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/main/resources/maven.xml jetty9-9.4.57/jetty-maven-plugin/src/main/resources/maven.xml --- jetty9-9.4.50/jetty-maven-plugin/src/main/resources/maven.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/main/resources/maven.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-maven-plugin/src/site/site.xml jetty9-9.4.57/jetty-maven-plugin/src/site/site.xml --- jetty9-9.4.50/jetty-maven-plugin/src/site/site.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-maven-plugin/src/site/site.xml 2024-12-19 21:51:26.000000000 +0000 @@ -6,8 +6,8 @@ ${project.name} - https://www.eclipse.org/jetty/images/jetty-logo-80x22.png - https://eclipse.org/jetty/ + https://jetty.org/images/jetty-logo-80x22.png + https://jetty.org/ https://www.eclipse.org/eclipse.org-common/themes/solstice/public/images/logo/eclipse-426x100.png diff -Nru jetty9-9.4.50/jetty-memcached/jetty-memcached-sessions/pom.xml jetty9-9.4.57/jetty-memcached/jetty-memcached-sessions/pom.xml --- jetty9-9.4.50/jetty-memcached/jetty-memcached-sessions/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-memcached/jetty-memcached-sessions/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.memcached memcached-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-memcached/jetty-memcached-sessions/src/main/config/etc/sessions/session-data-cache/xmemcached.xml jetty9-9.4.57/jetty-memcached/jetty-memcached-sessions/src/main/config/etc/sessions/session-data-cache/xmemcached.xml --- jetty9-9.4.50/jetty-memcached/jetty-memcached-sessions/src/main/config/etc/sessions/session-data-cache/xmemcached.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-memcached/jetty-memcached-sessions/src/main/config/etc/sessions/session-data-cache/xmemcached.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-memcached/jetty-memcached-sessions/src/main/config/modules/sessions/session-data-cache/xmemcached.mod jetty9-9.4.57/jetty-memcached/jetty-memcached-sessions/src/main/config/modules/sessions/session-data-cache/xmemcached.mod --- jetty9-9.4.50/jetty-memcached/jetty-memcached-sessions/src/main/config/modules/sessions/session-data-cache/xmemcached.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-memcached/jetty-memcached-sessions/src/main/config/modules/sessions/session-data-cache/xmemcached.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Memcache cache for SessionData diff -Nru jetty9-9.4.50/jetty-memcached/pom.xml jetty9-9.4.57/jetty-memcached/pom.xml --- jetty9-9.4.50/jetty-memcached/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-memcached/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-nosql/pom.xml jetty9-9.4.57/jetty-nosql/pom.xml --- jetty9-9.4.50/jetty-nosql/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-nosql/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-nosql diff -Nru jetty9-9.4.50/jetty-nosql/src/main/config/etc/sessions/mongo/session-store-by-address.xml jetty9-9.4.57/jetty-nosql/src/main/config/etc/sessions/mongo/session-store-by-address.xml --- jetty9-9.4.50/jetty-nosql/src/main/config/etc/sessions/mongo/session-store-by-address.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-nosql/src/main/config/etc/sessions/mongo/session-store-by-address.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-nosql/src/main/config/etc/sessions/mongo/session-store-by-uri.xml jetty9-9.4.57/jetty-nosql/src/main/config/etc/sessions/mongo/session-store-by-uri.xml --- jetty9-9.4.50/jetty-nosql/src/main/config/etc/sessions/mongo/session-store-by-uri.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-nosql/src/main/config/etc/sessions/mongo/session-store-by-uri.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-nosql/src/main/config/modules/session-store-mongo.mod jetty9-9.4.57/jetty-nosql/src/main/config/modules/session-store-mongo.mod --- jetty9-9.4.50/jetty-nosql/src/main/config/modules/session-store-mongo.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-nosql/src/main/config/modules/session-store-mongo.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables NoSql session management with a MongoDB driver. diff -Nru jetty9-9.4.50/jetty-nosql/src/main/config/modules/sessions/mongo/address.mod jetty9-9.4.57/jetty-nosql/src/main/config/modules/sessions/mongo/address.mod --- jetty9-9.4.50/jetty-nosql/src/main/config/modules/sessions/mongo/address.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-nosql/src/main/config/modules/sessions/mongo/address.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Server/port address connections for session storage diff -Nru jetty9-9.4.50/jetty-nosql/src/main/config/modules/sessions/mongo/uri.mod jetty9-9.4.57/jetty-nosql/src/main/config/modules/sessions/mongo/uri.mod --- jetty9-9.4.50/jetty-nosql/src/main/config/modules/sessions/mongo/uri.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-nosql/src/main/config/modules/sessions/mongo/uri.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] MongoURI connections for session storage diff -Nru jetty9-9.4.50/jetty-openid/pom.xml jetty9-9.4.57/jetty-openid/pom.xml --- jetty9-9.4.50/jetty-openid/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-openid/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-openid/src/main/config/etc/jetty-openid.xml jetty9-9.4.57/jetty-openid/src/main/config/etc/jetty-openid.xml --- jetty9-9.4.50/jetty-openid/src/main/config/etc/jetty-openid.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-openid/src/main/config/etc/jetty-openid.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ - + diff -Nru jetty9-9.4.50/jetty-openid/src/main/config/modules/openid/openid-baseloginservice.xml jetty9-9.4.57/jetty-openid/src/main/config/modules/openid/openid-baseloginservice.xml --- jetty9-9.4.50/jetty-openid/src/main/config/modules/openid/openid-baseloginservice.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-openid/src/main/config/modules/openid/openid-baseloginservice.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ - + diff -Nru jetty9-9.4.50/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml jetty9-9.4.57/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml --- jetty9-9.4.50/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,12 +1,12 @@ - + - + diff -Nru jetty9-9.4.50/jetty-osgi/jetty-osgi-boot/pom.xml jetty9-9.4.57/jetty-osgi/jetty-osgi-boot/pom.xml --- jetty9-9.4.50/jetty-osgi/jetty-osgi-boot/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/jetty-osgi-boot/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-osgi-boot diff -Nru jetty9-9.4.50/jetty-osgi/jetty-osgi-boot-jsp/pom.xml jetty9-9.4.57/jetty-osgi/jetty-osgi-boot-jsp/pom.xml --- jetty9-9.4.50/jetty-osgi/jetty-osgi-boot-jsp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/jetty-osgi-boot-jsp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-osgi-boot-jsp diff -Nru jetty9-9.4.50/jetty-osgi/jetty-osgi-boot-warurl/pom.xml jetty9-9.4.57/jetty-osgi/jetty-osgi-boot-warurl/pom.xml --- jetty9-9.4.50/jetty-osgi/jetty-osgi-boot-warurl/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/jetty-osgi-boot-warurl/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.50.v20221107 + 9.4.57.v20241219 ../pom.xml 4.0.0 diff -Nru jetty9-9.4.50/jetty-osgi/jetty-osgi-httpservice/contexts/httpservice.xml jetty9-9.4.57/jetty-osgi/jetty-osgi-httpservice/contexts/httpservice.xml --- jetty9-9.4.50/jetty-osgi/jetty-osgi-httpservice/contexts/httpservice.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/jetty-osgi-httpservice/contexts/httpservice.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-osgi/jetty-osgi-httpservice/pom.xml jetty9-9.4.57/jetty-osgi/jetty-osgi-httpservice/pom.xml --- jetty9-9.4.50/jetty-osgi/jetty-osgi-httpservice/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/jetty-osgi-httpservice/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-httpservice diff -Nru jetty9-9.4.50/jetty-osgi/pom.xml jetty9-9.4.57/jetty-osgi/pom.xml --- jetty9-9.4.50/jetty-osgi/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 @@ -12,14 +12,15 @@ pom - 3.18.100 - 3.11.0 + 3.21.0 + + 3.11.200 1.6.1 - 1.5.0 + 1.5.1 1.4.1 - 3.7.100 + 3.7.300 1.2.0 - 1.2.0 + 1.3.0 1.0.2 1.0.1 1.5.4 @@ -165,6 +166,11 @@ servlet-api + + org.eclipse.jetty.toolchain + jetty-servlet-api + + org.apache.felix org.osgi.foundation @@ -226,6 +232,11 @@ org.osgi.util.tracker ${osgi-util-tracker-version} + + org.osgi + org.osgi.util.promise + ${osgi-util-promise-version} + diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi/pom.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi/pom.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.50.v20221107 + 9.4.57.v20241219 ../pom.xml 4.0.0 @@ -13,8 +13,8 @@ ${project.groupId}.boot.test.osgi https://download.eclipse.org/jetty/orbit/ target/distribution - 4.13.1 - 2.6.2 + 4.13.5 + 2.6.14 5.3.0 1.8.3 3.0.0 @@ -193,7 +193,7 @@ org.apache.aries.spifly org.apache.aries.spifly.dynamic.bundle - 1.3.5 + 1.3.7 test @@ -453,7 +453,7 @@ org.slf4j - slf4j-log4j12 + slf4j-reload4j ${slf4j.version} test diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-alpn.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-alpn.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-alpn.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-alpn.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-deploy.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-deploy.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-deploy.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-deploy.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-context-as-service.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-context-as-service.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-context-as-service.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-context-as-service.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-webapp-as-service.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-webapp-as-service.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-webapp-as-service.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-webapp-as-service.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-annotations.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-annotations.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-annotations.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-annotations.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-javax-websocket.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-javax-websocket.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-javax-websocket.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-javax-websocket.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-jsp.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-jsp.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-jsp.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-jsp.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-resources.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-resources.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-resources.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-resources.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-websocket.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-websocket.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-websocket.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-websocket.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http2-jdk9.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http2-jdk9.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http2-jdk9.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http2-jdk9.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http2.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http2.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http2.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http2.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-https.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-https.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-https.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-https.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-ssl.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-ssl.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-ssl.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-ssl.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ - + diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-testrealm.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-testrealm.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-testrealm.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-testrealm.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,12 +1,12 @@ - + - + diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestOSGiUtil.java jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestOSGiUtil.java --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestOSGiUtil.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestOSGiUtil.java 2024-12-19 21:51:26.000000000 +0000 @@ -127,14 +127,20 @@ res.add(mavenBundle().groupId("org.osgi").artifactId("org.osgi.service.component").versionAsInProject()); res.add(mavenBundle().groupId("org.osgi").artifactId("org.osgi.service.event").versionAsInProject()); res.add(mavenBundle().groupId("org.osgi").artifactId("org.osgi.util.function").versionAsInProject()); - res.add(mavenBundle().groupId("org.osgi").artifactId("org.osgi.util.function").versionAsInProject()); res.add(mavenBundle().groupId("org.osgi").artifactId("org.osgi.util.promise").versionAsInProject()); res.add(mavenBundle().groupId("org.osgi").artifactId("org.osgi.util.measurement").versionAsInProject()); res.add(mavenBundle().groupId("org.osgi").artifactId("org.osgi.util.position").versionAsInProject()); res.add(mavenBundle().groupId("org.osgi").artifactId("org.osgi.util.tracker").versionAsInProject()); res.add(mavenBundle().groupId("org.osgi").artifactId("org.osgi.util.xml").versionAsInProject()); + res.add(mavenBundle().groupId("org.osgi").artifactId("org.osgi.service.device").versionAsInProject()); + res.add(mavenBundle().groupId("org.osgi").artifactId("org.osgi.service.metatype").versionAsInProject()); + res.add(mavenBundle().groupId("org.osgi").artifactId("org.osgi.service.provisioning").versionAsInProject()); + res.add(mavenBundle().groupId("org.osgi").artifactId("org.osgi.service.upnp").versionAsInProject()); + res.add(mavenBundle().groupId("org.osgi").artifactId("org.osgi.service.useradmin").versionAsInProject()); + res.add(mavenBundle().groupId("org.osgi").artifactId("org.osgi.service.wireadmin").versionAsInProject()); res.add(mavenBundle().groupId("org.eclipse.platform").artifactId("org.eclipse.osgi.util").versionAsInProject()); res.add(mavenBundle().groupId("org.eclipse.platform").artifactId("org.eclipse.osgi.services").versionAsInProject()); + res.add(mavenBundle().groupId("org.ow2.asm").artifactId("asm").versionAsInProject().start()); res.add(mavenBundle().groupId("org.ow2.asm").artifactId("asm-commons").versionAsInProject().start()); res.add(mavenBundle().groupId("org.ow2.asm").artifactId("asm-tree").versionAsInProject().start()); diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi-context/pom.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi-context/pom.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi-context/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi-context/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 test-jetty-osgi-context diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi-context/src/main/context/acme.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi-context/src/main/context/acme.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi-context/src/main/context/acme.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi-context/src/main/context/acme.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi-fragment/pom.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi-fragment/pom.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi-fragment/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi-fragment/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.50.v20221107 + 9.4.57.v20241219 ../pom.xml 4.0.0 diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi-server/pom.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi-server/pom.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi-server/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi-server/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 test-jetty-osgi-server diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi-webapp/pom.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi-webapp/pom.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi-webapp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi-webapp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.50.v20221107 + 9.4.57.v20241219 ../pom.xml 4.0.0 diff -Nru jetty9-9.4.50/jetty-osgi/test-jetty-osgi-webapp-resources/pom.xml jetty9-9.4.57/jetty-osgi/test-jetty-osgi-webapp-resources/pom.xml --- jetty9-9.4.50/jetty-osgi/test-jetty-osgi-webapp-resources/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-osgi/test-jetty-osgi-webapp-resources/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 test-jetty-osgi-webapp-resources diff -Nru jetty9-9.4.50/jetty-plus/pom.xml jetty9-9.4.57/jetty-plus/pom.xml --- jetty9-9.4.50/jetty-plus/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-plus/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-plus diff -Nru jetty9-9.4.50/jetty-plus/src/main/plus-config/etc/jetty-plus.xml jetty9-9.4.57/jetty-plus/src/main/plus-config/etc/jetty-plus.xml --- jetty9-9.4.50/jetty-plus/src/main/plus-config/etc/jetty-plus.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-plus/src/main/plus-config/etc/jetty-plus.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-plus/src/main/plus-config/modules/plus.mod jetty9-9.4.57/jetty-plus/src/main/plus-config/modules/plus.mod --- jetty9-9.4.50/jetty-plus/src/main/plus-config/modules/plus.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-plus/src/main/plus-config/modules/plus.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables JNDI and resource injection for webapplications diff -Nru jetty9-9.4.50/jetty-plus/src/main/plus-config/modules/transactions.mod jetty9-9.4.57/jetty-plus/src/main/plus-config/modules/transactions.mod --- jetty9-9.4.50/jetty-plus/src/main/plus-config/modules/transactions.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-plus/src/main/plus-config/modules/transactions.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Puts javax.transaction api on the classpath diff -Nru jetty9-9.4.50/jetty-proxy/pom.xml jetty9-9.4.57/jetty-proxy/pom.xml --- jetty9-9.4.50/jetty-proxy/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-proxy/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-proxy diff -Nru jetty9-9.4.50/jetty-proxy/src/main/config/etc/jetty-proxy.xml jetty9-9.4.57/jetty-proxy/src/main/config/etc/jetty-proxy.xml --- jetty9-9.4.50/jetty-proxy/src/main/config/etc/jetty-proxy.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-proxy/src/main/config/etc/jetty-proxy.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-proxy/src/main/config/modules/proxy.mod jetty9-9.4.57/jetty-proxy/src/main/config/modules/proxy.mod --- jetty9-9.4.50/jetty-proxy/src/main/config/modules/proxy.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-proxy/src/main/config/modules/proxy.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enable the Jetty Proxy, that allows the server to act diff -Nru jetty9-9.4.50/jetty-quickstart/pom.xml jetty9-9.4.57/jetty-quickstart/pom.xml --- jetty9-9.4.50/jetty-quickstart/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-quickstart/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 org.eclipse.jetty diff -Nru jetty9-9.4.50/jetty-quickstart/src/main/config/etc/example-quickstart.xml jetty9-9.4.57/jetty-quickstart/src/main/config/etc/example-quickstart.xml --- jetty9-9.4.50/jetty-quickstart/src/main/config/etc/example-quickstart.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-quickstart/src/main/config/etc/example-quickstart.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-rewrite/src/main/config/etc/jetty-rewrite.xml jetty9-9.4.57/jetty-rewrite/src/main/config/etc/jetty-rewrite.xml --- jetty9-9.4.50/jetty-rewrite/src/main/config/etc/jetty-rewrite.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-rewrite/src/main/config/etc/jetty-rewrite.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-rewrite/src/main/config/etc/rewrite-compactpath.xml jetty9-9.4.57/jetty-rewrite/src/main/config/etc/rewrite-compactpath.xml --- jetty9-9.4.50/jetty-rewrite/src/main/config/etc/rewrite-compactpath.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-rewrite/src/main/config/etc/rewrite-compactpath.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-rewrite/src/main/config/modules/rewrite-compactpath.mod jetty9-9.4.57/jetty-rewrite/src/main/config/modules/rewrite-compactpath.mod --- jetty9-9.4.50/jetty-rewrite/src/main/config/modules/rewrite-compactpath.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-rewrite/src/main/config/modules/rewrite-compactpath.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Add a rule to the rewrite module to compact paths so that double slashes diff -Nru jetty9-9.4.50/jetty-rewrite/src/main/config/modules/rewrite-customizer.mod jetty9-9.4.57/jetty-rewrite/src/main/config/modules/rewrite-customizer.mod --- jetty9-9.4.50/jetty-rewrite/src/main/config/modules/rewrite-customizer.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-rewrite/src/main/config/modules/rewrite-customizer.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables a rewrite Rules container as a request customizer on diff -Nru jetty9-9.4.50/jetty-rewrite/src/main/config/modules/rewrite.mod jetty9-9.4.57/jetty-rewrite/src/main/config/modules/rewrite.mod --- jetty9-9.4.50/jetty-rewrite/src/main/config/modules/rewrite.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-rewrite/src/main/config/modules/rewrite.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables the jetty-rewrite handler. Specific rewrite diff -Nru jetty9-9.4.50/jetty-rewrite/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml jetty9-9.4.57/jetty-rewrite/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml --- jetty9-9.4.50/jetty-rewrite/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-rewrite/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-runner/pom.xml jetty9-9.4.57/jetty-runner/pom.xml --- jetty9-9.4.50/jetty-runner/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-runner/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-runner @@ -70,8 +70,6 @@ true - - ${project.build.directory}/NON_USED_MANIFEST diff -Nru jetty9-9.4.50/jetty-runner/src/main/java/org/eclipse/jetty/runner/Runner.java jetty9-9.4.57/jetty-runner/src/main/java/org/eclipse/jetty/runner/Runner.java --- jetty9-9.4.50/jetty-runner/src/main/java/org/eclipse/jetty/runner/Runner.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-runner/src/main/java/org/eclipse/jetty/runner/Runner.java 2024-12-19 21:51:26.000000000 +0000 @@ -544,7 +544,7 @@ { System.err.println("WARNING: jetty-runner is deprecated."); System.err.println(" See Jetty Documentation for startup options"); - System.err.println(" https://www.eclipse.org/jetty/documentation/"); + System.err.println(" https://jetty.org/docs/"); Runner runner = new Runner(); diff -Nru jetty9-9.4.50/jetty-security/pom.xml jetty9-9.4.57/jetty-security/pom.xml --- jetty9-9.4.50/jetty-security/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-security/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-security diff -Nru jetty9-9.4.50/jetty-security/src/main/config/modules/security.mod jetty9-9.4.57/jetty-security/src/main/config/modules/security.mod --- jetty9-9.4.50/jetty-security/src/main/config/modules/security.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-security/src/main/config/modules/security.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Adds servlet standard security handling to the classpath. diff -Nru jetty9-9.4.50/jetty-server/pom.xml jetty9-9.4.57/jetty-server/pom.xml --- jetty9-9.4.50/jetty-server/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-server @@ -98,5 +98,10 @@ ${project.version} test + + org.awaitility + awaitility + test + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/home-base-warning.xml jetty9-9.4.57/jetty-server/src/main/config/etc/home-base-warning.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/home-base-warning.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/home-base-warning.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-acceptratelimit.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-acceptratelimit.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-acceptratelimit.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-acceptratelimit.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-bytebufferpool-logarithmic.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-bytebufferpool-logarithmic.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-bytebufferpool-logarithmic.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-bytebufferpool-logarithmic.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-bytebufferpool.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-bytebufferpool.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-bytebufferpool.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-bytebufferpool.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-connectionlimit.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-connectionlimit.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-connectionlimit.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-connectionlimit.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-customrequestlog.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-customrequestlog.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-customrequestlog.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-customrequestlog.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-debug.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-debug.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-debug.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-debug.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-debuglog.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-debuglog.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-debuglog.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-debuglog.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-gzip.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-gzip.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-gzip.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-gzip.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-http-forwarded.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-http-forwarded.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-http-forwarded.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-http-forwarded.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-http.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-http.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-http.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-http.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-https.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-https.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-https.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-https.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-ipaccess.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-ipaccess.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-ipaccess.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-ipaccess.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-lowresources.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-lowresources.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-lowresources.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-lowresources.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-proxy-protocol-ssl.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-proxy-protocol-ssl.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-proxy-protocol-ssl.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-proxy-protocol-ssl.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-proxy-protocol.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-proxy-protocol.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-proxy-protocol.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-proxy-protocol.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-requestlog.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-requestlog.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-requestlog.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-requestlog.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-ssl-context-reload.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-ssl-context-reload.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-ssl-context-reload.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-ssl-context-reload.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-ssl-context.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-ssl-context.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-ssl-context.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-ssl-context.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + @@ -6,7 +6,7 @@ diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-ssl.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-ssl.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-ssl.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-ssl.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-stats.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-stats.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-stats.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-stats.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-threadlimit.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-threadlimit.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-threadlimit.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-threadlimit.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-threadpool.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-threadpool.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty-threadpool.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty-threadpool.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/jetty.xml jetty9-9.4.57/jetty-server/src/main/config/etc/jetty.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/jetty.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/jetty.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,8 +1,8 @@ - + - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/sessions/file/session-store.xml jetty9-9.4.57/jetty-server/src/main/config/etc/sessions/file/session-store.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/sessions/file/session-store.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/sessions/file/session-store.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/sessions/id-manager.xml jetty9-9.4.57/jetty-server/src/main/config/etc/sessions/id-manager.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/sessions/id-manager.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/sessions/id-manager.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/sessions/jdbc/datasource.xml jetty9-9.4.57/jetty-server/src/main/config/etc/sessions/jdbc/datasource.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/sessions/jdbc/datasource.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/sessions/jdbc/datasource.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/sessions/jdbc/driver.xml jetty9-9.4.57/jetty-server/src/main/config/etc/sessions/jdbc/driver.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/sessions/jdbc/driver.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/sessions/jdbc/driver.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/sessions/jdbc/session-store.xml jetty9-9.4.57/jetty-server/src/main/config/etc/sessions/jdbc/session-store.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/sessions/jdbc/session-store.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/sessions/jdbc/session-store.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/sessions/session-cache-hash.xml jetty9-9.4.57/jetty-server/src/main/config/etc/sessions/session-cache-hash.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/sessions/session-cache-hash.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/sessions/session-cache-hash.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/sessions/session-cache-null.xml jetty9-9.4.57/jetty-server/src/main/config/etc/sessions/session-cache-null.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/sessions/session-cache-null.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/sessions/session-cache-null.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/etc/sessions/session-data-cache/session-caching-store.xml jetty9-9.4.57/jetty-server/src/main/config/etc/sessions/session-data-cache/session-caching-store.xml --- jetty9-9.4.50/jetty-server/src/main/config/etc/sessions/session-data-cache/session-caching-store.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/etc/sessions/session-data-cache/session-caching-store.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/acceptratelimit.mod jetty9-9.4.57/jetty-server/src/main/config/modules/acceptratelimit.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/acceptratelimit.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/acceptratelimit.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enable a server wide accept rate limit diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/bytebufferpool-logarithmic.mod jetty9-9.4.57/jetty-server/src/main/config/modules/bytebufferpool-logarithmic.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/bytebufferpool-logarithmic.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/bytebufferpool-logarithmic.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Configures the ByteBufferPool used by ServerConnectors whose bucket sizes increase exponentially instead of linearly. diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/bytebufferpool.mod jetty9-9.4.57/jetty-server/src/main/config/modules/bytebufferpool.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/bytebufferpool.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/bytebufferpool.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Configures the ByteBufferPool used by ServerConnectors. diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/connectionlimit.mod jetty9-9.4.57/jetty-server/src/main/config/modules/connectionlimit.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/connectionlimit.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/connectionlimit.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enable a server wide connection limit diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/continuation.mod jetty9-9.4.57/jetty-server/src/main/config/modules/continuation.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/continuation.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/continuation.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables support for Continuation style asynchronous diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/customrequestlog.mod jetty9-9.4.57/jetty-server/src/main/config/modules/customrequestlog.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/customrequestlog.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/customrequestlog.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables a format string style request log. diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/debug.mod jetty9-9.4.57/jetty-server/src/main/config/modules/debug.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/debug.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/debug.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables the DebugListener to generate additional diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/debuglog.mod jetty9-9.4.57/jetty-server/src/main/config/modules/debuglog.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/debuglog.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/debuglog.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Deprecated Debug Log using the DebugHandle. diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/ext.mod jetty9-9.4.57/jetty-server/src/main/config/modules/ext.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/ext.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/ext.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Adds all jar files discovered in $JETTY_HOME/lib/ext diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/gzip.mod jetty9-9.4.57/jetty-server/src/main/config/modules/gzip.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/gzip.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/gzip.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enable GzipHandler for dynamic gzip compression diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/home-base-warning.mod jetty9-9.4.57/jetty-server/src/main/config/modules/home-base-warning.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/home-base-warning.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/home-base-warning.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Generates a warning that server has been run from $JETTY_HOME diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/http-forwarded.mod jetty9-9.4.57/jetty-server/src/main/config/modules/http-forwarded.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/http-forwarded.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/http-forwarded.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Adds a forwarded request customizer to the HTTP Connector diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/http.mod jetty9-9.4.57/jetty-server/src/main/config/modules/http.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/http.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/http.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables an HTTP connector on the server. diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/https.mod jetty9-9.4.57/jetty-server/src/main/config/modules/https.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/https.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/https.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Adds HTTPS protocol support to the TLS(SSL) Connector diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/inetaccess/jetty-inetaccess.xml jetty9-9.4.57/jetty-server/src/main/config/modules/inetaccess/jetty-inetaccess.xml --- jetty9-9.4.50/jetty-server/src/main/config/modules/inetaccess/jetty-inetaccess.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/inetaccess/jetty-inetaccess.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/inetaccess.mod jetty9-9.4.57/jetty-server/src/main/config/modules/inetaccess.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/inetaccess.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/inetaccess.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enable the InetAccessHandler to apply a include/exclude diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/ipaccess.mod jetty9-9.4.57/jetty-server/src/main/config/modules/ipaccess.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/ipaccess.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/ipaccess.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enable the ipaccess handler to apply a white/black list diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/jdbc.mod jetty9-9.4.57/jetty-server/src/main/config/modules/jdbc.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/jdbc.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/jdbc.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [jpms] add-modules: java.sql diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/jvm.mod jetty9-9.4.57/jetty-server/src/main/config/modules/jvm.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/jvm.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/jvm.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] A noop module that creates an ini template useful for diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/logback-access/jetty-logback-access.xml jetty9-9.4.57/jetty-server/src/main/config/modules/logback-access/jetty-logback-access.xml --- jetty9-9.4.50/jetty-server/src/main/config/modules/logback-access/jetty-logback-access.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/logback-access/jetty-logback-access.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/logback-access.mod jetty9-9.4.57/jetty-server/src/main/config/modules/logback-access.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/logback-access.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/logback-access.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables logback request log. diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/lowresources.mod jetty9-9.4.57/jetty-server/src/main/config/modules/lowresources.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/lowresources.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/lowresources.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables a low resource monitor on the server diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/proxy-protocol-ssl.mod jetty9-9.4.57/jetty-server/src/main/config/modules/proxy-protocol-ssl.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/proxy-protocol-ssl.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/proxy-protocol-ssl.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables the Proxy Protocol on the TLS(SSL) Connector. diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/proxy-protocol.mod jetty9-9.4.57/jetty-server/src/main/config/modules/proxy-protocol.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/proxy-protocol.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/proxy-protocol.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables the Proxy Protocol on the HTTP Connector. diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/requestlog.mod jetty9-9.4.57/jetty-server/src/main/config/modules/requestlog.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/requestlog.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/requestlog.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables a NCSA style request log. diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/resources.mod jetty9-9.4.57/jetty-server/src/main/config/modules/resources.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/resources.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/resources.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Adds the $JETTY_HOME/resources and/or $JETTY_BASE/resources diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/server.mod jetty9-9.4.57/jetty-server/src/main/config/modules/server.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/server.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/server.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables the core Jetty server on the classpath. diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/session-cache-hash.mod jetty9-9.4.57/jetty-server/src/main/config/modules/session-cache-hash.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/session-cache-hash.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/session-cache-hash.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enable first level session cache. If this module is not enabled, sessions will diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/session-cache-null.mod jetty9-9.4.57/jetty-server/src/main/config/modules/session-cache-null.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/session-cache-null.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/session-cache-null.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] A trivial SessionCache that does not actually cache sessions. diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/session-store-cache.mod jetty9-9.4.57/jetty-server/src/main/config/modules/session-store-cache.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/session-store-cache.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/session-store-cache.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables caching of SessionData in front of a SessionDataStore. diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/session-store-file.mod jetty9-9.4.57/jetty-server/src/main/config/modules/session-store-file.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/session-store-file.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/session-store-file.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables session persistent storage in files. diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/session-store-jdbc.mod jetty9-9.4.57/jetty-server/src/main/config/modules/session-store-jdbc.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/session-store-jdbc.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/session-store-jdbc.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables JDBC persistent/distributed session storage. diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/sessions/jdbc/datasource.mod jetty9-9.4.57/jetty-server/src/main/config/modules/sessions/jdbc/datasource.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/sessions/jdbc/datasource.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/sessions/jdbc/datasource.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] JDBC Datasource connections for session storage diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/sessions/jdbc/driver.mod jetty9-9.4.57/jetty-server/src/main/config/modules/sessions/jdbc/driver.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/sessions/jdbc/driver.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/sessions/jdbc/driver.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] JDBC Driver connections for session storage diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/sessions.mod jetty9-9.4.57/jetty-server/src/main/config/modules/sessions.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/sessions.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/sessions.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] The session management. By enabling this module, it allows diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/ssl-reload.mod jetty9-9.4.57/jetty-server/src/main/config/modules/ssl-reload.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/ssl-reload.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/ssl-reload.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables the SSL keystore to be reloaded after any changes are detected on the file system. diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/ssl.mod jetty9-9.4.57/jetty-server/src/main/config/modules/ssl.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/ssl.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/ssl.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables a TLS(SSL) Connector on the server. @@ -124,7 +124,7 @@ # jetty.sslContext.useCipherSuitesOrder=true ## To configure Includes / Excludes for Cipher Suites or Protocols see tweak-ssl.xml example at -## https://www.eclipse.org/jetty/documentation/current/configuring-ssl.html#configuring-sslcontextfactory-cipherSuites +## https://jetty.org/docs/9/configuring-ssl.html#configuring-sslcontextfactory-cipherSuites ## Set the size of the SslSession cache # jetty.sslContext.sslSessionCacheSize=-1 diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/stats.mod jetty9-9.4.57/jetty-server/src/main/config/modules/stats.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/stats.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/stats.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enable detailed statistics collection for the server, diff -Nru jetty9-9.4.50/jetty-server/src/main/config/modules/threadpool.mod jetty9-9.4.57/jetty-server/src/main/config/modules/threadpool.mod --- jetty9-9.4.50/jetty-server/src/main/config/modules/threadpool.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/config/modules/threadpool.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables the Server thread pool. diff -Nru jetty9-9.4.50/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java jetty9-9.4.57/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java --- jetty9-9.4.50/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java 2024-12-19 21:51:26.000000000 +0000 @@ -154,6 +154,13 @@ // Handle quoted values for name or value if (inQuoted) { + boolean eol = c == 0 && i == hdr.length(); + if (!eol && _compliance != CookieCompliance.RFC2965 && isRFC6265RejectedCharacter(inQuoted, c)) + { + reject = true; + continue; + } + if (escaped) { escaped = false; @@ -182,15 +189,24 @@ continue; case 0: - // unterminated quote, let's ignore quotes + // unterminated quote + if (_compliance == CookieCompliance.RFC6265) + continue; + // let's ignore quotes unquoted.setLength(0); inQuoted = false; i--; continue; + case ';': + if (_compliance == CookieCompliance.RFC6265) + reject = true; + else + unquoted.append(c); + continue; + default: unquoted.append(c); - continue; } } else @@ -198,6 +214,13 @@ // Handle name and value state machines if (invalue) { + boolean eol = c == 0 && i == hdr.length(); + if (!eol && _compliance == CookieCompliance.RFC6265 && isRFC6265RejectedCharacter(inQuoted, c)) + { + reject = true; + continue; + } + // parse the cookie-value switch (c) { @@ -300,9 +323,20 @@ unquoted = new StringBuilder(); break; } + else if (_compliance == CookieCompliance.RFC6265) + { + reject = true; + continue; + } // fall through to default case default: + if (_compliance == CookieCompliance.RFC6265 && quoted) + { + reject = true; + continue; + } + if (quoted) { // must have been a bad internal quote. let's fix as best we can @@ -312,18 +346,12 @@ continue; } - if (_compliance == CookieCompliance.RFC6265) - { - if (isRFC6265RejectedCharacter(inQuoted, c)) - { - reject = true; - } - } + if (_compliance == CookieCompliance.RFC6265_LEGACY && isRFC6265RejectedCharacter(inQuoted, c)) + reject = true; if (tokenstart < 0) tokenstart = i; tokenend = i; - continue; } } else @@ -366,13 +394,8 @@ continue; } - if (_compliance == CookieCompliance.RFC6265) - { - if (isRFC6265RejectedCharacter(inQuoted, c)) - { - reject = true; - } - } + if (_compliance != CookieCompliance.RFC2965 && isRFC6265RejectedCharacter(inQuoted, c)) + reject = true; if (tokenstart < 0) tokenstart = i; @@ -390,28 +413,37 @@ protected boolean isRFC6265RejectedCharacter(boolean inQuoted, char c) { - if (inQuoted) + // LEGACY test + if (_compliance == CookieCompliance.RFC6265_LEGACY) { - // We only reject if a Control Character is encountered - if (Character.isISOControl(c)) + if (inQuoted) { - return true; + // We only reject if a Control Character is encountered + if (Character.isISOControl(c)) + return true; } - } - else - { - /* From RFC6265 - Section 4.1.1 - Syntax - * cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E - * ; US-ASCII characters excluding CTLs, - * ; whitespace DQUOTE, comma, semicolon, - * ; and backslash - */ - return Character.isISOControl(c) || // control characters - c > 127 || // 8-bit characters - c == ',' || // comma - c == ';'; // semicolon + else + { + return Character.isISOControl(c) || // control characters + c > 127 || // 8-bit characters + c == ',' || // comma + c == ';'; // semicolon + } + return false; } - return false; + /* From RFC6265 - Section 4.1.1 - Syntax + * cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E + * ; US-ASCII characters excluding CTLs, + * ; whitespace DQUOTE, comma, semicolon, + * ; and backslash + * + * Note: DQUOTE and semicolon are used as separator by the parser, + * so we can consider them authorized. + */ + return c > 127 || // 8-bit characters + Character.isISOControl(c) || // control characters + c == ',' || // comma + c == '\\'; // backslash } } diff -Nru jetty9-9.4.50/jetty-server/src/main/java/org/eclipse/jetty/server/HomeBaseWarning.java jetty9-9.4.57/jetty-server/src/main/java/org/eclipse/jetty/server/HomeBaseWarning.java --- jetty9-9.4.50/jetty-server/src/main/java/org/eclipse/jetty/server/HomeBaseWarning.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/java/org/eclipse/jetty/server/HomeBaseWarning.java 2024-12-19 21:51:26.000000000 +0000 @@ -68,7 +68,7 @@ { StringBuilder warn = new StringBuilder(); warn.append("This instance of Jetty is not running from a separate {jetty.base} directory"); - warn.append(", this is not recommended. See documentation at https://www.eclipse.org/jetty/documentation/current/startup.html"); + warn.append(", this is not recommended. See documentation at https://jetty.org/docs/9/startup.html"); LOG.warn("{}", warn.toString()); } } diff -Nru jetty9-9.4.50/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java jetty9-9.4.57/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java --- jetty9-9.4.50/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java 2024-12-19 21:51:26.000000000 +0000 @@ -184,6 +184,8 @@ if (failure == null) failure = new IOException("unconsumed input"); content.failed(failure); + if (_content == content) + _content = null; } return failure; } @@ -377,7 +379,7 @@ protected Content nextContent() throws IOException { Content content = nextNonSentinelContent(); - if (content == null && !isFinished()) + if (content == null && !isFinished() && !isError()) { produceContent(); content = nextNonSentinelContent(); @@ -461,7 +463,7 @@ // Intercept the current content. // The interceptor may be called several // times for the same content. - _intercepted = intercept(_content); + _intercepted = _interceptor.readFrom(_content); // If interception produced new content if (_intercepted != null && _intercepted != _content) @@ -493,24 +495,6 @@ return null; } - private Content intercept(Content content) throws IOException - { - try - { - return _interceptor.readFrom(content); - } - catch (Throwable x) - { - IOException failure = new IOException("Bad content", x); - content.failed(failure); - HttpChannel channel = _channelState.getHttpChannel(); - Response response = channel.getResponse(); - if (response.isCommitted()) - channel.abort(failure); - throw failure; - } - } - private void consume(Content content) { if (!isError() && content instanceof EofContent) @@ -610,6 +594,8 @@ { Throwable failure = isError() ? _state.getError() : new EOFException("Content after EOF"); content.failed(failure); + if (_content == content) + _content = null; return false; } else @@ -1146,6 +1132,8 @@ { if (_error instanceof IOException) throw (IOException)_error; + if (_error instanceof RuntimeException) + throw (RuntimeException)_error; throw new IOException(_error); } diff -Nru jetty9-9.4.50/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java jetty9-9.4.57/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java --- jetty9-9.4.50/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java 2024-12-19 21:51:26.000000000 +0000 @@ -58,7 +58,12 @@ public MultiPartsHttpParser(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir, Request request) throws IOException { - _httpParser = new MultiPartFormInputStream(in, contentType, config, contextTmpDir); + this(in, contentType, config, contextTmpDir, request, ContextHandler.DEFAULT_MAX_FORM_KEYS); + } + + public MultiPartsHttpParser(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir, Request request, int maxParts) throws IOException + { + _httpParser = new MultiPartFormInputStream(in, contentType, config, contextTmpDir, maxParts); _context = request.getContext(); _request = request; } @@ -123,7 +128,12 @@ public MultiPartsUtilParser(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir, Request request) throws IOException { - _utilParser = new MultiPartInputStreamParser(in, contentType, config, contextTmpDir); + this(in, contentType, config, contextTmpDir, request, ContextHandler.DEFAULT_MAX_FORM_KEYS); + } + + public MultiPartsUtilParser(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir, Request request, int maxParts) throws IOException + { + _utilParser = new MultiPartInputStreamParser(in, contentType, config, contextTmpDir, maxParts); _context = request.getContext(); _request = request; } diff -Nru jetty9-9.4.50/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java jetty9-9.4.57/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java --- jetty9-9.4.50/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java 2024-12-19 21:51:26.000000000 +0000 @@ -2431,7 +2431,21 @@ if (config == null) throw new IllegalStateException("No multipart config for servlet"); - _multiParts = newMultiParts(config); + int maxFormContentSize = ContextHandler.DEFAULT_MAX_FORM_CONTENT_SIZE; + int maxFormKeys = ContextHandler.DEFAULT_MAX_FORM_KEYS; + if (_context != null) + { + ContextHandler contextHandler = _context.getContextHandler(); + maxFormContentSize = contextHandler.getMaxFormContentSize(); + maxFormKeys = contextHandler.getMaxFormKeys(); + } + else + { + maxFormContentSize = lookupServerAttribute(ContextHandler.MAX_FORM_CONTENT_SIZE_KEY, maxFormContentSize); + maxFormKeys = lookupServerAttribute(ContextHandler.MAX_FORM_KEYS_KEY, maxFormKeys); + } + + _multiParts = newMultiParts(config, maxFormKeys); setAttribute(MULTIPARTS, _multiParts); Collection parts = _multiParts.getParts(); @@ -2465,11 +2479,16 @@ else defaultCharset = StandardCharsets.UTF_8; + long formContentSize = 0; ByteArrayOutputStream os = null; for (Part p : parts) { if (p.getSubmittedFileName() == null) { + formContentSize = Math.addExact(formContentSize, p.getSize()); + if (maxFormContentSize >= 0 && formContentSize > maxFormContentSize) + throw new IllegalStateException("Form is larger than max length " + maxFormContentSize); + // Servlet Spec 3.0 pg 23, parts without filename must be put into params. String charset = null; if (p.getContentType() != null) @@ -2494,7 +2513,7 @@ return _multiParts.getParts(); } - private MultiParts newMultiParts(MultipartConfigElement config) throws IOException + private MultiParts newMultiParts(MultipartConfigElement config, int maxParts) throws IOException { MultiPartFormDataCompliance compliance = getHttpChannel().getHttpConfiguration().getMultipartFormDataCompliance(); if (LOG.isDebugEnabled()) @@ -2504,12 +2523,12 @@ { case RFC7578: return new MultiParts.MultiPartsHttpParser(getInputStream(), getContentType(), config, - (_context != null ? (File)_context.getAttribute("javax.servlet.context.tempdir") : null), this); + (_context != null ? (File)_context.getAttribute("javax.servlet.context.tempdir") : null), this, maxParts); case LEGACY: default: return new MultiParts.MultiPartsUtilParser(getInputStream(), getContentType(), config, - (_context != null ? (File)_context.getAttribute("javax.servlet.context.tempdir") : null), this); + (_context != null ? (File)_context.getAttribute("javax.servlet.context.tempdir") : null), this, maxParts); } } diff -Nru jetty9-9.4.50/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java jetty9-9.4.57/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java --- jetty9-9.4.50/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java 2024-12-19 21:51:26.000000000 +0000 @@ -190,8 +190,8 @@ } writer.append("


    \n"); - writer.append("\"icon\" "); - writer.append("Powered by Eclipse Jetty:// Server
    \n"); + writer.append("\"icon\" "); + writer.append("Powered by Eclipse Jetty:// Server
    \n"); writer.append("\n\n"); writer.flush(); byte[] content = outputStream.toByteArray(); diff -Nru jetty9-9.4.50/jetty-server/src/main/java/org/eclipse/jetty/server/handler/SizeLimitHandler.java jetty9-9.4.57/jetty-server/src/main/java/org/eclipse/jetty/server/handler/SizeLimitHandler.java --- jetty9-9.4.50/jetty-server/src/main/java/org/eclipse/jetty/server/handler/SizeLimitHandler.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/java/org/eclipse/jetty/server/handler/SizeLimitHandler.java 2024-12-19 21:51:26.000000000 +0000 @@ -31,8 +31,6 @@ import org.eclipse.jetty.server.HttpOutput; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; /** *

    A handler that can limit the size of message bodies in requests and responses.

    @@ -46,8 +44,6 @@ */ public class SizeLimitHandler extends HandlerWrapper { - private static final Logger LOG = Log.getLogger(SizeLimitHandler.class); - private final long _requestLimit; private final long _responseLimit; @@ -90,7 +86,7 @@ baseRequest.getHttpInput().addInterceptor(limit); } - if (_responseLimit > 0) + if (_responseLimit >= 0) { httpOutput.setInterceptor(limit); response = new LimitResponse(response); @@ -126,10 +122,13 @@ @Override public HttpInput.Content readFrom(HttpInput.Content content) { + if (content == null) + return null; + if (content.hasContent()) { _read += content.remaining(); - checkResponseLimit(_read); + checkRequestLimit(_read); } return content; } @@ -140,7 +139,16 @@ if (content.hasRemaining()) { _written += content.remaining(); - checkResponseLimit(_written); + + try + { + checkResponseLimit(_written); + } + catch (Throwable t) + { + callback.failed(t); + return; + } } getNextInterceptor().write(content, last, callback); } diff -Nru jetty9-9.4.50/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ThreadLimitHandler.java jetty9-9.4.57/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ThreadLimitHandler.java --- jetty9-9.4.50/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ThreadLimitHandler.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ThreadLimitHandler.java 2024-12-19 21:51:26.000000000 +0000 @@ -26,10 +26,12 @@ import java.util.Deque; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicInteger; import javax.servlet.AsyncContext; import javax.servlet.ServletException; +import javax.servlet.ServletRequestEvent; +import javax.servlet.ServletRequestListener; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -79,7 +81,7 @@ private final boolean _rfc7239; private final String _forwardedHeader; private final IncludeExcludeSet _includeExcludeSet = new IncludeExcludeSet<>(InetAddressSet.class); - private final ConcurrentMap _remotes = new ConcurrentHashMap<>(); + private final ConcurrentHashMap _remotes = new ConcurrentHashMap<>(); private volatile boolean _enabled; private int _threadLimit = 10; @@ -165,6 +167,22 @@ } else { + request.getServletContext().addListener(new ServletRequestListener() + { + @Override + public void requestInitialized(ServletRequestEvent servletRequestEvent) + { + } + + @Override + public void requestDestroyed(ServletRequestEvent sre) + { + // Use a compute method to remove the Remote instance as it is necessary for + // the ref counter release and the removal to be atomic. + _remotes.computeIfPresent(remote._ip, (k, v) -> v._referenceCounter.release() ? null : v); + } + }); + // Do we already have a future permit from a previous invocation? Closeable permit = (Closeable)baseRequest.getAttribute(PERMIT); try @@ -256,14 +274,18 @@ if (limit <= 0) return null; - remote = _remotes.get(ip); - if (remote == null) + // Use a compute method to create or retain the Remote instance as it is necessary for + // the ref counter increment or the instance creation to be mutually exclusive. + // The map MUST be a CHM as it guarantees the remapping function is only called once. + remote = _remotes.compute(ip, (k, v) -> { - Remote r = new Remote(ip, limit); - remote = _remotes.putIfAbsent(ip, r); - if (remote == null) - remote = r; - } + if (v != null) + { + v._referenceCounter.retain(); + return v; + } + return new Remote(k, limit); + }); baseRequest.setAttribute(REMOTE, remote); @@ -282,7 +304,7 @@ } // If no remote IP from a header, determine it directly from the channel - // Do not use the request methods, as they may have been lied to by the + // Do not use the request methods, as they may have been lied to by the // RequestCustomizer! InetSocketAddress inetAddr = baseRequest.getHttpChannel().getRemoteAddress(); if (inetAddr != null && inetAddr.getAddress() != null) @@ -329,11 +351,17 @@ return (comma >= 0) ? forwardedFor.substring(comma + 1).trim() : forwardedFor; } + int getRemoteCount() + { + return _remotes.size(); + } + private final class Remote implements Closeable { private final String _ip; private final int _limit; private final Locker _locker = new Locker(); + private final ReferenceCounter _referenceCounter = new ReferenceCounter(); private int _permits; private Deque> _queue = new ArrayDeque<>(); private final CompletableFuture _permitted = CompletableFuture.completedFuture(this); @@ -357,7 +385,7 @@ return _permitted; // TODO is it OK to share/reuse this? } - // No pass available, so queue a new future + // No pass available, so queue a new future CompletableFuture pass = new CompletableFuture(); _queue.addLast(pass); return pass; @@ -437,4 +465,26 @@ } } } + + private static class ReferenceCounter + { + private final AtomicInteger references = new AtomicInteger(1); + + public void retain() + { + if (references.getAndUpdate(c -> c == 0 ? 0 : c + 1) == 0) + throw new IllegalStateException("released " + this); + } + + public boolean release() + { + int ref = references.updateAndGet(c -> + { + if (c == 0) + throw new IllegalStateException("already released " + this); + return c - 1; + }); + return ref == 0; + } + } } diff -Nru jetty9-9.4.50/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java jetty9-9.4.57/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java --- jetty9-9.4.50/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java 2024-12-19 21:51:26.000000000 +0000 @@ -1727,33 +1727,36 @@ if (isUsingURLs() && (requestedSessionId == null)) { String uri = request.getRequestURI(); - String prefix = getSessionIdPathParameterNamePrefix(); - if (prefix != null) + if (uri != null) { - int s = uri.indexOf(prefix); - if (s >= 0) + String prefix = getSessionIdPathParameterNamePrefix(); + if (prefix != null) { - s += prefix.length(); - int i = s; - while (i < uri.length()) + int s = uri.indexOf(prefix); + if (s >= 0) { - char c = uri.charAt(i); - if (c == ';' || c == '#' || c == '?' || c == '/') - break; - i++; - } + s += prefix.length(); + int i = s; + while (i < uri.length()) + { + char c = uri.charAt(i); + if (c == ';' || c == '#' || c == '?' || c == '/') + break; + i++; + } - requestedSessionId = uri.substring(s, i); - requestedSessionIdFromCookie = false; + requestedSessionId = uri.substring(s, i); + requestedSessionIdFromCookie = false; - if (LOG.isDebugEnabled()) - LOG.debug("Got Session ID {} from URL", requestedSessionId); + if (LOG.isDebugEnabled()) + LOG.debug("Got Session ID {} from URL", requestedSessionId); - session = getHttpSession(requestedSessionId); - if (session != null && isValid(session)) - { - baseRequest.enterSession(session); //request enters this session for first time - baseRequest.setSession(session); //associate the session with the request + session = getHttpSession(requestedSessionId); + if (session != null && isValid(session)) + { + baseRequest.enterSession(session); //request enters this session for first time + baseRequest.setSession(session); //associate the session with the request + } } } } diff -Nru jetty9-9.4.50/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterLenientTest.java jetty9-9.4.57/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterLenientTest.java --- jetty9-9.4.50/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterLenientTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterLenientTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -21,6 +21,7 @@ import java.util.stream.Stream; import javax.servlet.http.Cookie; +import org.eclipse.jetty.http.CookieCompliance; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -162,7 +163,7 @@ @MethodSource("data") public void testLenientBehavior(String rawHeader, String expectedName, String expectedValue) { - CookieCutter cutter = new CookieCutter(); + CookieCutter cutter = new CookieCutter(CookieCompliance.RFC6265_LEGACY); cutter.addCookieField(rawHeader); Cookie[] cookies = cutter.getCookies(); if (expectedName == null) diff -Nru jetty9-9.4.50/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterTest.java jetty9-9.4.57/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterTest.java --- jetty9-9.4.50/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -19,10 +19,13 @@ package org.eclipse.jetty.server; import java.util.Arrays; +import java.util.List; import javax.servlet.http.Cookie; import org.eclipse.jetty.http.CookieCompliance; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -162,15 +165,13 @@ "$Version=\"1\"; session_id=\"1111\"; $Domain=\".cracker.edu\""; Cookie[] cookies = parseCookieHeaders(CookieCompliance.RFC2965, rawCookie); - assertThat("Cookies.length", cookies.length, is(2)); assertCookie("Cookies[0]", cookies[0], "session_id", "1234", 1, null); assertCookie("Cookies[1]", cookies[1], "session_id", "1111", 1, null); cookies = parseCookieHeaders(CookieCompliance.RFC6265, rawCookie); - assertThat("Cookies.length", cookies.length, is(2)); - assertCookie("Cookies[0]", cookies[0], "session_id", "1234\", $Version=\"1", 0, null); - assertCookie("Cookies[1]", cookies[1], "session_id", "1111", 0, null); + assertThat("Cookies.length", cookies.length, is(1)); + assertCookie("Cookies[0]", cookies[0], "session_id", "1111", 0, null); } /** @@ -266,7 +267,7 @@ { char[] excessive = new char[65535]; Arrays.fill(excessive, ';'); - String rawCookie = "foo=bar; " + excessive + "; xyz=pdq"; + String rawCookie = "foo=bar; " + new String(excessive) + "; xyz=pdq"; Cookie[] cookies = parseCookieHeaders(CookieCompliance.RFC6265, rawCookie); @@ -274,4 +275,83 @@ assertCookie("Cookies[0]", cookies[0], "foo", "bar", 0, null); assertCookie("Cookies[1]", cookies[1], "xyz", "pdq", 0, null); } + + @ParameterizedTest + @MethodSource("rfc6265Cookies") + public void testRFC6265CookieParsing(Param param) + { + Cookie[] cookies = parseCookieHeaders(CookieCompliance.RFC6265, param.input); + + assertThat("Cookies.length (" + dump(cookies) + ")", cookies.length, is(param.expected.size())); + for (int i = 0; i < cookies.length; i++) + { + Cookie cookie = cookies[i]; + assertThat("Cookies[" + i + "] (" + dump(cookies) + ")", cookie.getName() + "=" + cookie.getValue(), is(param.expected.get(i))); + } + } + + public static List rfc6265Cookies() + { + return Arrays.asList( + new Param("A=1; B=2; C=3", "A=1", "B=2", "C=3"), + new Param("A=\"1\"; B=2; C=3", "A=1", "B=2", "C=3"), + new Param("A=\"1\"; B=\"2\"; C=\"3\"", "A=1", "B=2", "C=3"), + new Param("A=1; B=2; C=\"3", "A=1", "B=2"), + new Param("A=1 ; B=2; C=3", "A=1", "B=2", "C=3"), + new Param("A= 1; B=2; C=3", "A=1", "B=2", "C=3"), + new Param("A=\"1; B=2\"; C=3", "C=3"), + new Param("A=\"1; B=2; C=3"), + new Param("A=\"1 B=2\"; C=3", "A=1 B=2", "C=3"), + new Param("A=\"\"1; B=2; C=3", "B=2", "C=3"), + new Param("A=\"\" ; B=2; C=3", "A=", "B=2", "C=3"), + new Param("A=\"\"; B=2; C=3", "A=", "B=2", "C=3"), + new Param("A=1\"\"; B=2; C=3", "B=2", "C=3"), + new Param("A=1\"; B=2; C=3", "B=2", "C=3"), + new Param("A=1\"1; B=2; C=3", "B=2", "C=3"), + new Param("A=\" 1\"; B=2; C=3", "A= 1", "B=2", "C=3"), + new Param("A=\"1 \"; B=2; C=3", "A=1 ", "B=2", "C=3"), + new Param("A=\" 1 \"; B=2; C=3", "A= 1 ", "B=2", "C=3"), + new Param("A=\" 1 1 \"; B=2; C=3", "A= 1 1 ", "B=2", "C=3"), + new Param("A=1,; B=2; C=3", "B=2", "C=3"), + new Param("A=\"1,\"; B=2; C=3", "B=2", "C=3"), + new Param("A=\\1; B=2; C=3", "B=2", "C=3"), + new Param("A=\"\\1\"; B=2; C=3", "B=2", "C=3"), + new Param("A=1\u0007; B=2; C=3", "B=2", "C=3"), + new Param("A=\"1\u0007\"; B=2; C=3", "B=2", "C=3"), + new Param("€"), + new Param("@={}"), + new Param("$X=Y; N=V", "N=V"), + new Param("N=V; $X=Y", "N=V") + ); + } + + private static String dump(Cookie[] cookies) + { + StringBuilder sb = new StringBuilder(); + for (Cookie cookie : cookies) + { + sb.append("<").append(cookie.getName()).append(">=<").append(cookie.getValue()).append("> | "); + } + if (sb.length() > 0) + sb.delete(sb.length() - 2, sb.length() - 1); + return sb.toString(); + } + + private static class Param + { + private final String input; + private final List expected; + + public Param(String input, String... expected) + { + this.input = input; + this.expected = Arrays.asList(expected); + } + + @Override + public String toString() + { + return input + " -> " + expected.toString(); + } + } } diff -Nru jetty9-9.4.50/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java jetty9-9.4.57/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java --- jetty9-9.4.50/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -53,6 +53,7 @@ import javax.servlet.http.Part; import org.eclipse.jetty.http.BadMessageException; +import org.eclipse.jetty.http.CookieCompliance; import org.eclipse.jetty.http.HttpCompliance; import org.eclipse.jetty.http.HttpComplianceSection; import org.eclipse.jetty.http.HttpStatus; @@ -140,6 +141,7 @@ http.getHttpConfiguration().setRequestHeaderSize(512); http.getHttpConfiguration().setResponseHeaderSize(512); http.getHttpConfiguration().setOutputBufferSize(2048); + http.getHttpConfiguration().setRequestCookieCompliance(CookieCompliance.RFC6265_LEGACY); http.getHttpConfiguration().addCustomizer(new ForwardedRequestCustomizer()); _connector = new LocalConnector(_server, http); _server.addConnector(_connector); diff -Nru jetty9-9.4.50/jetty-server/src/test/java/org/eclipse/jetty/server/handler/SizeLimitHandlerTest.java jetty9-9.4.57/jetty-server/src/test/java/org/eclipse/jetty/server/handler/SizeLimitHandlerTest.java --- jetty9-9.4.50/jetty-server/src/test/java/org/eclipse/jetty/server/handler/SizeLimitHandlerTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/test/java/org/eclipse/jetty/server/handler/SizeLimitHandlerTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -111,6 +111,7 @@ _local.getResponse("GET /ctx/hello HTTP/1.0\r\n\r\n")); assertThat(response.getStatus(), equalTo(500)); assertThat(response.getContent(), containsString("8193>8192")); + assertThat(response.getContent(), containsString("Response body is too large")); } @Test @@ -130,6 +131,7 @@ _local.getResponse("GET /ctx/hello HTTP/1.0\r\n\r\n")); assertThat(response.getStatus(), equalTo(500)); assertThat(response.getContent(), containsString("8193>8192")); + assertThat(response.getContent(), containsString("Response body is too large")); } @Test @@ -219,6 +221,7 @@ "\r\n" + "123456...")); assertThat(response.getStatus(), equalTo(413)); + assertThat(response.getContent(), containsString("Request body is too large")); assertThat(response.getContent(), containsString("32768>8192")); } @@ -249,11 +252,12 @@ String text = new String(data, 0, 1024, Charset.defaultCharset()); for (int i = 0; i < 9; i++) - endp.addInput("400\r\n" + text + "\r\n"); + endp.addInput(Integer.toHexString(text.length()) + ";\r\n" + text + "\r\n"); HttpTester.Response response = HttpTester.parseResponse(endp.getResponse()); - assertThat(response.getStatus(), equalTo(500)); + assertThat(response.getStatus(), equalTo(413)); + assertThat(response.getContent(), containsString("Request body is too large")); assertThat(response.getContent(), containsString(">8192")); } } diff -Nru jetty9-9.4.50/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ThreadLimitHandlerTest.java jetty9-9.4.57/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ThreadLimitHandlerTest.java --- jetty9-9.4.50/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ThreadLimitHandlerTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ThreadLimitHandlerTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -40,6 +40,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import static org.awaitility.Awaitility.await; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -88,7 +89,9 @@ response.setStatus(HttpStatus.OK_200); } }); - _server.setHandler(handler); + ContextHandler contextHandler = new ContextHandler("/"); + contextHandler.setHandler(handler); + _server.setHandler(contextHandler); _server.start(); last.set(null); @@ -102,6 +105,8 @@ last.set(null); _local.getResponse("GET / HTTP/1.0\r\nForwarded: for=1.2.3.4\r\n\r\n"); assertThat(last.get(), Matchers.is("0.0.0.0")); + + await().atMost(5, TimeUnit.SECONDS).until(handler::getRemoteCount, is(0)); } @Test @@ -117,7 +122,9 @@ return super.getThreadLimit(ip); } }; - _server.setHandler(handler); + ContextHandler contextHandler = new ContextHandler("/"); + contextHandler.setHandler(handler); + _server.setHandler(contextHandler); _server.start(); last.set(null); @@ -135,6 +142,8 @@ last.set(null); _local.getResponse("GET / HTTP/1.0\r\nX-Forwarded-For: 1.1.1.1\r\nX-Forwarded-For: 6.6.6.6,1.2.3.4\r\nForwarded: for=1.2.3.4\r\n\r\n"); assertThat(last.get(), Matchers.is("1.2.3.4")); + + await().atMost(5, TimeUnit.SECONDS).until(handler::getRemoteCount, is(0)); } @Test @@ -150,7 +159,9 @@ return super.getThreadLimit(ip); } }; - _server.setHandler(handler); + ContextHandler contextHandler = new ContextHandler("/"); + contextHandler.setHandler(handler); + _server.setHandler(contextHandler); _server.start(); last.set(null); @@ -168,6 +179,8 @@ last.set(null); _local.getResponse("GET / HTTP/1.0\r\nX-Forwarded-For: 1.1.1.1\r\nForwarded: for=6.6.6.6; for=1.2.3.4\r\nX-Forwarded-For: 6.6.6.6\r\nForwarded: proto=https\r\n\r\n"); assertThat(last.get(), Matchers.is("1.2.3.4")); + + await().atMost(5, TimeUnit.SECONDS).until(handler::getRemoteCount, is(0)); } @Test @@ -206,7 +219,9 @@ } } }); - _server.setHandler(handler); + ContextHandler contextHandler = new ContextHandler("/"); + contextHandler.setHandler(handler); + _server.setHandler(contextHandler); _server.start(); Socket[] client = new Socket[10]; @@ -241,5 +256,7 @@ Thread.sleep(10); } assertThat(count.get(), is(0)); + + await().atMost(5, TimeUnit.SECONDS).until(handler::getRemoteCount, is(0)); } } diff -Nru jetty9-9.4.50/jetty-servlet/pom.xml jetty9-9.4.57/jetty-servlet/pom.xml --- jetty9-9.4.50/jetty-servlet/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-servlet/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-servlet diff -Nru jetty9-9.4.50/jetty-servlet/src/main/config/modules/servlet.mod jetty9-9.4.57/jetty-servlet/src/main/config/modules/servlet.mod --- jetty9-9.4.50/jetty-servlet/src/main/config/modules/servlet.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-servlet/src/main/config/modules/servlet.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables standard Servlet handling. diff -Nru jetty9-9.4.50/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java jetty9-9.4.57/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java --- jetty9-9.4.50/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -713,6 +713,36 @@ } @Test + public void testBadGzip() throws Exception + { + String data = "Hello Nice World! "; + for (int i = 0; i < 10; ++i) + { + data += data; + } + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + baos.write(data.getBytes(StandardCharsets.UTF_8)); + baos.close(); + byte[] bytes = baos.toByteArray(); + + // generated and parsed test + HttpTester.Request request = HttpTester.newRequest(); + HttpTester.Response response; + + request.setMethod("POST"); + request.setURI("/ctx/echo"); + request.setVersion("HTTP/1.1"); + request.setHeader("Host", "tester"); + request.setHeader("Content-Type", "text/plain"); + request.setHeader("Content-Encoding", "gzip"); + request.setContent(bytes); + + response = HttpTester.parseResponse(_connector.getResponse(request.generate())); + + assertThat(response.getStatus(), is(500)); + } + + @Test public void testGzipRequestChunked() throws Exception { String data = "Hello Nice World! "; diff -Nru jetty9-9.4.50/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/MultiPartServletTest.java jetty9-9.4.57/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/MultiPartServletTest.java --- jetty9-9.4.50/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/MultiPartServletTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/MultiPartServletTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -41,13 +41,16 @@ import org.eclipse.jetty.client.util.BytesContentProvider; import org.eclipse.jetty.client.util.InputStreamResponseListener; import org.eclipse.jetty.client.util.MultiPartContentProvider; +import org.eclipse.jetty.client.util.OutputStreamContentProvider; import org.eclipse.jetty.client.util.StringContentProvider; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpScheme; +import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.http.MultiPartFormInputStream; +import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.MultiPartFormDataCompliance; @@ -55,18 +58,17 @@ import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.gzip.GzipHandler; import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.StacklessLogging; 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; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.startsWith; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -74,19 +76,35 @@ public class MultiPartServletTest { - private static final Logger LOG = Log.getLogger(MultiPartServletTest.class); - private Server server; private ServerConnector connector; private HttpClient client; private Path tmpDir; + private ServletContextHandler contextHandler; private static final int MAX_FILE_SIZE = 512 * 1024; + private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 8; private static final int LARGE_MESSAGE_SIZE = 1024 * 1024; - public static Stream data() + public static Stream complianceModes() { - return Arrays.asList(MultiPartFormDataCompliance.values()).stream().map(Arguments::of); + return Stream.of( + Arguments.of(MultiPartFormDataCompliance.RFC7578), + Arguments.of(MultiPartFormDataCompliance.LEGACY) + ); + } + + public static class RequestParameterServlet extends HttpServlet + { + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + req.getParameterMap(); + req.getParts(); + resp.setStatus(200); + resp.getWriter().print("success"); + resp.getWriter().close(); + } } public static class MultiPartServlet extends HttpServlet @@ -138,11 +156,19 @@ MultipartConfigElement config = new MultipartConfigElement(tmpDir.toAbsolutePath().toString(), MAX_FILE_SIZE, -1, 1); + MultipartConfigElement requestSizedConfig = new MultipartConfigElement(tmpDir.toAbsolutePath().toString(), + -1, MAX_REQUEST_SIZE, 1); + MultipartConfigElement defaultConfig = new MultipartConfigElement(tmpDir.toAbsolutePath().toString(), + -1, -1, 1); - ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); + contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); contextHandler.setContextPath("/"); ServletHolder servletHolder = contextHandler.addServlet(MultiPartServlet.class, "/"); servletHolder.getRegistration().setMultipartConfig(config); + servletHolder = contextHandler.addServlet(RequestParameterServlet.class, "/defaultConfig"); + servletHolder.getRegistration().setMultipartConfig(defaultConfig); + servletHolder = contextHandler.addServlet(RequestParameterServlet.class, "/requestSizeLimit"); + servletHolder.getRegistration().setMultipartConfig(requestSizedConfig); servletHolder = contextHandler.addServlet(MultiPartEchoServlet.class, "/echo"); servletHolder.getRegistration().setMultipartConfig(config); @@ -170,24 +196,170 @@ } @ParameterizedTest - @MethodSource("data") - public void testTempFilesDeletedOnError(MultiPartFormDataCompliance compliance) throws Exception + @MethodSource("complianceModes") + public void testLargePart(MultiPartFormDataCompliance compliance) throws Exception { connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration() .setMultiPartFormDataCompliance(compliance); - byte[] byteArray = new byte[LARGE_MESSAGE_SIZE]; - for (int i = 0; i < byteArray.length; i++) + OutputStreamContentProvider content = new OutputStreamContentProvider(); + MultiPartContentProvider multiPart = new MultiPartContentProvider(); + multiPart.addFieldPart("param", content, null); + multiPart.close(); + + InputStreamResponseListener listener = new InputStreamResponseListener(); + client.newRequest("localhost", connector.getLocalPort()) + .path("/defaultConfig") + .scheme(HttpScheme.HTTP.asString()) + .method(HttpMethod.POST) + .content(multiPart) + .send(listener); + + // Write large amount of content to the part. + byte[] byteArray = new byte[1024 * 1024]; + Arrays.fill(byteArray, (byte)1); + for (int i = 0; i < 1024 * 2; i++) + { + content.getOutputStream().write(byteArray); + } + content.close(); + + Response response = listener.get(2, TimeUnit.MINUTES); + assertThat(response.getStatus(), equalTo(HttpStatus.BAD_REQUEST_400)); + String responseContent = IO.toString(listener.getInputStream()); + assertThat(responseContent, containsString("Unable to parse form content")); + assertThat(responseContent, containsString("Form is larger than max length")); + } + + @ParameterizedTest + @MethodSource("complianceModes") + public void testManyParts(MultiPartFormDataCompliance compliance) throws Exception + { + int maxParts = 1000; + contextHandler.setMaxFormKeys(maxParts); + connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration() + .setMultiPartFormDataCompliance(compliance); + + byte[] byteArray = new byte[10]; + Arrays.fill(byteArray, (byte)1); + + MultiPartContentProvider multiPart = new MultiPartContentProvider(); + for (int i = 0; i < maxParts; i++) + { + BytesContentProvider content = new BytesContentProvider(byteArray); + multiPart.addFieldPart("part" + i, content, null); + } + multiPart.close(); + + InputStreamResponseListener listener = new InputStreamResponseListener(); + client.newRequest("localhost", connector.getLocalPort()) + .path("/defaultConfig") + .scheme(HttpScheme.HTTP.asString()) + .method(HttpMethod.POST) + .content(multiPart) + .send(listener); + + Response response = listener.get(30, TimeUnit.SECONDS); + assertThat(response.getStatus(), equalTo(HttpStatus.OK_200)); + String responseContent = IO.toString(listener.getInputStream()); + assertThat(responseContent, containsString("success")); + } + + @ParameterizedTest + @MethodSource("complianceModes") + public void testTooManyParts(MultiPartFormDataCompliance compliance) throws Exception + { + int maxParts = 1000; + contextHandler.setMaxFormKeys(maxParts); + connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration() + .setMultiPartFormDataCompliance(compliance); + + byte[] byteArray = new byte[5]; + Arrays.fill(byteArray, (byte)1); + + MultiPartContentProvider multiPart = new MultiPartContentProvider(); + for (int i = 0; i < 1024 * 1024; i++) + { + BytesContentProvider content = new BytesContentProvider(byteArray); + multiPart.addFieldPart("part" + i, content, null); + } + multiPart.close(); + + InputStreamResponseListener listener = new InputStreamResponseListener(); + client.newRequest("localhost", connector.getLocalPort()) + .path("/defaultConfig") + .scheme(HttpScheme.HTTP.asString()) + .method(HttpMethod.POST) + .content(multiPart) + .send(listener); + + Response response = listener.get(30, TimeUnit.SECONDS); + assertThat(response.getStatus(), equalTo(HttpStatus.BAD_REQUEST_400)); + String responseContent = IO.toString(listener.getInputStream()); + assertThat(responseContent, containsString("Unable to parse form content")); + assertThat(responseContent, containsString("Form with too many parts")); + } + + @ParameterizedTest + @MethodSource("complianceModes") + public void testMaxRequestSize(MultiPartFormDataCompliance compliance) throws Exception + { + connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration() + .setMultiPartFormDataCompliance(compliance); + + OutputStreamContentProvider content = new OutputStreamContentProvider(); + MultiPartContentProvider multiPart = new MultiPartContentProvider(); + multiPart.addFieldPart("param", content, null); + multiPart.close(); + + InputStreamResponseListener listener = new InputStreamResponseListener(); + client.newRequest("localhost", connector.getLocalPort()) + .path("/requestSizeLimit") + .scheme(HttpScheme.HTTP.asString()) + .method(HttpMethod.POST) + .content(multiPart) + .send(listener); + + Throwable writeError = null; + try + { + // Write large amount of content to the part. + byte[] byteArray = new byte[1024 * 1024]; + Arrays.fill(byteArray, (byte)1); + for (int i = 0; i < 512; i++) + { + content.getOutputStream().write(byteArray); + } + } + catch (Exception e) { - byteArray[i] = 1; + writeError = e; } + + if (writeError != null) + assertThat(writeError, instanceOf(EofException.class)); + + // We should get 400 response. + Response response = listener.get(30, TimeUnit.SECONDS); + assertThat(response.getStatus(), equalTo(HttpStatus.BAD_REQUEST_400)); + } + + @ParameterizedTest + @MethodSource("complianceModes") + public void testTempFilesDeletedOnError(MultiPartFormDataCompliance compliance) throws Exception + { + connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration() + .setMultiPartFormDataCompliance(compliance); + + byte[] byteArray = new byte[LARGE_MESSAGE_SIZE]; + Arrays.fill(byteArray, (byte)1); BytesContentProvider contentProvider = new BytesContentProvider(byteArray); MultiPartContentProvider multiPart = new MultiPartContentProvider(); multiPart.addFieldPart("largePart", contentProvider, null); multiPart.close(); - try (StacklessLogging stacklessLogging = new StacklessLogging(HttpChannel.class, MultiPartFormInputStream.class)) + try (StacklessLogging ignored = new StacklessLogging(HttpChannel.class, MultiPartFormInputStream.class)) { ContentResponse response = client.newRequest("localhost", connector.getLocalPort()) .scheme(HttpScheme.HTTP.asString()) @@ -205,9 +377,13 @@ assertThat(fileList.length, is(0)); } - @Test - public void testMultiPartGzip() throws Exception + @ParameterizedTest + @MethodSource("complianceModes") + public void testMultiPartGzip(MultiPartFormDataCompliance compliance) throws Exception { + connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration() + .setMultiPartFormDataCompliance(compliance); + String contentString = "the quick brown fox jumps over the lazy dog, " + "the quick brown fox jumps over the lazy dog"; StringContentProvider content = new StringContentProvider(contentString); diff -Nru jetty9-9.4.50/jetty-servlets/pom.xml jetty9-9.4.57/jetty-servlets/pom.xml --- jetty9-9.4.50/jetty-servlets/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-servlets/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-servlets diff -Nru jetty9-9.4.50/jetty-servlets/src/main/config/modules/servlets.mod jetty9-9.4.57/jetty-servlets/src/main/config/modules/servlets.mod --- jetty9-9.4.50/jetty-servlets/src/main/config/modules/servlets.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-servlets/src/main/config/modules/servlets.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Puts a collection of jetty utility servlets and filters diff -Nru jetty9-9.4.50/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CGI.java jetty9-9.4.57/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CGI.java --- jetty9-9.4.50/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CGI.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CGI.java 2024-12-19 21:51:26.000000000 +0000 @@ -67,7 +67,10 @@ *
    ignoreExitState
    *
    If true then do not act on a non-zero exec exit status")
    * + * + * @deprecated do not use, no replacement, will be removed in a future release. */ +@Deprecated public class CGI extends HttpServlet { private static final long serialVersionUID = -6182088932884791074L; diff -Nru jetty9-9.4.50/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java jetty9-9.4.57/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java --- jetty9-9.4.50/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java 2024-12-19 21:51:26.000000000 +0000 @@ -22,10 +22,8 @@ import java.io.Serializable; import java.time.Duration; import java.util.ArrayList; -import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; @@ -48,11 +46,6 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpSessionActivationListener; -import javax.servlet.http.HttpSessionBindingEvent; -import javax.servlet.http.HttpSessionBindingListener; -import javax.servlet.http.HttpSessionEvent; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.server.handler.ContextHandler; @@ -77,10 +70,8 @@ * second. If a limit is exceeded, the request is either rejected, delayed, or * throttled. *

    - * When a request is throttled, it is placed in a priority queue. Priority is - * given first to authenticated users and users with an HttpSession, then - * connections which can be identified by their IP addresses. Connections with - * no way to identify them are given lowest priority. + * When a request is throttled, it is placed in a queue and will only proceed + * when there is capacity. *

    * The {@link #extractUserId(ServletRequest request)} function should be * implemented, in order to uniquely identify authenticated users. @@ -109,10 +100,8 @@ * before deciding that the user has gone away, and discarding it *

    insertHeaders
    *
    if true , insert the DoSFilter headers into the response. Defaults to true.
    - *
    trackSessions
    - *
    if true, usage rate is tracked by session if a session exists. Defaults to true.
    *
    remotePort
    - *
    if true and session tracking is not used, then rate is tracked by IP+port (effectively connection). Defaults to false.
    + *
    if true then rate is tracked by IP+port (effectively connection). Defaults to false.
    *
    ipWhitelist
    *
    a comma-separated list of IP addresses that will not be rate limited
    *
    managedAttr
    @@ -159,12 +148,14 @@ static final String MAX_REQUEST_MS_INIT_PARAM = "maxRequestMs"; static final String MAX_IDLE_TRACKER_MS_INIT_PARAM = "maxIdleTrackerMs"; static final String INSERT_HEADERS_INIT_PARAM = "insertHeaders"; + @Deprecated static final String TRACK_SESSIONS_INIT_PARAM = "trackSessions"; static final String REMOTE_PORT_INIT_PARAM = "remotePort"; static final String IP_WHITELIST_INIT_PARAM = "ipWhitelist"; static final String ENABLED_INIT_PARAM = "enabled"; static final String TOO_MANY_CODE = "tooManyCode"; + @Deprecated public enum RateType { AUTH, @@ -184,7 +175,6 @@ private volatile long _maxRequestMs; private volatile long _maxIdleTrackerMs; private volatile boolean _insertHeaders; - private volatile boolean _trackSessions; private volatile boolean _remotePort; private volatile boolean _enabled; private volatile String _name; @@ -192,20 +182,14 @@ private Semaphore _passes; private volatile int _throttledRequests; private volatile int _maxRequestsPerSec; - private Map> _queues = new HashMap<>(); - private Map _listeners = new HashMap<>(); + private final Queue _queue = new ConcurrentLinkedQueue<>(); + private final AsyncListener _asyncListener = new DoSAsyncListener(); private Scheduler _scheduler; private ServletContext _context; @Override public void init(FilterConfig filterConfig) throws ServletException { - for (RateType rateType : RateType.values()) - { - _queues.put(rateType, new ConcurrentLinkedQueue<>()); - _listeners.put(rateType, new DoSAsyncListener(rateType)); - } - _rateTrackers.clear(); int maxRequests = __DEFAULT_MAX_REQUESTS_PER_SEC; @@ -260,10 +244,10 @@ setInsertHeaders(parameter == null || Boolean.parseBoolean(parameter)); parameter = filterConfig.getInitParameter(TRACK_SESSIONS_INIT_PARAM); - setTrackSessions(parameter == null || Boolean.parseBoolean(parameter)); + setTrackSessions(Boolean.parseBoolean(parameter)); parameter = filterConfig.getInitParameter(REMOTE_PORT_INIT_PARAM); - setRemotePort(parameter != null && Boolean.parseBoolean(parameter)); + setRemotePort(Boolean.parseBoolean(parameter)); parameter = filterConfig.getInitParameter(ENABLED_INIT_PARAM); setEnabled(parameter == null || Boolean.parseBoolean(parameter)); @@ -398,15 +382,14 @@ long throttleMs = getThrottleMs(); if (!Boolean.TRUE.equals(throttled) && throttleMs > 0) { - RateType priority = getPriority(request, tracker); request.setAttribute(__THROTTLED, Boolean.TRUE); if (isInsertHeaders()) response.addHeader("DoSFilter", "throttled"); AsyncContext asyncContext = request.startAsync(); request.setAttribute(_suspended, Boolean.TRUE); asyncContext.setTimeout(throttleMs); - asyncContext.addListener(_listeners.get(priority)); - _queues.get(priority).add(asyncContext); + asyncContext.addListener(_asyncListener); + _queue.add(asyncContext); if (LOG.isDebugEnabled()) LOG.debug("Throttled {}, {}ms", request, throttleMs); return; @@ -450,22 +433,17 @@ { try { - // Wake up the next highest priority request. - for (RateType rateType : RateType.values()) + AsyncContext asyncContext = _queue.poll(); + if (asyncContext != null) { - AsyncContext asyncContext = _queues.get(rateType).poll(); - if (asyncContext != null) + ServletRequest candidate = asyncContext.getRequest(); + Boolean suspended = (Boolean)candidate.getAttribute(_suspended); + if (Boolean.TRUE.equals(suspended)) { - ServletRequest candidate = asyncContext.getRequest(); - Boolean suspended = (Boolean)candidate.getAttribute(_suspended); - if (Boolean.TRUE.equals(suspended)) - { - if (LOG.isDebugEnabled()) - LOG.debug("Resuming {}", request); - candidate.setAttribute(_resumed, Boolean.TRUE); - asyncContext.dispatch(); - break; - } + if (LOG.isDebugEnabled()) + LOG.debug("Resuming {}", request); + candidate.setAttribute(_resumed, Boolean.TRUE); + asyncContext.dispatch(); } } } @@ -539,27 +517,13 @@ } /** - * Get priority for this request, based on user type - * - * @param request the current request - * @param tracker the rate tracker for this request - * @return the priority for this request - */ - private RateType getPriority(HttpServletRequest request, RateTracker tracker) - { - if (extractUserId(request) != null) - return RateType.AUTH; - if (tracker != null) - return tracker.getType(); - return RateType.UNKNOWN; - } - - /** - * @return the maximum priority that we can assign to a request + * @return null + * @deprecated Priority no longer supported */ + @Deprecated protected RateType getMaxPriority() { - return RateType.AUTH; + return null; } public void setListener(DoSFilter.Listener listener) @@ -585,61 +549,29 @@ *

    * Assumes that each connection has an identifying characteristic, and goes * through them in order, taking the first that matches: user id (logged - * in), session id, client IP address. Unidentifiable connections are lumped + * in), client IP address. Unidentifiable connections are lumped * into one. - *

    - * When a session expires, its rate tracker is automatically deleted. * * @param request the current request * @return the request rate tracker for the current connection */ RateTracker getRateTracker(ServletRequest request) { - HttpSession session = ((HttpServletRequest)request).getSession(false); - - String loadId = extractUserId(request); - final RateType type; - if (loadId != null) - { - type = RateType.AUTH; - } - else - { - if (isTrackSessions() && session != null && !session.isNew()) - { - loadId = session.getId(); - type = RateType.SESSION; - } - else - { - loadId = isRemotePort() ? createRemotePortId(request) : request.getRemoteAddr(); - type = RateType.IP; - } - } - + String loadId = isRemotePort() ? createRemotePortId(request) : request.getRemoteAddr(); RateTracker tracker = _rateTrackers.get(loadId); if (tracker == null) { boolean allowed = checkWhitelist(request.getRemoteAddr()); int maxRequestsPerSec = getMaxRequestsPerSec(); - tracker = allowed ? new FixedRateTracker(_context, _name, loadId, type, maxRequestsPerSec) - : new RateTracker(_context, _name, loadId, type, maxRequestsPerSec); + tracker = allowed ? new FixedRateTracker(_context, _name, loadId, maxRequestsPerSec) + : new RateTracker(_context, _name, loadId, maxRequestsPerSec); tracker.setContext(_context); RateTracker existing = _rateTrackers.putIfAbsent(loadId, tracker); if (existing != null) tracker = existing; - if (type == RateType.IP) - { - // USER_IP expiration from _rateTrackers is handled by the _scheduler - _scheduler.schedule(tracker, getMaxIdleTrackerMs(), TimeUnit.MILLISECONDS); - } - else if (session != null) - { - // USER_SESSION expiration from _rateTrackers are handled by the HttpSessionBindingListener - session.setAttribute(__TRACKER, tracker); - } + _scheduler.schedule(tracker, getMaxIdleTrackerMs(), TimeUnit.MILLISECONDS); } return tracker; @@ -784,7 +716,7 @@ return result; // Sets the _prefix_ most significant bits to 1 - result[index] = (byte)~((1 << (8 - prefix)) - 1); + result[index] = (byte)-(1 << (8 - prefix)); return result; } @@ -810,12 +742,11 @@ } /** - * Returns the user id, used to track this connection. - * This SHOULD be overridden by subclasses. - * - * @param request the current request - * @return a unique user id, if logged in; otherwise null. + * @param request ignored + * @return null + * @deprecated User ID no longer supported */ + @Deprecated protected String extractUserId(ServletRequest request) { return null; @@ -1030,26 +961,29 @@ * Get flag to have usage rate tracked by session if a session exists. * * @return value of the flag + * @deprecated Session tracking is no longer supported */ - @ManagedAttribute("usage rate is tracked by session if one exists") + @Deprecated public boolean isTrackSessions() { - return _trackSessions; + return false; } /** * Set flag to have usage rate tracked by session if a session exists. * * @param value value of the flag + * @deprecated Session tracking is no longer supported */ + @Deprecated public void setTrackSessions(boolean value) { - _trackSessions = value; + if (value) + LOG.warn("Session Tracking is not supported"); } /** * Get flag to have usage rate tracked by IP+port (effectively connection) - * if session tracking is not used. * * @return value of the flag */ @@ -1061,7 +995,6 @@ /** * Set flag to have usage rate tracked by IP+port (effectively connection) - * if session tracking is not used. * * @param value value of the flag */ @@ -1164,7 +1097,10 @@ private boolean addWhitelistAddress(List list, String address) { address = address.trim(); - return address.length() > 0 && list.add(address); + if (address.length() <= 0) + return false; + list.add(address); + return true; } /** @@ -1191,25 +1127,23 @@ * A RateTracker is associated with a connection, and stores request rate * data. */ - static class RateTracker implements Runnable, HttpSessionBindingListener, HttpSessionActivationListener, Serializable + static class RateTracker implements Runnable, Serializable { private static final long serialVersionUID = 3534663738034577872L; protected final String _filterName; protected transient ServletContext _context; protected final String _id; - protected final RateType _type; protected final int _maxRequestsPerSecond; protected final long[] _timestamps; protected int _next; - public RateTracker(ServletContext context, String filterName, String id, RateType type, int maxRequestsPerSecond) + RateTracker(ServletContext context, String filterName, String id, int maxRequestsPerSecond) { _context = context; _filterName = filterName; _id = id; - _type = type; _maxRequestsPerSecond = maxRequestsPerSecond; _timestamps = new long[maxRequestsPerSecond]; _next = 0; @@ -1247,52 +1181,6 @@ return _id; } - public RateType getType() - { - return _type; - } - - @Override - public void valueBound(HttpSessionBindingEvent event) - { - if (LOG.isDebugEnabled()) - LOG.debug("Value bound: {}", getId()); - _context = event.getSession().getServletContext(); - } - - @Override - public void valueUnbound(HttpSessionBindingEvent event) - { - //take the tracker out of the list of trackers - DoSFilter filter = (DoSFilter)event.getSession().getServletContext().getAttribute(_filterName); - removeFromRateTrackers(filter, _id); - _context = null; - } - - @Override - public void sessionWillPassivate(HttpSessionEvent se) - { - //take the tracker of the list of trackers (if its still there) - DoSFilter filter = (DoSFilter)se.getSession().getServletContext().getAttribute(_filterName); - removeFromRateTrackers(filter, _id); - _context = null; - } - - @Override - public void sessionDidActivate(HttpSessionEvent se) - { - RateTracker tracker = (RateTracker)se.getSession().getAttribute(__TRACKER); - ServletContext context = se.getSession().getServletContext(); - tracker.setContext(context); - DoSFilter filter = (DoSFilter)context.getAttribute(_filterName); - if (filter == null) - { - LOG.info("No filter {} for rate tracker {}", _filterName, tracker); - return; - } - addToRateTrackers(filter, tracker); - } - public void setContext(ServletContext context) { _context = context; @@ -1344,7 +1232,7 @@ @Override public String toString() { - return "RateTracker/" + _id + "/" + _type; + return "RateTracker/" + _id; } public class Overage implements OverLimit @@ -1359,12 +1247,6 @@ } @Override - public RateType getRateType() - { - return _type; - } - - @Override public String getRateId() { return _id; @@ -1385,23 +1267,20 @@ @Override public String toString() { - final StringBuilder sb = new StringBuilder(OverLimit.class.getSimpleName()); - sb.append('@').append(Integer.toHexString(hashCode())); - sb.append("[type=").append(getRateType()); - sb.append(", id=").append(getRateId()); - sb.append(", duration=").append(duration); - sb.append(", count=").append(count); - sb.append(']'); - return sb.toString(); + return OverLimit.class.getSimpleName() + '@' + Integer.toHexString(hashCode()) + + "[id=" + getRateId() + + ", duration=" + duration + + ", count=" + count + + ']'; } } } private static class FixedRateTracker extends RateTracker { - public FixedRateTracker(ServletContext context, String filterName, String id, RateType type, int numRecentRequestsTracked) + public FixedRateTracker(ServletContext context, String filterName, String id, int numRecentRequestsTracked) { - super(context, filterName, id, type, numRecentRequestsTracked); + super(context, filterName, id, numRecentRequestsTracked); } @Override @@ -1452,17 +1331,14 @@ private class DoSAsyncListener extends DoSTimeoutAsyncListener { - private final RateType priority; - - public DoSAsyncListener(RateType priority) + public DoSAsyncListener() { - this.priority = priority; } @Override public void onTimeout(AsyncEvent event) throws IOException { - _queues.get(priority).remove(event.getAsyncContext()); + _queue.remove(event.getAsyncContext()); // TODO what??? super.onTimeout(event); } } @@ -1510,8 +1386,6 @@ public interface OverLimit { - RateType getRateType(); - String getRateId(); Duration getDuration(); @@ -1538,13 +1412,13 @@ switch (action) { case REJECT: - LOG.warn("DOS ALERT: Request rejected ip={}, overlimit={}, session={}, user={}", request.getRemoteAddr(), overlimit, request.getRequestedSessionId(), request.getUserPrincipal()); + LOG.warn("DoS ALERT: Request rejected ip={}, overlimit={}, user={}", request.getRemoteAddr(), overlimit, request.getUserPrincipal()); break; case DELAY: - LOG.warn("DOS ALERT: Request delayed={}ms, ip={}, overlimit={}, session={}, user={}", dosFilter.getDelayMs(), request.getRemoteAddr(), overlimit, request.getRequestedSessionId(), request.getUserPrincipal()); + LOG.warn("DoS ALERT: Request delayed={}ms, ip={}, overlimit={}, user={}", dosFilter.getDelayMs(), request.getRemoteAddr(), overlimit, request.getUserPrincipal()); break; case THROTTLE: - LOG.warn("DOS ALERT: Request throttled ip={}, overlimit={}, session={}, user={}", request.getRemoteAddr(), overlimit, request.getRequestedSessionId(), request.getUserPrincipal()); + LOG.warn("DoS ALERT: Request throttled ip={}, overlimit={}, user={}", request.getRemoteAddr(), overlimit, request.getUserPrincipal()); break; } diff -Nru jetty9-9.4.50/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PushCacheFilter.java jetty9-9.4.57/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PushCacheFilter.java --- jetty9-9.4.50/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PushCacheFilter.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PushCacheFilter.java 2024-12-19 21:51:26.000000000 +0000 @@ -73,7 +73,9 @@ * cache.

    *

    If the init param useQueryInKey is set, then the query string is used as * as part of the key to identify a resource

    + * @deprecated no replacement for this deprecated http feature */ +@Deprecated @ManagedObject("Push cache based on the HTTP 'Referer' header") public class PushCacheFilter implements Filter { @@ -87,6 +89,11 @@ private long _renew = System.nanoTime(); private boolean _useQueryInKey; + public PushCacheFilter() + { + LOG.warn(PushCacheFilter.class.getSimpleName() + " is an example class not suitable for production."); + } + @Override public void init(FilterConfig config) throws ServletException { diff -Nru jetty9-9.4.50/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PushSessionCacheFilter.java jetty9-9.4.57/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PushSessionCacheFilter.java --- jetty9-9.4.50/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PushSessionCacheFilter.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PushSessionCacheFilter.java 2024-12-19 21:51:26.000000000 +0000 @@ -41,6 +41,10 @@ import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +/** + * @deprecated no replacement for this deprecated http feature + */ +@Deprecated public class PushSessionCacheFilter implements Filter { private static final String TARGET_ATTR = "PushCacheFilter.target"; @@ -49,6 +53,11 @@ private final ConcurrentMap _cache = new ConcurrentHashMap<>(); private long _associateDelay = 5000L; + public PushSessionCacheFilter() + { + LOG.warn(PushSessionCacheFilter.class.getSimpleName() + " is an example class not suitable for production."); + } + @Override public void init(FilterConfig config) throws ServletException { diff -Nru jetty9-9.4.50/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AbstractDoSFilterTest.java jetty9-9.4.57/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AbstractDoSFilterTest.java --- jetty9-9.4.50/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AbstractDoSFilterTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AbstractDoSFilterTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -48,9 +48,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.lessThan; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; public abstract class AbstractDoSFilterTest { @@ -262,60 +260,6 @@ } @Test - public void testSessionTracking() throws Exception - { - // get a session, first - String requestSession = "GET /ctx/dos/test?session=true HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; - String response = doRequests("", 1, 0, 0, requestSession); - String sessionId = response.substring(response.indexOf("Set-Cookie: ") + 12, response.indexOf(";")); - - // all other requests use this session - String request = "GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nCookie: " + sessionId + "\r\n\r\n"; - String last = "GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\nCookie: " + sessionId + "\r\n\r\n"; - String responses = doRequests(request + request + request + request + request, 2, 1100, 1100, last); - - assertEquals(11, count(responses, "HTTP/1.1 200 OK")); - assertEquals(2, count(responses, "DoSFilter: delayed")); - } - - @Test - public void testMultipleSessionTracking() throws Exception - { - // get some session ids, first - String requestSession = "GET /ctx/dos/test?session=true HTTP/1.1\r\nHost: localhost\r\n\r\n"; - String closeRequest = "GET /ctx/dos/test?session=true HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"; - String response = doRequests(requestSession + requestSession, 1, 0, 0, closeRequest); - - String[] sessions = response.split("\r\n\r\n"); - - String sessionId1 = sessions[0].substring(sessions[0].indexOf("Set-Cookie: ") + 12, sessions[0].indexOf(";")); - String sessionId2 = sessions[1].substring(sessions[1].indexOf("Set-Cookie: ") + 12, sessions[1].indexOf(";")); - - // alternate between sessions - String request1 = "GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nCookie: " + sessionId1 + "\r\n\r\n"; - String request2 = "GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nCookie: " + sessionId2 + "\r\n\r\n"; - String last = "GET /ctx/dos/test HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\nCookie: " + sessionId2 + "\r\n\r\n"; - - // ensure the sessions are new - doRequests(request1 + request2, 1, 1100, 1100, last); - Thread.sleep(1000); - - String responses = doRequests(request1 + request2 + request1 + request2 + request1, 2, 1100, 1100, last); - - assertEquals(11, count(responses, "HTTP/1.1 200 OK")); - // This test is system speed dependent, so allow some (20%-ish) requests to be delayed, but not more. - assertThat("delayed count", count(responses, "DoSFilter: delayed"), lessThan(2)); - - // alternate between sessions - responses = doRequests(request1 + request2 + request1 + request2 + request1, 2, 250, 250, last); - - // System.err.println(responses); - assertEquals(11, count(responses, "HTTP/1.1 200 OK")); - int delayedRequests = count(responses, "DoSFilter: delayed"); - assertTrue(delayedRequests >= 2 && delayedRequests <= 5, "delayedRequests: " + delayedRequests + " is not between 2 and 5"); - } - - @Test public void testUnresponsiveClient() throws Exception { int numRequests = 1000; diff -Nru jetty9-9.4.50/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterTest.java jetty9-9.4.57/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterTest.java --- jetty9-9.4.50/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -173,7 +173,7 @@ { boolean exceeded = false; ServletContext context = new ContextHandler.StaticContext(); - RateTracker rateTracker = new RateTracker(context, doSFilter.getName(), "test2", DoSFilter.RateType.UNKNOWN, 4); + RateTracker rateTracker = new RateTracker(context, doSFilter.getName(), "test2", 4); for (int i = 0; i < 5; i++) { diff -Nru jetty9-9.4.50/jetty-spring/pom.xml jetty9-9.4.57/jetty-spring/pom.xml --- jetty9-9.4.50/jetty-spring/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-spring/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,14 +2,14 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-spring Example :: Jetty Spring - 5.3.23 + 5.3.39 target/dependencies ${project.groupId}.spring true diff -Nru jetty9-9.4.50/jetty-spring/src/main/config/modules/spring.mod jetty9-9.4.57/jetty-spring/src/main/config/modules/spring.mod --- jetty9-9.4.50/jetty-spring/src/main/config/modules/spring.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-spring/src/main/config/modules/spring.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enable spring configuration processing so all jetty style diff -Nru jetty9-9.4.50/jetty-start/pom.xml jetty9-9.4.57/jetty-start/pom.xml --- jetty9-9.4.50/jetty-start/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-start/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-start diff -Nru jetty9-9.4.50/jetty-start/src/main/java/org/eclipse/jetty/start/ModuleGraphWriter.java jetty9-9.4.57/jetty-start/src/main/java/org/eclipse/jetty/start/ModuleGraphWriter.java --- jetty9-9.4.50/jetty-start/src/main/java/org/eclipse/jetty/start/ModuleGraphWriter.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-start/src/main/java/org/eclipse/jetty/start/ModuleGraphWriter.java 2024-12-19 21:51:26.000000000 +0000 @@ -123,7 +123,7 @@ out.println("/*"); out.println(" * GraphViz Graph of Jetty Modules"); out.println(" * "); - out.println(" * Jetty: https://eclipse.org/jetty/"); + out.println(" * Jetty: https://jetty.org/"); out.println(" * GraphViz: http://graphviz.org/"); out.println(" * "); out.println(" * To Generate Graph image using graphviz:"); diff -Nru jetty9-9.4.50/jetty-start/src/main/resources/org/eclipse/jetty/start/usage.txt jetty9-9.4.57/jetty-start/src/main/resources/org/eclipse/jetty/start/usage.txt --- jetty9-9.4.50/jetty-start/src/main/resources/org/eclipse/jetty/start/usage.txt 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-start/src/main/resources/org/eclipse/jetty/start/usage.txt 2024-12-19 21:51:26.000000000 +0000 @@ -74,7 +74,7 @@ --debug Enable debug output of the startup procedure. Note: this does not setup debug for Jetty itself. If you want debug for Jetty, configure your logging. - https://www.eclipse.org/jetty/documentation/ + https://jetty.org/docs/ --start-log-file= A filename, relative to ${jetty.base}, where all startup @@ -264,4 +264,4 @@ 5) /start.d/*.ini For more information on startup, see the online documentation at - https://www.eclipse.org/jetty/documentation/ + https://jetty.org/docs/ diff -Nru jetty9-9.4.50/jetty-start/src/test/java/org/eclipse/jetty/start/fileinits/MavenLocalRepoFileInitializerTest.java jetty9-9.4.57/jetty-start/src/test/java/org/eclipse/jetty/start/fileinits/MavenLocalRepoFileInitializerTest.java --- jetty9-9.4.50/jetty-start/src/test/java/org/eclipse/jetty/start/fileinits/MavenLocalRepoFileInitializerTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-start/src/test/java/org/eclipse/jetty/start/fileinits/MavenLocalRepoFileInitializerTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -66,7 +66,7 @@ public void testGetCoordinateNotMaven() { MavenLocalRepoFileInitializer repo = new MavenLocalRepoFileInitializer(baseHome); - String ref = "https://www.eclipse.org/jetty/"; + String ref = "https://jetty.org/"; Coordinates coords = repo.getCoordinates(URI.create(ref)); assertThat("Coords", coords, nullValue()); } diff -Nru jetty9-9.4.50/jetty-start/src/test/resources/bogus.xml jetty9-9.4.57/jetty-start/src/test/resources/bogus.xml --- jetty9-9.4.50/jetty-start/src/test/resources/bogus.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-start/src/test/resources/bogus.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,2 +1,3 @@ + \ No newline at end of file diff -Nru jetty9-9.4.50/jetty-start/src/test/resources/dist-home/modules/main.mod jetty9-9.4.57/jetty-start/src/test/resources/dist-home/modules/main.mod --- jetty9-9.4.50/jetty-start/src/test/resources/dist-home/modules/main.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-start/src/test/resources/dist-home/modules/main.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Example of a module diff -Nru jetty9-9.4.50/jetty-unixsocket/pom.xml jetty9-9.4.57/jetty-unixsocket/pom.xml --- jetty9-9.4.50/jetty-unixsocket/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-unixsocket/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-unixsocket diff -Nru jetty9-9.4.50/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-forwarded.xml jetty9-9.4.57/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-forwarded.xml --- jetty9-9.4.50/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-forwarded.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-forwarded.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-http.xml jetty9-9.4.57/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-http.xml --- jetty9-9.4.50/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-http.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-http.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-http2c.xml jetty9-9.4.57/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-http2c.xml --- jetty9-9.4.50/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-http2c.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-http2c.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-proxy-protocol.xml jetty9-9.4.57/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-proxy-protocol.xml --- jetty9-9.4.50/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-proxy-protocol.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-proxy-protocol.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-secure.xml jetty9-9.4.57/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-secure.xml --- jetty9-9.4.50/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-secure.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket-secure.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket.xml jetty9-9.4.57/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket.xml --- jetty9-9.4.50/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-unixsocket/src/main/config-template/etc/jetty-unixsocket.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-unixsocket/src/main/config-template/modules/unixsocket-forwarded.mod jetty9-9.4.57/jetty-unixsocket/src/main/config-template/modules/unixsocket-forwarded.mod --- jetty9-9.4.50/jetty-unixsocket/src/main/config-template/modules/unixsocket-forwarded.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-unixsocket/src/main/config-template/modules/unixsocket-forwarded.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Adds a forwarded request customizer to the HTTP configuration used diff -Nru jetty9-9.4.50/jetty-unixsocket/src/main/config-template/modules/unixsocket-http.mod jetty9-9.4.57/jetty-unixsocket/src/main/config-template/modules/unixsocket-http.mod --- jetty9-9.4.50/jetty-unixsocket/src/main/config-template/modules/unixsocket-http.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-unixsocket/src/main/config-template/modules/unixsocket-http.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Adds an HTTP protocol support to the Unix Domain Socket connector. diff -Nru jetty9-9.4.50/jetty-unixsocket/src/main/config-template/modules/unixsocket-http2c.mod jetty9-9.4.57/jetty-unixsocket/src/main/config-template/modules/unixsocket-http2c.mod --- jetty9-9.4.50/jetty-unixsocket/src/main/config-template/modules/unixsocket-http2c.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-unixsocket/src/main/config-template/modules/unixsocket-http2c.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Adds an HTTP2C connetion factory to the Unix Domain Socket Connector diff -Nru jetty9-9.4.50/jetty-unixsocket/src/main/config-template/modules/unixsocket-prefix.mod jetty9-9.4.57/jetty-unixsocket/src/main/config-template/modules/unixsocket-prefix.mod --- jetty9-9.4.50/jetty-unixsocket/src/main/config-template/modules/unixsocket-prefix.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-unixsocket/src/main/config-template/modules/unixsocket-prefix.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables a Unix Domain Socket Connector that can receive diff -Nru jetty9-9.4.50/jetty-unixsocket/src/main/config-template/modules/unixsocket-proxy-protocol.mod jetty9-9.4.57/jetty-unixsocket/src/main/config-template/modules/unixsocket-proxy-protocol.mod --- jetty9-9.4.50/jetty-unixsocket/src/main/config-template/modules/unixsocket-proxy-protocol.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-unixsocket/src/main/config-template/modules/unixsocket-proxy-protocol.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enables the proxy protocol on the Unix Domain Socket Connector diff -Nru jetty9-9.4.50/jetty-unixsocket/src/main/config-template/modules/unixsocket-secure.mod jetty9-9.4.57/jetty-unixsocket/src/main/config-template/modules/unixsocket-secure.mod --- jetty9-9.4.50/jetty-unixsocket/src/main/config-template/modules/unixsocket-secure.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-unixsocket/src/main/config-template/modules/unixsocket-secure.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enable a secure request customizer on the HTTP Configuration diff -Nru jetty9-9.4.50/jetty-util/pom.xml jetty9-9.4.57/jetty-util/pom.xml --- jetty9-9.4.50/jetty-util/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-util diff -Nru jetty9-9.4.50/jetty-util/src/main/config/etc/console-capture.xml jetty9-9.4.57/jetty-util/src/main/config/etc/console-capture.xml --- jetty9-9.4.50/jetty-util/src/main/config/etc/console-capture.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/etc/console-capture.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/console-capture.mod jetty9-9.4.57/jetty-util/src/main/config/modules/console-capture.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/console-capture.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/console-capture.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Redirects JVMs console stderr and stdout to a log file, diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/jcl-slf4j.mod jetty9-9.4.57/jetty-util/src/main/config/modules/jcl-slf4j.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/jcl-slf4j.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/jcl-slf4j.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Provides a Java Commons Logging (JCL) binding to SLF4J logging. diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/jul-impl.mod jetty9-9.4.57/jetty-util/src/main/config/modules/jul-impl.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/jul-impl.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/jul-impl.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Configures the Java Util Logging mechanism diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/jul-slf4j.mod jetty9-9.4.57/jetty-util/src/main/config/modules/jul-slf4j.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/jul-slf4j.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/jul-slf4j.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Provides a Java Util Logging binding to SLF4J logging. diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/log4j-impl.mod jetty9-9.4.57/jetty-util/src/main/config/modules/log4j-impl.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/log4j-impl.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/log4j-impl.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Provides a Log4j v1.2 API and implementation. diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/log4j2-api.mod jetty9-9.4.57/jetty-util/src/main/config/modules/log4j2-api.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/log4j2-api.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/log4j2-api.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Provides the Log4j v2 API diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/log4j2-impl.mod jetty9-9.4.57/jetty-util/src/main/config/modules/log4j2-impl.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/log4j2-impl.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/log4j2-impl.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Provides a Log4j v2 implementation. diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/log4j2-slf4j.mod jetty9-9.4.57/jetty-util/src/main/config/modules/log4j2-slf4j.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/log4j2-slf4j.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/log4j2-slf4j.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Provides a Log4j v2 binding to SLF4J logging. diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/logback-impl.mod jetty9-9.4.57/jetty-util/src/main/config/modules/logback-impl.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/logback-impl.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/logback-impl.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Provides the logback core implementation diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/logging-jetty.mod jetty9-9.4.57/jetty-util/src/main/config/modules/logging-jetty.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/logging-jetty.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/logging-jetty.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Configure jetty logging mechanism. diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/logging-jul.mod jetty9-9.4.57/jetty-util/src/main/config/modules/logging-jul.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/logging-jul.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/logging-jul.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Configure jetty logging to use Java Util Logging (jul) diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/logging-log4j.mod jetty9-9.4.57/jetty-util/src/main/config/modules/logging-log4j.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/logging-log4j.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/logging-log4j.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Configure jetty logging to use Log4j Logging diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/logging-log4j2.mod jetty9-9.4.57/jetty-util/src/main/config/modules/logging-log4j2.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/logging-log4j2.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/logging-log4j2.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Configure jetty logging to use log4j version 2 diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/logging-logback.mod jetty9-9.4.57/jetty-util/src/main/config/modules/logging-logback.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/logging-logback.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/logging-logback.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Configure jetty logging to use Logback Logging. diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/logging-slf4j.mod jetty9-9.4.57/jetty-util/src/main/config/modules/logging-slf4j.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/logging-slf4j.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/logging-slf4j.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Configure jetty logging to use slf4j. diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/slf4j-api.mod jetty9-9.4.57/jetty-util/src/main/config/modules/slf4j-api.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/slf4j-api.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/slf4j-api.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Provides SLF4J API. Requires a slf4j implementation (eg slf4j-simple-impl) diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/slf4j-jul.mod jetty9-9.4.57/jetty-util/src/main/config/modules/slf4j-jul.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/slf4j-jul.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/slf4j-jul.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Provides a SLF4J binding to Java Util Logging (JUL) logging. diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/slf4j-log4j.mod jetty9-9.4.57/jetty-util/src/main/config/modules/slf4j-log4j.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/slf4j-log4j.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/slf4j-log4j.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Provides a SLF4J binding to the Log4j v1.2 API logging. diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/slf4j-log4j2.mod jetty9-9.4.57/jetty-util/src/main/config/modules/slf4j-log4j2.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/slf4j-log4j2.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/slf4j-log4j2.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Provides a SLF4J binding to Log4j v2 logging. diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/slf4j-logback.mod jetty9-9.4.57/jetty-util/src/main/config/modules/slf4j-logback.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/slf4j-logback.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/slf4j-logback.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Provides a SLF4J binding to Logback logging. diff -Nru jetty9-9.4.50/jetty-util/src/main/config/modules/slf4j-simple-impl.mod jetty9-9.4.57/jetty-util/src/main/config/modules/slf4j-simple-impl.mod --- jetty9-9.4.50/jetty-util/src/main/config/modules/slf4j-simple-impl.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/config/modules/slf4j-simple-impl.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Provides SLF4J simple logging implementation. diff -Nru jetty9-9.4.50/jetty-util/src/main/java/org/eclipse/jetty/util/CharsetStringBuilder.java jetty9-9.4.57/jetty-util/src/main/java/org/eclipse/jetty/util/CharsetStringBuilder.java --- jetty9-9.4.50/jetty-util/src/main/java/org/eclipse/jetty/util/CharsetStringBuilder.java 1970-01-01 00:00:00.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/java/org/eclipse/jetty/util/CharsetStringBuilder.java 2024-12-19 21:51:26.000000000 +0000 @@ -0,0 +1,312 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.util; + +import java.nio.ByteBuffer; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CodingErrorAction; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Objects; + +/** + *

    Build a string from a sequence of bytes and/or characters.

    + *

    Implementations of this interface are optimized for processing a mix of calls to already decoded + * character based appends (e.g. {@link #append(char)} and calls to undecoded byte methods (e.g. {@link #append(byte)}. + * This is particularly useful for decoding % encoded strings that are mostly already decoded but may contain + * escaped byte sequences that are not decoded. The standard {@link CharsetDecoder} API is not well suited for this + * use-case.

    + *

    Any coding errors in the string will be reported by a {@link CharacterCodingException} thrown + * from the {@link #build()} method.

    + * @see Utf8StringBuilder for UTF-8 decoding with replacement of coding errors and/or fast fail behaviour. + * @see CharsetDecoder for decoding arbitrary {@link Charset}s with control over {@link CodingErrorAction}. + */ +public interface CharsetStringBuilder +{ + /** + * @param b An encoded byte to append + */ + void append(byte b); + + /** + * @param c A decoded character to append + */ + void append(char c); + + /** + * @param bytes Array of encoded bytes to append + */ + default void append(byte[] bytes) + { + append(bytes, 0, bytes.length); + } + + /** + * @param b Array of encoded bytes + * @param offset offset into the array + * @param length the number of bytes to append from the array. + */ + default void append(byte[] b, int offset, int length) + { + int end = offset + length; + for (int i = offset; i < end; i++) + append(b[i]); + } + + /** + * @param chars sequence of decoded characters + * @param offset offset into the array + * @param length the number of character to append from the sequence. + */ + default void append(CharSequence chars, int offset, int length) + { + int end = offset + length; + for (int i = offset; i < end; i++) + append(chars.charAt(i)); + } + + /** + * @param buf Buffer of encoded bytes to append. The bytes are consumed from the buffer. + */ + default void append(ByteBuffer buf) + { + int end = buf.position() + buf.remaining(); + while (buf.position() < end) + append(buf.get()); + } + + /** + *

    Build the completed string and reset the buffer.

    + * @return The decoded built string which must be complete in regard to any multibyte sequences. + * @throws CharacterCodingException If the bytes cannot be correctly decoded or a multibyte sequence is incomplete. + */ + String build() throws CharacterCodingException; + + void reset(); + + /** + * @param charset The charset + * @return A {@link CharsetStringBuilder} suitable for the charset. + */ + static CharsetStringBuilder forCharset(Charset charset) + { + Objects.requireNonNull(charset); + if (charset == StandardCharsets.ISO_8859_1) + return new Iso88591StringBuilder(); + if (charset == StandardCharsets.US_ASCII) + return new UsAsciiStringBuilder(); + + // Use a CharsetDecoder that defaults to CodingErrorAction#REPORT + return new DecoderStringBuilder(charset.newDecoder()); + } + + class Iso88591StringBuilder implements CharsetStringBuilder + { + private final StringBuilder _builder = new StringBuilder(); + + @Override + public void append(byte b) + { + _builder.append((char)(0xff & b)); + } + + @Override + public void append(char c) + { + _builder.append(c); + } + + @Override + public void append(CharSequence chars, int offset, int length) + { + _builder.append(chars, offset, offset + length); + } + + @Override + public String build() + { + String s = _builder.toString(); + _builder.setLength(0); + return s; + } + + @Override + public void reset() + { + _builder.setLength(0); + } + } + + class UsAsciiStringBuilder implements CharsetStringBuilder + { + private final StringBuilder _builder = new StringBuilder(); + + @Override + public void append(byte b) + { + if (b < 0) + throw new IllegalArgumentException(); + _builder.append((char)b); + } + + @Override + public void append(char c) + { + _builder.append(c); + } + + @Override + public void append(CharSequence chars, int offset, int length) + { + _builder.append(chars, offset, offset + length); + } + + @Override + public String build() + { + String s = _builder.toString(); + _builder.setLength(0); + return s; + } + + @Override + public void reset() + { + _builder.setLength(0); + } + } + + class DecoderStringBuilder implements CharsetStringBuilder + { + private final CharsetDecoder _decoder; + private final StringBuilder _stringBuilder = new StringBuilder(32); + private ByteBuffer _buffer = ByteBuffer.allocate(32); + + public DecoderStringBuilder(CharsetDecoder charsetDecoder) + { + _decoder = charsetDecoder; + } + + private void ensureSpace(int needed) + { + int space = _buffer.remaining(); + if (space < needed) + { + int position = _buffer.position(); + _buffer = ByteBuffer.wrap(Arrays.copyOf(_buffer.array(), _buffer.capacity() + needed - space + 32)); + _buffer.position(position); + } + } + + @Override + public void append(byte b) + { + ensureSpace(1); + _buffer.put(b); + } + + @Override + public void append(char c) + { + if (_buffer.position() > 0) + { + try + { + // Append any data already in the decoder + _buffer.flip(); + _stringBuilder.append(_decoder.decode(_buffer)); + _buffer.clear(); + } + catch (CharacterCodingException e) + { + // This will be thrown only if the decoder is configured to REPORT, + // otherwise errors will be ignored or replaced and we will not catch here. + throw new RuntimeException(e); + } + } + _stringBuilder.append(c); + } + + @Override + public void append(CharSequence chars, int offset, int length) + { + if (_buffer.position() > 0) + { + try + { + // Append any data already in the decoder + _buffer.flip(); + _stringBuilder.append(_decoder.decode(_buffer)); + _buffer.clear(); + } + catch (CharacterCodingException e) + { + // This will be thrown only if the decoder is configured to REPORT, + // otherwise errors will be ignored or replaced and we will not catch here. + throw new RuntimeException(e); + } + } + _stringBuilder.append(chars, offset, offset + length); + } + + @Override + public void append(byte[] b, int offset, int length) + { + ensureSpace(length); + _buffer.put(b, offset, length); + } + + @Override + public void append(ByteBuffer buf) + { + ensureSpace(buf.remaining()); + _buffer.put(buf); + } + + @Override + public String build() throws CharacterCodingException + { + try + { + if (_buffer.position() > 0) + { + _buffer.flip(); + CharSequence decoded = _decoder.decode(_buffer); + _buffer.clear(); + if (_stringBuilder.length() == 0) + return decoded.toString(); + _stringBuilder.append(decoded); + } + return _stringBuilder.toString(); + } + finally + { + _stringBuilder.setLength(0); + } + } + + @Override + public void reset() + { + _stringBuilder.setLength(0); + } + } +} diff -Nru jetty9-9.4.50/jetty-util/src/main/java/org/eclipse/jetty/util/IteratingCallback.java jetty9-9.4.57/jetty-util/src/main/java/org/eclipse/jetty/util/IteratingCallback.java --- jetty9-9.4.50/jetty-util/src/main/java/org/eclipse/jetty/util/IteratingCallback.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/java/org/eclipse/jetty/util/IteratingCallback.java 2024-12-19 21:51:26.000000000 +0000 @@ -24,109 +24,118 @@ /** * This specialized callback implements a pattern that allows - * a large job to be broken into smaller tasks using iteration - * rather than recursion. + * a large asynchronous task to be broken into smaller + * asynchronous sub-tasks using iteration rather than recursion. *

    * A typical example is the write of a large content to a socket, * divided in chunks. Chunk C1 is written by thread T1, which * also invokes the callback, which writes chunk C2, which invokes * the callback again, which writes chunk C3, and so forth. - *

    *

    - * The problem with the example is that if the callback thread + * The problem with the example above is that if the callback thread * is the same that performs the I/O operation, then the process * is recursive and may result in a stack overflow. * To avoid the stack overflow, a thread dispatch must be performed, * causing context switching and cache misses, affecting performance. - *

    *

    - * To avoid this issue, this callback uses an AtomicReference to - * record whether success callback has been called during the processing - * of a sub task, and if so then the processing iterates rather than - * recurring. - *

    + * To avoid this issue, this callback atomically records whether + * the callback for an asynchronous sub-task has been called + * during the processing of the asynchronous sub-task, and if so + * then the processing of the large asynchronous task iterates + * rather than recursing. *

    - * Subclasses must implement method {@link #process()} where the sub - * task is executed and a suitable {@link IteratingCallback.Action} is - * returned to this callback to indicate the overall progress of the job. - * This callback is passed to the asynchronous execution of each sub - * task and a call the {@link #succeeded()} on this callback represents - * the completion of the sub task. - *

    + * Subclasses must implement method {@link #process()} where the + * asynchronous sub-task is initiated and a suitable {@link Action} + * is returned to this callback to indicate the overall progress of + * the large asynchronous task. + * This callback is passed to the asynchronous sub-task, and a call + * to {@link #succeeded()} on this callback represents the successful + * completion of the asynchronous sub-task, while a call to + * {@link #failed(Throwable)} on this callback represents the + * completion with a failure of the large asynchronous task. */ public abstract class IteratingCallback implements Callback { /** - * The internal states of this callback + * The internal states of this callback. */ private enum State { /** - * This callback is IDLE, ready to iterate. + * This callback is idle, ready to iterate. */ IDLE, /** - * This callback is iterating calls to {@link #process()} and is dealing with - * the returns. To get into processing state, it much of held the lock state - * and set iterating to true. + * This callback is just about to call {@link #process()}, + * or within it, or just exited from it, either normally + * or by throwing. */ PROCESSING, /** - * Waiting for a schedule callback + * Method {@link #process()} returned {@link Action#SCHEDULED} + * and this callback is waiting for the asynchronous sub-task + * to complete. */ PENDING, /** - * Called by a schedule callback + * The asynchronous sub-task was completed successfully + * via a call to {@link #succeeded()} while in + * {@link #PROCESSING} state. */ CALLED, /** - * The overall job has succeeded as indicated by a {@link Action#SUCCEEDED} return - * from {@link IteratingCallback#process()} + * The iteration terminated successfully as indicated by + * {@link Action#SUCCEEDED} returned from + * {@link IteratingCallback#process()}. */ SUCCEEDED, /** - * The overall job has failed as indicated by a call to {@link IteratingCallback#failed(Throwable)} + * The iteration terminated with a failure via a call + * to {@link IteratingCallback#failed(Throwable)}. */ FAILED, /** - * This callback has been closed and cannot be reset. + * This callback has been {@link #close() closed} and + * cannot be {@link #reset() reset}. */ CLOSED } /** - * The indication of the overall progress of the overall job that - * implementations of {@link #process()} must return. + * The indication of the overall progress of the iteration + * that implementations of {@link #process()} must return. */ protected enum Action { /** * Indicates that {@link #process()} has no more work to do, - * but the overall job is not completed yet, probably waiting + * but the iteration is not completed yet, probably waiting * for additional events to trigger more work. */ IDLE, /** - * Indicates that {@link #process()} is executing asynchronously - * a sub task, where the execution has started but the callback + * Indicates that {@link #process()} has initiated an asynchronous + * sub-task, where the execution has started but the callback + * that signals the completion of the asynchronous sub-task * may have not yet been invoked. */ SCHEDULED, - /** - * Indicates that {@link #process()} has completed the overall job. + * Indicates that {@link #process()} has completed the whole + * iteration successfully. */ SUCCEEDED } private Locker _locker = new Locker(); private State _state; + private Throwable _failure; private boolean _iterate; protected IteratingCallback() @@ -140,11 +149,10 @@ } /** - * Method called by {@link #iterate()} to process the sub task. + * Method called by {@link #iterate()} to process the asynchronous sub-task. *

    - * Implementations must start the asynchronous execution of the sub task + * Implementations must initiate the asynchronous execution of the sub-task * (if any) and return an appropriate action: - *

    *
      *
    • {@link Action#IDLE} when no sub tasks are available for execution * but the overall job is not completed yet
    • @@ -154,7 +162,7 @@ *
    * * @return the appropriate Action - * @throws Throwable if the sub task processing throws + * @throws Throwable if the sub-task processing throws */ protected abstract Action process() throws Throwable; @@ -179,44 +187,42 @@ /** * This method must be invoked by applications to start the processing - * of sub tasks. It can be called at any time by any thread, and it's - * contract is that when called, then the {@link #process()} method will - * be called during or soon after, either by the calling thread or by - * another thread. + * of asynchronous sub-tasks. + *

    + * It can be called at any time by any thread, and its contract is that + * when called, then the {@link #process()} method will be called during + * or soon after, either by the calling thread or by another thread, but + * in either case by one thread only. */ public void iterate() { boolean process = false; - loop: - while (true) + try (Locker.Lock lock = _locker.lock()) { - try (Locker.Lock lock = _locker.lock()) + switch (_state) { - switch (_state) - { - case PENDING: - case CALLED: - // process will be called when callback is handled - break loop; + case PENDING: + case CALLED: + // process will be called when callback is handled + break; - case IDLE: - _state = State.PROCESSING; - process = true; - break loop; + case IDLE: + _state = State.PROCESSING; + process = true; + break; - case PROCESSING: - _iterate = true; - break loop; + case PROCESSING: + _iterate = true; + break; - case FAILED: - case SUCCEEDED: - break loop; + case FAILED: + case SUCCEEDED: + break; - case CLOSED: - default: - throw new IllegalStateException(toString()); - } + case CLOSED: + default: + throw new IllegalStateException(toString()); } } if (process) @@ -228,14 +234,15 @@ // This should only ever be called when in processing state, however a failed or close call // may happen concurrently, so state is not assumed. - boolean onCompleteSuccess = false; + boolean notifyCompleteSuccess = false; + Throwable notifyCompleteFailure = null; // While we are processing processing: while (true) { // Call process to get the action that we have to take. - Action action; + Action action = null; try { action = process(); @@ -243,7 +250,7 @@ catch (Throwable x) { failed(x); - break processing; + // Fall through to possibly invoke onCompleteFailure(). } // acted on the action we have just received @@ -253,65 +260,65 @@ { case PROCESSING: { - switch (action) + if (action != null) { - case IDLE: + switch (action) { - // Has iterate been called while we were processing? - if (_iterate) + case IDLE: + { + // Has iterate been called while we were processing? + if (_iterate) + { + // yes, so skip idle and keep processing + _iterate = false; + continue; + } + + // No, so we can go idle + _state = State.IDLE; + break processing; + } + case SCHEDULED: { - // yes, so skip idle and keep processing _iterate = false; - _state = State.PROCESSING; - continue processing; + // we won the race against the callback, so the callback has to process and we can break processing + _state = State.PENDING; + break processing; + } + case SUCCEEDED: + { + // we lost the race against the callback, + _iterate = false; + _state = State.SUCCEEDED; + notifyCompleteSuccess = true; + break processing; + } + default: + { + break; } - - // No, so we can go idle - _state = State.IDLE; - break processing; - } - - case SCHEDULED: - { - // we won the race against the callback, so the callback has to process and we can break processing - _state = State.PENDING; - break processing; - } - - case SUCCEEDED: - { - // we lost the race against the callback, - _iterate = false; - _state = State.SUCCEEDED; - onCompleteSuccess = true; - break processing; } - - default: - break; } throw new IllegalStateException(String.format("%s[action=%s]", this, action)); } case CALLED: { - switch (action) - { - case SCHEDULED: - { - // we lost the race, so we have to keep processing - _state = State.PROCESSING; - continue processing; - } - - default: - throw new IllegalStateException(String.format("%s[action=%s]", this, action)); - } + if (action != Action.SCHEDULED) + throw new IllegalStateException(String.format("%s[action=%s]", this, action)); + _iterate = false; + // we lost the race, so we have to keep processing + _state = State.PROCESSING; + continue; } - case SUCCEEDED: case FAILED: case CLOSED: + notifyCompleteFailure = _failure; + _failure = null; + break processing; + + case SUCCEEDED: break processing; case IDLE: @@ -322,14 +329,17 @@ } } - if (onCompleteSuccess) + if (notifyCompleteSuccess) onCompleteSuccess(); + else if (notifyCompleteFailure != null) + onCompleteFailure(notifyCompleteFailure); } /** - * Invoked when the sub task succeeds. - * Subclasses that override this method must always remember to call - * {@code super.succeeded()}. + * Method to invoke when the asynchronous sub-task succeeds. + *

    + * Subclasses that override this method must always remember + * to call {@code super.succeeded()}. */ @Override public void succeeded() @@ -367,9 +377,18 @@ } /** - * Invoked when the sub task fails. - * Subclasses that override this method must always remember to call - * {@code super.failed(Throwable)}. + * Method to invoke when the asynchronous sub-task fails, + * or to fail the overall asynchronous task and therefore + * terminate the iteration. + *

    + * Subclasses that override this method must always remember + * to call {@code super.failed(Throwable)}. + *

    + * Eventually, {@link #onCompleteFailure(Throwable)} is + * called, either by the caller thread or by the processing + * thread. + * + * @see #isFailed() */ @Override public void failed(Throwable x) @@ -386,14 +405,18 @@ case CALLED: // too late!. break; - case PENDING: - case PROCESSING: { _state = State.FAILED; failure = true; break; } + case PROCESSING: + { + _state = State.FAILED; + _failure = x; + break; + } default: throw new IllegalStateException(toString()); } @@ -402,6 +425,15 @@ onCompleteFailure(x); } + /** + * Method to invoke to forbid further invocations to {@link #iterate()} + * and {@link #reset()}. + *

    + * When this method is invoked during processing, it behaves like invoking + * {@link #failed(Throwable)}. + * + * @see #isClosed() + */ public void close() { String failure = null; @@ -415,12 +447,18 @@ _state = State.CLOSED; break; + case PROCESSING: + _failure = new IOException(String.format("Close %s in state %s", this, _state)); + _state = State.CLOSED; + break; + case CLOSED: break; default: failure = String.format("Close %s in state %s", this, _state); _state = State.CLOSED; + break; } } @@ -428,9 +466,16 @@ onCompleteFailure(new IOException(failure)); } - /* - * only for testing - * @return whether this callback is idle and {@link #iterate()} needs to be called + boolean isPending() + { + try (Locker.Lock lock = _locker.lock()) + { + return _state == State.PENDING; + } + } + + /** + * @return whether this callback is idle, and {@link #iterate()} needs to be called */ boolean isIdle() { @@ -440,6 +485,9 @@ } } + /** + * @return whether this callback has been {@link #close() closed} + */ public boolean isClosed() { try (Locker.Lock lock = _locker.lock()) @@ -449,7 +497,7 @@ } /** - * @return whether this callback has failed + * @return whether this callback has been {@link #failed(Throwable) failed} */ public boolean isFailed() { @@ -460,7 +508,9 @@ } /** - * @return whether this callback has succeeded + * @return whether this callback and the overall asynchronous task has been succeeded + * + * @see #onCompleteSuccess() */ public boolean isSucceeded() { @@ -473,9 +523,9 @@ /** * Resets this callback. *

    - * A callback can only be reset to IDLE from the - * SUCCEEDED or FAILED states or if it is already IDLE. - *

    + * A callback can only be reset to the idle state from the + * {@link #isSucceeded() succeeded} or {@link #isFailed() failed} states + * or if it is already idle. * * @return true if the reset was successful */ @@ -490,8 +540,9 @@ case SUCCEEDED: case FAILED: - _iterate = false; _state = State.IDLE; + _failure = null; + _iterate = false; return true; default: diff -Nru jetty9-9.4.50/jetty-util/src/main/java/org/eclipse/jetty/util/Jetty.java jetty9-9.4.57/jetty-util/src/main/java/org/eclipse/jetty/util/Jetty.java --- jetty9-9.4.50/jetty-util/src/main/java/org/eclipse/jetty/util/Jetty.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/java/org/eclipse/jetty/util/Jetty.java 2024-12-19 21:51:26.000000000 +0000 @@ -72,7 +72,7 @@ else VERSION = System.getProperty("jetty.version", __buildProperties.getProperty("version", "9.4.z-SNAPSHOT")); - POWERED_BY = "Powered by Jetty:// " + VERSION + ""; + POWERED_BY = "Powered by Jetty:// " + VERSION + ""; // Show warning when RC# or M# is in version string STABLE = !VERSION.matches("^.*\\.(RC|M)[0-9]+$"); diff -Nru jetty9-9.4.50/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java jetty9-9.4.57/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java --- jetty9-9.4.50/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java 2024-12-19 21:51:26.000000000 +0000 @@ -64,8 +64,11 @@ public class MultiPartInputStreamParser { private static final Logger LOG = Log.getLogger(MultiPartInputStreamParser.class); + private static final int DEFAULT_MAX_FORM_KEYS = 1000; public static final MultipartConfigElement __DEFAULT_MULTIPART_CONFIG = new MultipartConfigElement(System.getProperty("java.io.tmpdir")); - public static final MultiMap EMPTY_MAP = new MultiMap(Collections.emptyMap()); + public static final MultiMap EMPTY_MAP = new MultiMap<>(Collections.emptyMap()); + private final int _maxParts; + private int _numParts; protected InputStream _in; protected MultipartConfigElement _config; protected String _contentType; @@ -395,9 +398,22 @@ */ public MultiPartInputStreamParser(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir) { + this(in, contentType, config, contextTmpDir, DEFAULT_MAX_FORM_KEYS); + } + + /** + * @param in Request input stream + * @param contentType Content-Type header + * @param config MultipartConfigElement + * @param contextTmpDir javax.servlet.context.tempdir + * @param maxParts the maximum number of parts that can be parsed from the multipart content (0 for no parts allowed, -1 for unlimited parts). + */ + public MultiPartInputStreamParser(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir, int maxParts) + { _contentType = contentType; _config = config; _contextTmpDir = contextTmpDir; + _maxParts = maxParts; if (_contextTmpDir == null) _contextTmpDir = new File(System.getProperty("java.io.tmpdir")); @@ -693,6 +709,11 @@ continue; } + // Check if we can create a new part. + _numParts++; + if (_maxParts >= 0 && _numParts > _maxParts) + throw new IllegalStateException(String.format("Form with too many parts [%d > %d]", _numParts, _maxParts)); + //Have a new Part MultiPart part = new MultiPart(name, filename); part.setHeaders(headers); diff -Nru jetty9-9.4.50/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java jetty9-9.4.57/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java --- jetty9-9.4.50/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java 2024-12-19 21:51:26.000000000 +0000 @@ -107,6 +107,27 @@ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177' }; + // @checkstyle-disable-check : IllegalTokenTextCheck + private static final char[] uppercases = + { + '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', + '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', + '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', + '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', + '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', + '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', + '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', + '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', + '\100', '\101', '\102', '\103', '\104', '\105', '\106', '\107', + '\110', '\111', '\112', '\113', '\114', '\115', '\116', '\117', + '\120', '\121', '\122', '\123', '\124', '\125', '\126', '\127', + '\130', '\131', '\132', '\133', '\134', '\135', '\136', '\137', + '\140', '\101', '\102', '\103', '\104', '\105', '\106', '\107', + '\110', '\111', '\112', '\113', '\114', '\115', '\116', '\117', + '\120', '\121', '\122', '\123', '\124', '\125', '\126', '\127', + '\130', '\131', '\132', '\173', '\174', '\175', '\176', '\177' + }; + /** * fast lower case conversion. Only works on ascii (not unicode) * @@ -145,6 +166,42 @@ } /** + * fast upper case conversion. Only works on ascii (not unicode) + * + * @param s the string to convert + * @return a lower case version of s + */ + public static String asciiToUpperCase(String s) + { + if (s == null) + return null; + + char[] c = null; + int i = s.length(); + // look for first conversion + while (i-- > 0) + { + char c1 = s.charAt(i); + if (c1 <= 127) + { + char c2 = uppercases[c1]; + if (c1 != c2) + { + c = s.toCharArray(); + c[i] = c2; + break; + } + } + } + while (i-- > 0) + { + if (c[i] <= 127) + c[i] = uppercases[c[i]]; + } + return c == null ? s : new String(c); + } + + /** * Replace all characters from input string that are known to have * special meaning in various filesystems. * @@ -454,6 +511,22 @@ } /** + * Generate a string from another string repeated n times. + * + * @param s the string to use + * @param n the number of times this string should be appended + */ + public static String stringFrom(String s, int n) + { + StringBuilder stringBuilder = new StringBuilder(s.length() * n); + for (int i = 0; i < n; i++) + { + stringBuilder.append(s); + } + return stringBuilder.toString(); + } + + /** * Return a non null string. * * @param s String diff -Nru jetty9-9.4.50/jetty-util/src/main/java/org/eclipse/jetty/util/URIUtil.java jetty9-9.4.57/jetty-util/src/main/java/org/eclipse/jetty/util/URIUtil.java --- jetty9-9.4.50/jetty-util/src/main/java/org/eclipse/jetty/util/URIUtil.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/main/java/org/eclipse/jetty/util/URIUtil.java 2024-12-19 21:51:26.000000000 +0000 @@ -1175,11 +1175,13 @@ { switch (scheme) { + case "ws": case "http": if (port != 80) url.append(':').append(port); break; + case "wss": case "https": if (port != 443) url.append(':').append(port); @@ -1209,11 +1211,13 @@ { switch (scheme) { + case "ws": case "http": if (port != 80) url.append(':').append(port); break; + case "wss": case "https": if (port != 443) url.append(':').append(port); diff -Nru jetty9-9.4.50/jetty-util/src/test/java/org/eclipse/jetty/util/IteratingCallbackTest.java jetty9-9.4.57/jetty-util/src/test/java/org/eclipse/jetty/util/IteratingCallbackTest.java --- jetty9-9.4.50/jetty-util/src/test/java/org/eclipse/jetty/util/IteratingCallbackTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/test/java/org/eclipse/jetty/util/IteratingCallbackTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -20,13 +20,18 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler; import org.eclipse.jetty.util.thread.Scheduler; 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.ValueSource; +import static org.awaitility.Awaitility.await; +import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -48,6 +53,45 @@ scheduler.stop(); } + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void testIterateWhileProcessingLoopCount(boolean succeededWinsRace) + { + AtomicInteger count = new AtomicInteger(); + IteratingCallback icb = new IteratingCallback() + { + + @Override + protected Action process() + { + int counter = count.getAndIncrement(); + if (counter == 0) + { + iterate(); + if (succeededWinsRace) + { + succeeded(); + } + else + { + new Thread(() -> + { + await().atMost(5, TimeUnit.SECONDS).until(this::isPending, is(true)); + succeeded(); + }).start(); + } + return Action.SCHEDULED; + } + return Action.IDLE; + } + }; + + icb.iterate(); + + await().atMost(10, TimeUnit.SECONDS).until(icb::isIdle, is(true)); + assertEquals(2, count.get()); + } + @Test public void testNonWaitingProcess() throws Exception { @@ -327,4 +371,44 @@ return isSucceeded(); } } + + @Test + public void testMultipleFailures() throws Exception + { + AtomicInteger process = new AtomicInteger(); + AtomicInteger failure = new AtomicInteger(); + IteratingCallback icb = new IteratingCallback() + { + @Override + protected Action process() throws Throwable + { + process.incrementAndGet(); + return Action.SCHEDULED; + } + + @Override + protected void onCompleteFailure(Throwable cause) + { + super.onCompleteFailure(cause); + failure.incrementAndGet(); + } + }; + + icb.iterate(); + assertEquals(1, process.get()); + assertEquals(0, failure.get()); + + icb.failed(new Throwable("test1")); + + assertEquals(1, process.get()); + assertEquals(1, failure.get()); + + icb.succeeded(); + assertEquals(1, process.get()); + assertEquals(1, failure.get()); + + icb.failed(new Throwable("test2")); + assertEquals(1, process.get()); + assertEquals(1, failure.get()); + } } diff -Nru jetty9-9.4.50/jetty-util/src/test/java/org/eclipse/jetty/util/LazyListTest.java jetty9-9.4.57/jetty-util/src/test/java/org/eclipse/jetty/util/LazyListTest.java --- jetty9-9.4.50/jetty-util/src/test/java/org/eclipse/jetty/util/LazyListTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/test/java/org/eclipse/jetty/util/LazyListTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -1501,12 +1501,12 @@ uris.add(URI.create("http://www.mortbay.org/")); uris.add(URI.create("http://jetty.codehaus.org/jetty/")); uris.add(URI.create("http://www.intalio.com/jetty/")); - uris.add(URI.create("https://www.eclipse.org/jetty/")); + uris.add(URI.create("https://jetty.org/")); // Make sure that Generics pass through the 'get' routine safely. // We should be able to call this without casting the result to URI URI eclipseUri = LazyList.get(uris, 3); - assertEquals("https://www.eclipse.org/jetty/", eclipseUri.toASCIIString()); + assertEquals("https://jetty.org/", eclipseUri.toASCIIString()); } /** diff -Nru jetty9-9.4.50/jetty-util/src/test/java/org/eclipse/jetty/util/RolloverFileOutputStreamTest.java jetty9-9.4.57/jetty-util/src/test/java/org/eclipse/jetty/util/RolloverFileOutputStreamTest.java --- jetty9-9.4.50/jetty-util/src/test/java/org/eclipse/jetty/util/RolloverFileOutputStreamTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/test/java/org/eclipse/jetty/util/RolloverFileOutputStreamTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -83,7 +83,7 @@ } /** - * https://github.com/eclipse/jetty.project/issues/1507 + * https://github.com/jetty/jetty.project/issues/1507 */ @Test public void testMidnightRolloverCalcPDTIssue1507() diff -Nru jetty9-9.4.50/jetty-util/src/test/java/org/eclipse/jetty/util/URIUtilTest.java jetty9-9.4.57/jetty-util/src/test/java/org/eclipse/jetty/util/URIUtilTest.java --- jetty9-9.4.50/jetty-util/src/test/java/org/eclipse/jetty/util/URIUtilTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/test/java/org/eclipse/jetty/util/URIUtilTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -756,4 +756,43 @@ String decoded = URIUtil.decodePath(encoded); assertEquals(path, decoded); } + + public static Stream appendSchemeHostPortCases() + { + return Stream.of( + // Default behaviors of stripping a port number based on scheme + Arguments.of("http", "example.org", 80, "http://example.org"), + Arguments.of("https", "example.org", 443, "https://example.org"), + Arguments.of("ws", "example.org", 80, "ws://example.org"), + Arguments.of("wss", "example.org", 443, "wss://example.org"), + // Mismatches between scheme and port + Arguments.of("http", "example.org", 443, "http://example.org:443"), + Arguments.of("https", "example.org", 80, "https://example.org:80"), + Arguments.of("ws", "example.org", 443, "ws://example.org:443"), + Arguments.of("wss", "example.org", 80, "wss://example.org:80"), + // Odd ports + Arguments.of("http", "example.org", 12345, "http://example.org:12345"), + Arguments.of("https", "example.org", 54321, "https://example.org:54321"), + Arguments.of("ws", "example.org", 6666, "ws://example.org:6666"), + Arguments.of("wss", "example.org", 7777, "wss://example.org:7777") + ); + } + + @ParameterizedTest + @MethodSource("appendSchemeHostPortCases") + public void testAppendSchemeHostPortBuilder(String scheme, String server, int port, String expectedStr) + { + StringBuilder actual = new StringBuilder(); + URIUtil.appendSchemeHostPort(actual, scheme, server, port); + assertEquals(expectedStr, actual.toString()); + } + + @ParameterizedTest + @MethodSource("appendSchemeHostPortCases") + public void testAppendSchemeHostPortBuffer(String scheme, String server, int port, String expectedStr) + { + StringBuffer actual = new StringBuffer(); + URIUtil.appendSchemeHostPort(actual, scheme, server, port); + assertEquals(expectedStr, actual.toString()); + } } diff -Nru jetty9-9.4.50/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8LineParserTest.java jetty9-9.4.57/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8LineParserTest.java --- jetty9-9.4.50/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8LineParserTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8LineParserTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -87,7 +87,7 @@ public void testWildHttpRequestParse() { // Arbitrary Http Response Headers seen in the wild. - // Request URI -> http://www.eclipse.org/jetty/ + // Request URI -> https://jetty.org/ List expected = new ArrayList<>(); expected.add("HEAD /jetty/ HTTP/1.0"); expected.add("User-Agent: \"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.6) Gecko/20060601 Firefox/2.0.0.6 (Ubuntu-feisty)\""); diff -Nru jetty9-9.4.50/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java jetty9-9.4.57/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java --- jetty9-9.4.50/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -222,7 +222,7 @@ public void testNotFileURI(Class resourceClass) { assertThrows(IllegalArgumentException.class, - () -> newResource(resourceClass, new URI("https://www.eclipse.org/jetty/"))); + () -> newResource(resourceClass, new URI("https://jetty.org/"))); } @ParameterizedTest diff -Nru jetty9-9.4.50/jetty-util-ajax/pom.xml jetty9-9.4.57/jetty-util-ajax/pom.xml --- jetty9-9.4.50/jetty-util-ajax/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-util-ajax/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-util-ajax diff -Nru jetty9-9.4.50/jetty-webapp/pom.xml jetty9-9.4.57/jetty-webapp/pom.xml --- jetty9-9.4.50/jetty-webapp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-webapp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-webapp diff -Nru jetty9-9.4.50/jetty-webapp/src/main/config/etc/jetty-webapp.xml jetty9-9.4.57/jetty-webapp/src/main/config/etc/jetty-webapp.xml --- jetty9-9.4.50/jetty-webapp/src/main/config/etc/jetty-webapp.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-webapp/src/main/config/etc/jetty-webapp.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-webapp/src/main/config/modules/webapp.mod jetty9-9.4.57/jetty-webapp/src/main/config/modules/webapp.mod --- jetty9-9.4.50/jetty-webapp/src/main/config/modules/webapp.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-webapp/src/main/config/modules/webapp.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Adds support for servlet specification webapplication to the server diff -Nru jetty9-9.4.50/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java jetty9-9.4.57/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java --- jetty9-9.4.50/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java 2024-12-19 21:51:26.000000000 +0000 @@ -689,7 +689,7 @@ * * @param classOrPackage A pattern. * @see #setServerClasses(String[]) - * @see Jetty Documentation: Classloading + * @see Jetty Documentation: Classloading * @deprecated Use {@link #getServerClasspathPattern()}.{@link ClasspathPattern#add(String)} */ @Deprecated @@ -743,7 +743,7 @@ * * @param classOrPackage A pattern. * @see #setSystemClasses(String[]) - * @see Jetty Documentation: Classloading + * @see Jetty Documentation: Classloading * @deprecated Use {@link #getSystemClasspathPattern()}.{@link ClasspathPattern#add(String)} */ @Deprecated diff -Nru jetty9-9.4.50/jetty-websocket/javax-websocket-client-impl/pom.xml jetty9-9.4.57/jetty-websocket/javax-websocket-client-impl/pom.xml --- jetty9-9.4.50/jetty-websocket/javax-websocket-client-impl/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-websocket/javax-websocket-client-impl/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-websocket/javax-websocket-client-impl/src/test/resources/examples/jetty-websocket-httpclient.xml jetty9-9.4.57/jetty-websocket/javax-websocket-client-impl/src/test/resources/examples/jetty-websocket-httpclient.xml --- jetty9-9.4.50/jetty-websocket/javax-websocket-client-impl/src/test/resources/examples/jetty-websocket-httpclient.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-websocket/javax-websocket-client-impl/src/test/resources/examples/jetty-websocket-httpclient.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-websocket/javax-websocket-server-impl/pom.xml jetty9-9.4.57/jetty-websocket/javax-websocket-server-impl/pom.xml --- jetty9-9.4.50/jetty-websocket/javax-websocket-server-impl/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-websocket/javax-websocket-server-impl/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-websocket/javax-websocket-server-impl/src/main/config/modules/websocket.mod jetty9-9.4.57/jetty-websocket/javax-websocket-server-impl/src/main/config/modules/websocket.mod --- jetty9-9.4.50/jetty-websocket/javax-websocket-server-impl/src/main/config/modules/websocket.mod 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-websocket/javax-websocket-server-impl/src/main/config/modules/websocket.mod 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://jetty.org/docs/9/startup-modules.html [description] Enable websockets for deployed web applications diff -Nru jetty9-9.4.50/jetty-websocket/jetty-websocket-tests/pom.xml jetty9-9.4.57/jetty-websocket/jetty-websocket-tests/pom.xml --- jetty9-9.4.50/jetty-websocket/jetty-websocket-tests/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-websocket/jetty-websocket-tests/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-websocket/pom.xml jetty9-9.4.57/jetty-websocket/pom.xml --- jetty9-9.4.50/jetty-websocket/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-websocket/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-websocket/websocket-api/pom.xml jetty9-9.4.57/jetty-websocket/websocket-api/pom.xml --- jetty9-9.4.50/jetty-websocket/websocket-api/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-websocket/websocket-api/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionFactory.java jetty9-9.4.57/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionFactory.java --- jetty9-9.4.50/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionFactory.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionFactory.java 2024-12-19 21:51:26.000000000 +0000 @@ -37,7 +37,12 @@ public ExtensionFactory() { availableExtensions = new HashMap<>(); - Iterator iterator = ServiceLoader.load(Extension.class).iterator(); + final ServiceLoader sl = ServiceLoader.load(Extension.class); + if (sl == null) + { + return; + } + final Iterator iterator = sl.iterator(); while (true) { try diff -Nru jetty9-9.4.50/jetty-websocket/websocket-client/pom.xml jetty9-9.4.57/jetty-websocket/websocket-client/pom.xml --- jetty9-9.4.50/jetty-websocket/websocket-client/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-websocket/websocket-client/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-websocket/websocket-client/src/test/resources/httpclient/simple/jetty-websocket-httpclient.xml jetty9-9.4.57/jetty-websocket/websocket-client/src/test/resources/httpclient/simple/jetty-websocket-httpclient.xml --- jetty9-9.4.50/jetty-websocket/websocket-client/src/test/resources/httpclient/simple/jetty-websocket-httpclient.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-websocket/websocket-client/src/test/resources/httpclient/simple/jetty-websocket-httpclient.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ - + diff -Nru jetty9-9.4.50/jetty-websocket/websocket-common/pom.xml jetty9-9.4.57/jetty-websocket/websocket-common/pom.xml --- jetty9-9.4.50/jetty-websocket/websocket-common/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-websocket/websocket-common/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/WebSocketRemoteEndpointTest.java jetty9-9.4.57/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/WebSocketRemoteEndpointTest.java --- jetty9-9.4.50/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/WebSocketRemoteEndpointTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/WebSocketRemoteEndpointTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -91,7 +91,7 @@ /** * Ensure that WebSocketRemoteEndpoint honors the correct order of websocket frames. * - * @see eclipse/jetty.project#2491 + * @see eclipse/jetty.project#2491 */ @Test public void testLargeSmallText(TestInfo testInfo) throws ExecutionException, InterruptedException diff -Nru jetty9-9.4.50/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/FragmentExtensionTest.java jetty9-9.4.57/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/FragmentExtensionTest.java --- jetty9-9.4.50/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/FragmentExtensionTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/FragmentExtensionTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -330,7 +330,7 @@ /** * Ensure that FragmentExtension honors the correct order of websocket frames. * - * @see eclipse/jetty.project#2491 + * @see eclipse/jetty.project#2491 */ @Test public void testLargeSmallTextAlternating() throws Exception diff -Nru jetty9-9.4.50/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/FrameFlusherTest.java jetty9-9.4.57/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/FrameFlusherTest.java --- jetty9-9.4.50/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/FrameFlusherTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/FrameFlusherTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -90,7 +90,7 @@ /** * Ensure that FrameFlusher honors the correct order of websocket frames. * - * @see eclipse/jetty.project#2491 + * @see eclipse/jetty.project#2491 */ @Test public void testLargeSmallText() throws ExecutionException, InterruptedException diff -Nru jetty9-9.4.50/jetty-websocket/websocket-server/pom.xml jetty9-9.4.57/jetty-websocket/websocket-server/pom.xml --- jetty9-9.4.50/jetty-websocket/websocket-server/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-websocket/websocket-server/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-websocket/websocket-servlet/pom.xml jetty9-9.4.57/jetty-websocket/websocket-servlet/pom.xml --- jetty9-9.4.50/jetty-websocket/websocket-servlet/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-websocket/websocket-servlet/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 diff -Nru jetty9-9.4.50/jetty-xml/pom.xml jetty9-9.4.57/jetty-xml/pom.xml --- jetty9-9.4.50/jetty-xml/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-xml/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 jetty-xml diff -Nru jetty9-9.4.50/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java jetty9-9.4.57/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java --- jetty9-9.4.50/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java 2024-12-19 21:51:26.000000000 +0000 @@ -18,6 +18,7 @@ package org.eclipse.jetty.xml; +import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; @@ -67,6 +68,7 @@ import org.eclipse.jetty.util.resource.Resource; import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; /** *

    Configures objects from XML.

    @@ -203,7 +205,7 @@ private final String _dtd; private ConfigurationProcessor _processor; - ConfigurationParser getParser() + public XmlParser getXmlParser() { Pool.Entry entry = __parsers.acquire(ConfigurationParser::new); if (entry == null) @@ -220,12 +222,22 @@ */ public XmlConfiguration(Resource resource) throws SAXException, IOException { - try (ConfigurationParser parser = getParser(); InputStream inputStream = resource.getInputStream()) + XmlParser parser = getXmlParser(); + try (InputStream inputStream = resource.getInputStream()) { _location = resource; setConfig(parser.parse(inputStream)); _dtd = parser.getDTD(); } + catch (SAXParseException e) + { + throw new SAXParseException("Unable to parse: " + resource, null, e); + } + finally + { + if (parser instanceof Closeable) + ((Closeable)parser).close(); + } } /** @@ -255,15 +267,21 @@ public XmlConfiguration(String configuration) throws SAXException, IOException { configuration = "\n" + - "" + + "" + configuration; - try (ConfigurationParser parser = getParser(); StringReader reader = new StringReader(configuration)) + XmlParser parser = getXmlParser(); + try (StringReader reader = new StringReader(configuration)) { InputSource source = new InputSource(reader); _location = null; setConfig(parser.parse(source)); _dtd = parser.getDTD(); } + finally + { + if (parser instanceof Closeable) + ((Closeable)parser).close(); + } } /** @@ -278,12 +296,18 @@ public XmlConfiguration(InputStream configuration) throws SAXException, IOException { InputSource source = new InputSource(configuration); - try (ConfigurationParser parser = getParser()) + XmlParser parser = getXmlParser(); + try { _location = null; setConfig(parser.parse(source)); _dtd = parser.getDTD(); } + finally + { + if (parser instanceof Closeable) + ((Closeable)parser).close(); + } } @Override @@ -1918,7 +1942,7 @@ } } - private static class ConfigurationParser extends XmlParser implements AutoCloseable + private static class ConfigurationParser extends XmlParser implements Closeable { private final Pool.Entry _entry; @@ -1942,8 +1966,23 @@ redirectEntity("http://jetty.mortbay.org/configure.dtd", config93); redirectEntity("http://jetty.eclipse.org/configure.dtd", config93); redirectEntity("https://jetty.eclipse.org/configure.dtd", config93); - redirectEntity("http://www.eclipse.org/jetty/configure.dtd", config93); - redirectEntity("https://www.eclipse.org/jetty/configure.dtd", config93); + redirectEntity("http://jetty.mortbay.org/configure.dtd", config93); + + // Register all variations of DOCTYPE entity references for Config 9.3 + String[] schemes = {"http", "https"}; + String[] hosts = {"www.eclipse.org/jetty", "eclipse.org/jetty", "www.eclipse.dev/jetty", "eclipse.dev/jetty", "jetty.org"}; + String[] paths = {"/configure.dtd", "/configure_9_3.dtd"}; + + for (String scheme : schemes) + { + for (String host : hosts) + { + for (String path : paths) + { + redirectEntity(String.format("%s://%s%s", scheme, host, path), config93); + } + } + } redirectEntity("-//Mort Bay Consulting//DTD Configure//EN", config93); redirectEntity("-//Jetty//Configure//EN", config93); } diff -Nru jetty9-9.4.50/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlParser.java jetty9-9.4.57/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlParser.java --- jetty9-9.4.50/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlParser.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlParser.java 2024-12-19 21:51:26.000000000 +0000 @@ -69,9 +69,9 @@ */ public XmlParser() { - SAXParserFactory factory = SAXParserFactory.newInstance(); - boolean validatingDft = factory.getClass().toString().startsWith("org.apache.xerces."); - String validatingProp = System.getProperty("org.eclipse.jetty.xml.XmlParser.Validating", validatingDft ? "true" : "false"); + SAXParserFactory factory = newSAXParserFactory(); + boolean validatingDefault = factory.getClass().toString().contains("org.apache.xerces."); + String validatingProp = System.getProperty("org.eclipse.jetty.xml.XmlParser.Validating", validatingDefault ? "true" : "false"); boolean validating = Boolean.valueOf(validatingProp).booleanValue(); setValidating(validating); } @@ -81,11 +81,16 @@ setValidating(validating); } + protected SAXParserFactory newSAXParserFactory() + { + return SAXParserFactory.newInstance(); + } + public void setValidating(boolean validating) { try { - SAXParserFactory factory = SAXParserFactory.newInstance(); + SAXParserFactory factory = newSAXParserFactory(); factory.setValidating(validating); _parser = factory.newSAXParser(); @@ -127,6 +132,11 @@ return _parser.isValidating(); } + public SAXParser getSAXParser() + { + return _parser; + } + public synchronized void redirectEntity(String name, URL entity) { if (entity != null) @@ -261,18 +271,10 @@ if (pid != null) entity = _redirectMap.get(pid); if (entity == null) - entity = _redirectMap.get(sid); - if (entity == null) - { - String dtd = sid; - if (dtd.lastIndexOf('/') >= 0) - dtd = dtd.substring(dtd.lastIndexOf('/') + 1); - - if (LOG.isDebugEnabled()) - LOG.debug("Can't exact match entity in redirect map, trying " + dtd); - entity = _redirectMap.get(dtd); - } + entity = (URL)_redirectMap.get(sid); + // Only serve entity if found. + // We don't want to serve from unknown hosts or random paths. if (entity != null) { try @@ -289,6 +291,9 @@ LOG.ignore(e); } } + + if (LOG.isDebugEnabled()) + LOG.debug("Entity not found for PID:{} / SID:{}", pid, sid); return null; } diff -Nru jetty9-9.4.50/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java jetty9-9.4.57/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java --- jetty9-9.4.50/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -28,6 +28,7 @@ import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -47,7 +48,6 @@ import org.eclipse.jetty.util.log.StdErrLog; import org.eclipse.jetty.util.resource.PathResource; import org.hamcrest.Matchers; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -57,6 +57,7 @@ import org.junit.jupiter.params.provider.ArgumentsProvider; import org.junit.jupiter.params.provider.ArgumentsSource; import org.junit.jupiter.params.provider.MethodSource; +import org.xml.sax.InputSource; import org.xml.sax.SAXException; import static java.nio.charset.StandardCharsets.UTF_8; @@ -105,8 +106,16 @@ configuration.configure(); } + public static Stream xmlConfigs() + { + return Stream.of( + Arguments.of("org/eclipse/jetty/xml/configureWithAttr.xml"), + Arguments.of("org/eclipse/jetty/xml/configureWithElements.xml") + ); + } + @ParameterizedTest - @ArgumentsSource(ScenarioProvider.class) + @MethodSource("xmlConfigs") public void testPassedObject(String configure) throws Exception { Map properties = new HashMap<>(); @@ -274,10 +283,15 @@ public XmlConfiguration asXmlConfiguration(String filename, String rawXml) throws IOException, SAXException { + if (!rawXml.contains("!DOCTYPE")) + rawXml = "\n" + + "\n" + + rawXml; Path testFile = workDir.getEmptyPathDir().resolve(filename); - try (BufferedWriter writer = Files.newBufferedWriter(testFile, UTF_8)) + try (BufferedWriter writer = Files.newBufferedWriter(testFile, UTF_8, StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) { writer.write(rawXml); + writer.flush(); } return new XmlConfiguration(new PathResource(testFile)); } @@ -1723,6 +1737,43 @@ } } + public static Stream xmlSystemIdSource() + { + List ids = new ArrayList<>(); + + String[] schemes = {"http", "https"}; + String[] hostAndContexts = {"eclipse.org/jetty", "www.eclipse.org/jetty", "eclipse.dev/jetty", "www.eclipse.dev/jetty", "jetty.org"}; + String[] dtdNames = {"/configure.dtd", "/configure_9_3.dtd"}; + + for (String scheme: schemes) + { + for (String hostAndContext: hostAndContexts) + { + for (String dtdName: dtdNames) + { + ids.add(Arguments.of(String.format("%s://%s%s", scheme, hostAndContext, dtdName))); + } + } + } + + return ids.stream(); + } + + /** + * Test to ensure that all the XML System ID variants are covered in the + * {@link XmlConfiguration} internals. + */ + @ParameterizedTest + @MethodSource("xmlSystemIdSource") + public void testSystemIdVariants(String xmlSystemId) throws IOException, SAXException + { + // empty raw xml, just to instantiate XmlConfiguration, so we can access the XmlParser / ConfigurationParser. + XmlConfiguration xmlConfiguration = asXmlConfiguration(""); + XmlParser configurationProcessor = xmlConfiguration.getXmlParser(); + InputSource inputSource = configurationProcessor.resolveEntity(null, xmlSystemId); + assertNotNull(inputSource, "SystemID: " + xmlSystemId + " does not exist"); + } + private void assertHasExpectedLines(String type, List actualLines, String[] expectedLines) { assertThat("Count of " + type, actualLines.size(), is(expectedLines.length)); diff -Nru jetty9-9.4.50/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlParserTest.java jetty9-9.4.57/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlParserTest.java --- jetty9-9.4.50/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlParserTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlParserTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -19,10 +19,17 @@ package org.eclipse.jetty.xml; import java.net.URL; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; import org.junit.jupiter.api.Test; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; public class XmlParserTest { @@ -34,7 +41,7 @@ URL configURL = XmlConfiguration.class.getClassLoader().getResource("org/eclipse/jetty/xml/configure_9_3.dtd"); parser.redirectEntity("configure.dtd", configURL); parser.redirectEntity("configure_9_3.dtd", configURL); - //parser.redirectEntity("http://www.eclipse.org/jetty/configure_9_3.dtd", configURL); + parser.redirectEntity("http://www.eclipse.org/jetty/configure_9_3.dtd", configURL); parser.redirectEntity("http://jetty.eclipse.org/configure.dtd", configURL); parser.redirectEntity("-//Mort Bay Consulting//DTD Configure//EN", configURL); @@ -45,4 +52,32 @@ assertTrue(testDocStr.startsWith("")); } + + /** + * Customize SAXParserFactory behavior. + */ + @Test + public void testNewSAXParserFactory() throws SAXException + { + XmlParser xmlParser = new XmlParser() + { + @Override + protected SAXParserFactory newSAXParserFactory() + { + SAXParserFactory saxParserFactory = super.newSAXParserFactory(); + // Configure at factory level + saxParserFactory.setXIncludeAware(false); + return saxParserFactory; + } + }; + + SAXParser saxParser = xmlParser.getSAXParser(); + assertNotNull(saxParser); + + XMLReader xmlReader = saxParser.getXMLReader(); + // Only run testcase if Xerces is being used. + assumeTrue(xmlReader.getClass().getName().contains("org.apache.xerces.")); + // look to see it was set at XMLReader level + assertFalse(xmlReader.getFeature("http://apache.org/xml/features/xinclude")); + } } diff -Nru jetty9-9.4.50/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configureWithAttr.xml jetty9-9.4.57/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configureWithAttr.xml --- jetty9-9.4.50/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configureWithAttr.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configureWithAttr.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ - + name diff -Nru jetty9-9.4.50/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configureWithElements.xml jetty9-9.4.57/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configureWithElements.xml --- jetty9-9.4.50/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configureWithElements.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configureWithElements.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ - + name diff -Nru jetty9-9.4.50/jetty-xml/src/test/resources/org/eclipse/jetty/xml/mortbay.xml jetty9-9.4.57/jetty-xml/src/test/resources/org/eclipse/jetty/xml/mortbay.xml --- jetty9-9.4.50/jetty-xml/src/test/resources/org/eclipse/jetty/xml/mortbay.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/jetty-xml/src/test/resources/org/eclipse/jetty/xml/mortbay.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,2 +1,3 @@ - + + diff -Nru jetty9-9.4.50/pom.xml jetty9-9.4.57/pom.xml --- jetty9-9.4.50/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,11 +4,11 @@ 4.0.0 org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 Jetty :: Project The Eclipse Jetty Project pom - https://eclipse.org/jetty + https://jetty.org/ 1995 @@ -16,7 +16,7 @@ 8 8 false - https://eclipse.org/jetty + https://jetty.org/ benchmarks ${bundle-symbolic-name} UTF-8 @@ -25,31 +25,32 @@ 2.0.10 1.1.3.v20160715 - 1.10.12 - 1.11.1 - 9.4 - 6.3.1 + 1.10.15 + 1.11.4 + 2.2.3 + 9.7.1 + 6.4.1 1.5 9.3 - 1.15 - 1.22 - 2.11.0 - 3.12.0 + 1.17.1 + 1.27.1 + 2.18.0 + 3.17.0 2.5.2 3.4.4 3.0.2 - 2.14.0 - 1.47.0 - 2.9.0 - 31.1-jre - 5.1.0 - 2.15.0 + 2.36.0 + 1.68.2 + 2.11.0 + 33.3.1-jre + 7.0.0 + 3.0.2 3.12.12 - 4.4.3.Final - 11.0.16.Final - 2.13.3 - 2.13.3 - 2.13.3 + 4.4.4.Final + 11.0.19.Final + 2.18.2 + 2.18.2 + 2.18.2 2.82 1.1.0.v201105071233 1.3.2 @@ -58,98 +59,100 @@ 3.1.0 1.3 1.0 - 2.2.1.Final - 2.2.1.Final 3.4.3.Final + 3.5.1.Final 1.0.7 3.1.2 1.2 - 1.35 - 5.12.1 - 0.10.3 - 0.32.13 - 2.2.12 - 3.1.15 - 0.38.17 - 1.7.1 - 8.5.70 - 5.9.1 + 1.37 + 5.15.0 + 0.10.4 + 0.32.18 + 2.2.17 + 3.1.20 + 0.38.23 + 1.7.2 + 8.5.100 + 5.10.5 2.17.1 - 1.2.11 - 3.6.4 - 1.8.2 - 3.8.6 + 1.2.13 + 3.12.0 + 1.9.22 + 3.9.0 2.14.3 8.1.0 6.0.0 1.2.0 - 1.2.0 + 1.3.0 2.1.1 - 3.4.2 + 4.0.2 + 4.0.4 1.7.36 1.2.5 1.2.5 - 1.17.5 + 1.20.4 3.1.9.Final + + 2.2.7.Final 1.6.0.Final - 2.0.0.Final - 2.4.7 + 2.4.8 - 2.2.2 + 2.2.6 2.1.0 - 3.3.0 - 3.0.0 + 3.6.0 + 3.2.1 2.0.17 - 3.0.0 + 3.5.0 3.5.1 1.0.9 - 0.8.8 + 0.8.12 2.7 - 4.1 + 4.6 3.1.0 - 3.4.2 - 3.3.0 - 3.0.0-M7 - 3.1.0 - 3.2.0 - 3.10.1 - 3.3.0 + 3.7.1 + 3.8.1 + 3.5.2 + 3.6.0 + 3.4.0 + 3.13.0 + 3.8.1 2.10 - 3.1.0 - 3.3.0 + 3.5.0 + 3.4.1 3.3.1 - 3.3.1 - 3.6.4 - 2.5.3 - 3.0.0 - 3.2.0 - 3.4.1 - 3.12.1 - 3.2.1 - 3.3.2 - 3.0.1 - 3.0.0 - 1.4.0 - 2.11.0 + 3.6.0 + 3.15.1 + 3.1.1 + 3.2.0 + 3.3.1 + 3.6.0 + 3.21.0 + 3.3.1 + 3.4.0 + 3.1.3 + 3.1.3 + 1.5.0 + 2.18.0 - 4.2.0 + 4.2.2 false 5.9 false 1.0 ${project.build.directory}/local-repo - 3.0.6 + 3.5.1 /tmp 3.2.20 src/it/settings.xml 2.1.1.RELEASE 0 - 1.16.1 + 1.20.4 + @@ -164,9 +167,9 @@ - scm:git:https://github.com/eclipse/jetty.project.git + scm:git:https://github.com/jetty/jetty.project.git scm:git:git@github.com:eclipse/jetty.project.git - https://github.com/eclipse/jetty.project + https://github.com/jetty/jetty.project @@ -273,6 +276,27 @@ + + max-java8-bytecode + + enforce + + + + + 1.8 + + org.eclipse.jetty:jetty-alpn-java-client + org.eclipse.jetty:jetty-alpn-java-server + + + + + true + + @@ -280,6 +304,11 @@ jetty-build-support ${build-support.version} + + org.codehaus.mojo + extra-enforcer-rules + 1.9.0 + @@ -475,7 +504,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.1.2 + 3.6.0 jetty-checkstyle.xml true @@ -956,7 +985,7 @@ org.codehaus.plexus plexus-component-annotations - 2.1.1 + 2.2.0 org.codehaus.plexus @@ -964,6 +993,11 @@ ${plexus-utils.version} + org.codehaus.plexus + plexus-xml + ${plexus-xml.version} + + org.apache.maven maven-plugin-api ${maven.version} @@ -1039,22 +1073,22 @@ org.jboss.logging jboss-logging-processor - 2.2.1.Final + ${jboss.logging.version} org.jboss.logging jboss-logging-annotations - 2.2.1.Final + ${jboss.logging.version} org.jboss.logmanager jboss-logmanager - 2.1.19.Final + ${jboss.logging.version} org.jboss.threads jboss-threads - 3.5.0.Final + ${jboss.threads.version} @@ -1105,6 +1139,11 @@ ${commons.compress.version} + org.apache.mina + mina-core + ${mina.core.version} + + com.fasterxml.jackson.core jackson-core ${jackson.core.version} @@ -1120,16 +1159,16 @@ ${jackson.annotations.version} - org.wildfly.common - wildfly-common - ${wildfly.common.version} - - org.wildfly.security wildfly-elytron ${wildfly.elytron.version} + org.wildfly.common + wildfly-common + ${wildfly.common.version} + + org.slf4j slf4j-simple ${slf4j.version} @@ -1482,7 +1521,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.0.1 + 3.2.7 sign-artifacts @@ -1518,14 +1557,17 @@ com.github.spotbugs spotbugs-maven-plugin - 4.7.0.0 + 4.8.6.6 org.apache.maven.plugins maven-surefire-plugin ${maven.surefire.plugin.version} - external, large-disk-resource + external, large-disk-resource, stress, slow + + true + @@ -1610,7 +1652,7 @@ - 1.3.4 + 1.5.2 @@ -1706,7 +1748,7 @@ github - https://github.com/eclipse/jetty.project/issues + https://github.com/jetty/jetty.project/issues diff -Nru jetty9-9.4.50/scripts/release-jetty.sh jetty9-9.4.57/scripts/release-jetty.sh --- jetty9-9.4.50/scripts/release-jetty.sh 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/scripts/release-jetty.sh 2024-12-19 21:51:26.000000000 +0000 @@ -45,7 +45,7 @@ return 0 } -GIT_REMOTE_URL="github.com:eclipse/jetty.project.git" +GIT_REMOTE_URL="github.com:jetty/jetty.project.git" GIT_REMOTE_ID=$(gitFindRemoteByUrl "$GIT_REMOTE_URL") GIT_BRANCH_ID=$(git symbolic-ref -q --short HEAD || git describe --tags --exact-match) @@ -91,7 +91,8 @@ # DEPLOY_OPTS="$DEPLOY_OPTS -DaltDeploymentRepository=intarget::default::file://$ALT_DEPLOY_DIR/" # Uncomment for Java 1.7 -export MAVEN_OPTS="-Xmx1g -XX:MaxPermSize=128m" +# export MAVEN_OPTS="-Xmx1g -XX:MaxPermSize=128m" +export MAVEN_OPTS="-Xmx2g" echo "" echo "-----------------------------------------------" @@ -130,6 +131,7 @@ echo "" if proceedyn "Are you sure you want to release using above? (y/N)" n; then + mvn clean install -pl build-resources echo "" if proceedyn "Update VERSION.txt for $VER_RELEASE? (Y/n)" y; then # Uncomment alternate JVM for jetty 9.2 builds @@ -166,10 +168,7 @@ # This is equivalent to 'mvn release:perform' if proceedyn "Build/Deploy from tag $TAG_NAME? (Y/n)" y; then - git checkout $TAG_NAME - mvn clean package deploy -Peclipse-release $DEPLOY_OPTS - reportMavenTestFailures - git checkout $GIT_BRANCH_ID + mvn clean deploy -Peclipse-release $DEPLOY_OPTS fi if proceedyn "Update working directory for $VER_NEXT? (Y/n)" y; then echo "Update VERSION.txt for $VER_NEXT" diff -Nru jetty9-9.4.50/tests/pom.xml jetty9-9.4.57/tests/pom.xml --- jetty9-9.4.50/tests/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.50.v20221107 + 9.4.57.v20241219 ../pom.xml org.eclipse.jetty.tests diff -Nru jetty9-9.4.50/tests/test-continuation/pom.xml jetty9-9.4.57/tests/test-continuation/pom.xml --- jetty9-9.4.50/tests/test-continuation/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-continuation/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.50.v20221107 + 9.4.57.v20241219 ../pom.xml 4.0.0 diff -Nru jetty9-9.4.50/tests/test-distribution/pom.xml jetty9-9.4.57/tests/test-distribution/pom.xml --- jetty9-9.4.50/tests/test-distribution/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-distribution/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -2,7 +2,7 @@ tests-parent org.eclipse.jetty.tests - 9.4.50.v20221107 + 9.4.57.v20241219 4.0.0 @@ -20,6 +20,17 @@ slf4j-simple + org.codehaus.plexus + plexus-xml + test + + + javax.annotation + javax.annotation-api + + + + org.eclipse.jetty jetty-util ${project.version} @@ -169,6 +180,11 @@ test + commons-codec + commons-codec + test + + org.testcontainers testcontainers test diff -Nru jetty9-9.4.50/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java jetty9-9.4.57/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java --- jetty9-9.4.50/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -22,6 +22,7 @@ import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.junit.jupiter.api.AfterEach; public class AbstractDistributionTest @@ -44,6 +45,10 @@ protected void startHttpClient(Supplier supplier) throws Exception { client = supplier.get(); + client.setName("DistributionTest-Client"); + QueuedThreadPool executor = new QueuedThreadPool(); + executor.setName("dist-test-client"); + client.setExecutor(executor); client.start(); } diff -Nru jetty9-9.4.50/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java jetty9-9.4.57/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java --- jetty9-9.4.50/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java 2024-12-19 21:51:26.000000000 +0000 @@ -171,10 +171,11 @@ { assertTrue(run.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS)); - startHttpClient(); - ContentResponse response = client.GET("http://localhost:" + httpPort + "/proxy/current/"); + startHttpClient(true); + ContentResponse response = client.GET("http://localhost:" + httpPort + "/proxy/jetty-12/index.html"); assertEquals(HttpStatus.OK_200, response.getStatus()); - assertThat("Expecting APIdoc contents", response.getContentAsString(), containsString("Jetty Util : Common Resource Utilities")); + String body = response.getContentAsString(); + assertThat("Expecting APIdoc contents", body, containsString("Overview (Eclipse Jetty API Doc")); } } diff -Nru jetty9-9.4.50/tests/test-distribution/src/test/resources/badapp/badapp_throwonunavailable_false.xml jetty9-9.4.57/tests/test-distribution/src/test/resources/badapp/badapp_throwonunavailable_false.xml --- jetty9-9.4.50/tests/test-distribution/src/test/resources/badapp/badapp_throwonunavailable_false.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-distribution/src/test/resources/badapp/badapp_throwonunavailable_false.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Set name="contextPath">/badapp</Set> diff -Nru jetty9-9.4.50/tests/test-distribution/src/test/resources/badapp/badapp_throwonunavailable_true.xml jetty9-9.4.57/tests/test-distribution/src/test/resources/badapp/badapp_throwonunavailable_true.xml --- jetty9-9.4.50/tests/test-distribution/src/test/resources/badapp/badapp_throwonunavailable_true.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-distribution/src/test/resources/badapp/badapp_throwonunavailable_true.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Set name="contextPath">/badapp</Set> diff -Nru jetty9-9.4.50/tests/test-distribution/src/test/resources/test-realm.xml jetty9-9.4.57/tests/test-distribution/src/test/resources/test-realm.xml --- jetty9-9.4.50/tests/test-distribution/src/test/resources/test-realm.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-distribution/src/test/resources/test-realm.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ <?xml version="1.0"?> -<!DOCTYPE Configure PUBLIC "-" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<!DOCTYPE Configure PUBLIC "-" "https://jetty.org/configure_9_3.dtd"> <Configure id="Server" class="org.eclipse.jetty.server.Server"> <!-- =========================================================== --> <!-- Configure Authentication Login Service --> diff -Nru jetty9-9.4.50/tests/test-http-client-transport/pom.xml jetty9-9.4.57/tests/test-http-client-transport/pom.xml --- jetty9-9.4.50/tests/test-http-client-transport/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-http-client-transport/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>tests-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <modelVersion>4.0.0</modelVersion> diff -Nru jetty9-9.4.50/tests/test-integration/pom.xml jetty9-9.4.57/tests/test-integration/pom.xml --- jetty9-9.4.50/tests/test-integration/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-integration/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>tests-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>test-integration</artifactId> diff -Nru jetty9-9.4.50/tests/test-integration/src/test/java/org/eclipse/jetty/test/AllowedResourceAliasCheckerTest.java jetty9-9.4.57/tests/test-integration/src/test/java/org/eclipse/jetty/test/AllowedResourceAliasCheckerTest.java --- jetty9-9.4.50/tests/test-integration/src/test/java/org/eclipse/jetty/test/AllowedResourceAliasCheckerTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-integration/src/test/java/org/eclipse/jetty/test/AllowedResourceAliasCheckerTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -18,11 +18,11 @@ package org.eclipse.jetty.test; -import java.io.File; -import java.io.FileWriter; import java.io.IOException; +import java.io.OutputStream; import java.net.URI; -import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.FileSystemException; import java.nio.file.Files; import java.nio.file.Path; @@ -34,33 +34,26 @@ import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.util.IO; -import org.junit.jupiter.api.AfterAll; +import org.eclipse.jetty.toolchain.test.FS; +import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; +import org.eclipse.jetty.util.component.LifeCycle; +import org.eclipse.jetty.util.resource.PathResource; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; public class AllowedResourceAliasCheckerTest { - private static Server _server; - private static ServerConnector _connector; - private static HttpClient _client; - private static ServletContextHandler _context; - private static File _baseDir; - - private static Path getResourceDir() throws Exception - { - URL url = AllowedResourceAliasCheckerTest.class.getClassLoader().getResource("."); - assertNotNull(url); - return new File(url.toURI()).toPath(); - } + private Server _server; + private ServerConnector _connector; + private HttpClient _client; + private ServletContextHandler _context; + private Path _baseDir; public void start() throws Exception { @@ -68,8 +61,8 @@ _client.start(); } - @BeforeAll - public static void beforeAll() throws Exception + @BeforeEach + public void prepare(WorkDir workDir) { _client = new HttpClient(); _server = new Server(); @@ -81,46 +74,43 @@ _context.addServlet(DefaultServlet.class, "/"); _server.setHandler(_context); - _baseDir = getResourceDir().resolve("baseDir").toFile(); - _baseDir.deleteOnExit(); - assertFalse(_baseDir.exists()); - _context.setResourceBase(_baseDir.getAbsolutePath()); - } - - @AfterAll - public static void afterAll() throws Exception - { - _client.stop(); - _server.stop(); + _baseDir = workDir.getEmptyPathDir().resolve("baseDir"); + _context.setBaseResource(new PathResource(_baseDir)); } @AfterEach - public void afterEach() + public void dispose() { - IO.delete(_baseDir); + LifeCycle.stop(_client); + LifeCycle.stop(_server); } public void createBaseDir() throws IOException { - assertFalse(_baseDir.exists()); - assertTrue(_baseDir.mkdir()); + FS.ensureDirExists(_baseDir); // Create a file in the baseDir. - File file = _baseDir.toPath().resolve("file.txt").toFile(); - file.deleteOnExit(); - assertTrue(file.createNewFile()); - try (FileWriter fileWriter = new FileWriter(file)) + Path file = _baseDir.resolve("file.txt"); + try (OutputStream outputStream = Files.newOutputStream(file)) { - fileWriter.write("this is a file in the baseDir"); + outputStream.write("this is a file in the baseDir".getBytes(StandardCharsets.UTF_8)); } - // Create a symlink to that file. - // Symlink to a directory inside of the webroot. - File symlink = _baseDir.toPath().resolve("symlink").toFile(); - symlink.deleteOnExit(); - Files.createSymbolicLink(symlink.toPath(), file.toPath()); - assertTrue(symlink.exists()); + boolean symlinkSupported; + try + { + // Create a symlink to that file. + // Symlink to a directory inside the webroot. + Path symlink = _baseDir.resolve("symlink"); + Files.createSymbolicLink(symlink, file); + symlinkSupported = true; + } + catch (UnsupportedOperationException | FileSystemException e) + { + symlinkSupported = false; + } + assumeTrue(symlinkSupported, "Symlink not supported"); } @Test diff -Nru jetty9-9.4.50/tests/test-integration/src/test/java/org/eclipse/jetty/test/DeploymentErrorInitializer.java jetty9-9.4.57/tests/test-integration/src/test/java/org/eclipse/jetty/test/DeploymentErrorInitializer.java --- jetty9-9.4.50/tests/test-integration/src/test/java/org/eclipse/jetty/test/DeploymentErrorInitializer.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-integration/src/test/java/org/eclipse/jetty/test/DeploymentErrorInitializer.java 2024-12-19 21:51:26.000000000 +0000 @@ -26,7 +26,7 @@ /** * A SCI that tosses an Error to intentionally to cause issues with the DeploymentManager * - * @see <a href="https://github.com/eclipse/jetty.project/issues/1602">Issue #1602</a> + * @see <a href="https://github.com/jetty/jetty.project/issues/1602">Issue #1602</a> */ public class DeploymentErrorInitializer implements ServletContainerInitializer { diff -Nru jetty9-9.4.50/tests/test-integration/src/test/java/org/eclipse/jetty/test/HttpInputInterceptorTest.java jetty9-9.4.57/tests/test-integration/src/test/java/org/eclipse/jetty/test/HttpInputInterceptorTest.java --- jetty9-9.4.50/tests/test-integration/src/test/java/org/eclipse/jetty/test/HttpInputInterceptorTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-integration/src/test/java/org/eclipse/jetty/test/HttpInputInterceptorTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -40,6 +40,7 @@ import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.util.BytesContentProvider; +import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpTester; @@ -63,9 +64,10 @@ import org.junit.jupiter.params.provider.ValueSource; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.anyOf; +import static org.hamcrest.Matchers.sameInstance; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -110,10 +112,10 @@ // Throw immediately from the interceptor. jettyRequest.getHttpInput().addInterceptor(content -> { - throw new RuntimeException(); + throw new BadMessageException(); }); - assertThrows(IOException.class, () -> IO.readBytes(request.getInputStream())); + assertThrows(BadMessageException.class, () -> IO.readBytes(request.getInputStream())); serverLatch.countDown(); response.setStatus(HttpStatus.NO_CONTENT_204); } @@ -159,7 +161,7 @@ throw new RuntimeException(); }); - assertThrows(IOException.class, () -> IO.readBytes(request.getInputStream())); + assertThrows(RuntimeException.class, () -> IO.readBytes(request.getInputStream())); serverLatch.countDown(); response.setStatus(HttpStatus.NO_CONTENT_204); } @@ -362,7 +364,7 @@ // Now the interceptor should throw, but isReady() should not. if (input.isReady()) { - assertThrows(IOException.class, () -> assertEquals(bytes[0], input.read())); + assertThrows(RuntimeException.class, () -> assertEquals(bytes[0], input.read())); readFailureLatch.countDown(); response.setStatus(HttpStatus.NO_CONTENT_204); asyncContext.complete(); @@ -431,7 +433,7 @@ @Override public void onError(Throwable error) { - assertSame(failure, error.getCause()); + assertThat(failure, anyOf(sameInstance(error), sameInstance(error.getCause()))); response.setStatus(HttpStatus.NO_CONTENT_204); asyncContext.complete(); } diff -Nru jetty9-9.4.50/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithAliasesTest.java jetty9-9.4.57/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithAliasesTest.java --- jetty9-9.4.50/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithAliasesTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithAliasesTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -62,15 +62,15 @@ { List<Arguments> data = new ArrayList<>(); - data.add(Arguments.of("false", "/dump.jsp")); - data.add(Arguments.of("false", "/dump.jsp/")); - data.add(Arguments.of("true", "/dump.jsp%00")); - data.add(Arguments.of("false", "/dump.jsp%00/")); - data.add(Arguments.of("false", "/dump.jsp%00x/dump.jsp")); - data.add(Arguments.of("false", "/dump.jsp%00/dump.jsp")); - data.add(Arguments.of("false", "/dump.jsp%00x")); - data.add(Arguments.of("false", "/dump.jsp%00x/")); - data.add(Arguments.of("false", "/dump.jsp%00/index.html")); + data.add(Arguments.of("/dump.jsp", 200, false)); + data.add(Arguments.of("/dump.jsp/", 200, false)); + data.add(Arguments.of("/dump.jsp%00", 400, true)); + data.add(Arguments.of("/dump.jsp%00/", 400, false)); + data.add(Arguments.of("/dump.jsp%00x/dump.jsp", 400, false)); + data.add(Arguments.of("/dump.jsp%00/dump.jsp", 400, false)); + data.add(Arguments.of("/dump.jsp%00x", 400, false)); + data.add(Arguments.of("/dump.jsp%00x/", 400, false)); + data.add(Arguments.of("/dump.jsp%00/index.html", 400, false)); return data.stream(); } @@ -134,7 +134,7 @@ } } - private void assertResponse(HttpURLConnection conn, String path, boolean knownBypass) throws IOException + private void assertResponse(HttpURLConnection conn, String path, int expectedStatus, boolean knownBypass) throws IOException { if (conn.getResponseCode() == 200) { @@ -143,16 +143,12 @@ return; } - if (conn.getResponseCode() != 404) - System.err.println(conn.getResponseMessage()); - - // Of other possible paths, only 404 Not Found is expected - assertThat("Response Code", conn.getResponseCode(), is(404)); + assertThat("Response Code", conn.getResponseCode(), is(expectedStatus)); } @ParameterizedTest @MethodSource("aliases") - public void testGetReference(String path, boolean knownBypass) throws Exception + public void testGetReference(String path, int expectedStatus, boolean knownBypass) throws Exception { URI uri = serverURI.resolve(path); @@ -162,7 +158,7 @@ conn = (HttpURLConnection)uri.toURL().openConnection(); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); - assertResponse(conn, path, knownBypass); + assertResponse(conn, path, expectedStatus, knownBypass); } finally { diff -Nru jetty9-9.4.50/tests/test-integration/src/test/resources/DefaultHandler.xml jetty9-9.4.57/tests/test-integration/src/test/resources/DefaultHandler.xml --- jetty9-9.4.50/tests/test-integration/src/test/resources/DefaultHandler.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-integration/src/test/resources/DefaultHandler.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <!-- =============================================================== --> <!-- Configure the Jetty Server --> diff -Nru jetty9-9.4.50/tests/test-integration/src/test/resources/NIOHttp.xml jetty9-9.4.57/tests/test-integration/src/test/resources/NIOHttp.xml --- jetty9-9.4.50/tests/test-integration/src/test/resources/NIOHttp.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-integration/src/test/resources/NIOHttp.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure id="Server" class="org.eclipse.jetty.server.Server"> diff -Nru jetty9-9.4.50/tests/test-integration/src/test/resources/NIOHttps.xml jetty9-9.4.57/tests/test-integration/src/test/resources/NIOHttps.xml --- jetty9-9.4.50/tests/test-integration/src/test/resources/NIOHttps.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-integration/src/test/resources/NIOHttps.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure id="Server" class="org.eclipse.jetty.server.Server"> diff -Nru jetty9-9.4.50/tests/test-integration/src/test/resources/RFC2616Base.xml jetty9-9.4.57/tests/test-integration/src/test/resources/RFC2616Base.xml --- jetty9-9.4.50/tests/test-integration/src/test/resources/RFC2616Base.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-integration/src/test/resources/RFC2616Base.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <!-- =============================================================== --> <!-- Configure the Jetty Server --> @@ -47,7 +47,7 @@ </Array> </Set> <Set name="ResourceBase"><Property name="test.docroot.base"/>/virtualhost</Set> - <Set name="Handler"><New id="reshandler" class="org.eclipse.jetty.server.handler.ResourceHandler"/></Set> + <Set name="Handler"><New id="reshandlervirt" class="org.eclipse.jetty.server.handler.ResourceHandler"/></Set> <Set name="DisplayName">virtual</Set> </New> </Item> @@ -55,7 +55,7 @@ <New id="defcontext" class="org.eclipse.jetty.server.handler.ContextHandler"> <Set name="contextPath">/tests</Set> <Set name="ResourceBase"><Property name="test.docroot.base"/>/default</Set> - <Set name="Handler"><New id="reshandler" class="org.eclipse.jetty.server.handler.ResourceHandler"/></Set> + <Set name="Handler"><New id="reshandlerdefault" class="org.eclipse.jetty.server.handler.ResourceHandler"/></Set> <Set name="DisplayName">default</Set> </New> </Item> diff -Nru jetty9-9.4.50/tests/test-integration/src/test/resources/RFC2616_Filters.xml jetty9-9.4.57/tests/test-integration/src/test/resources/RFC2616_Filters.xml --- jetty9-9.4.50/tests/test-integration/src/test/resources/RFC2616_Filters.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-integration/src/test/resources/RFC2616_Filters.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure id="Server" class="org.eclipse.jetty.server.Server"> diff -Nru jetty9-9.4.50/tests/test-integration/src/test/resources/RFC2616_Redirects.xml jetty9-9.4.57/tests/test-integration/src/test/resources/RFC2616_Redirects.xml --- jetty9-9.4.50/tests/test-integration/src/test/resources/RFC2616_Redirects.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-integration/src/test/resources/RFC2616_Redirects.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure id="Server" class="org.eclipse.jetty.server.Server"> <!-- =========================================================== --> diff -Nru jetty9-9.4.50/tests/test-integration/src/test/resources/docroots/deployerror/badapp-unavailable-false.xml jetty9-9.4.57/tests/test-integration/src/test/resources/docroots/deployerror/badapp-unavailable-false.xml --- jetty9-9.4.50/tests/test-integration/src/test/resources/docroots/deployerror/badapp-unavailable-false.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-integration/src/test/resources/docroots/deployerror/badapp-unavailable-false.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Set name="contextPath">/badapp-uaf</Set> diff -Nru jetty9-9.4.50/tests/test-integration/src/test/resources/docroots/deployerror/badapp.xml jetty9-9.4.57/tests/test-integration/src/test/resources/docroots/deployerror/badapp.xml --- jetty9-9.4.50/tests/test-integration/src/test/resources/docroots/deployerror/badapp.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-integration/src/test/resources/docroots/deployerror/badapp.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Set name="contextPath">/badapp</Set> diff -Nru jetty9-9.4.50/tests/test-integration/src/test/resources/ssl.xml jetty9-9.4.57/tests/test-integration/src/test/resources/ssl.xml --- jetty9-9.4.50/tests/test-integration/src/test/resources/ssl.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-integration/src/test/resources/ssl.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,3 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory$Server"> <Set name="KeyStorePath"><Property name="jetty.home" default="." />/<Property name="jetty.sslContext.keyStorePath" default="keystore"/></Set> <Set name="KeyStorePassword"><Property name="jetty.sslContext.keyStorePassword" default="OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"/></Set> diff -Nru jetty9-9.4.50/tests/test-integration/src/test/resources/webapp-contexts/RFC2616/rfc2616-webapp.xml jetty9-9.4.57/tests/test-integration/src/test/resources/webapp-contexts/RFC2616/rfc2616-webapp.xml --- jetty9-9.4.50/tests/test-integration/src/test/resources/webapp-contexts/RFC2616/rfc2616-webapp.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-integration/src/test/resources/webapp-contexts/RFC2616/rfc2616-webapp.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Set name="contextPath">/rfc2616-webapp</Set> <Set name="war"><Property name="test.webapps" default="." />/test-webapp-rfc2616.war</Set> diff -Nru jetty9-9.4.50/tests/test-jmx/jmx-webapp/pom.xml jetty9-9.4.57/tests/test-jmx/jmx-webapp/pom.xml --- jetty9-9.4.50/tests/test-jmx/jmx-webapp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-jmx/jmx-webapp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-jmx-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <artifactId>jmx-webapp</artifactId> <packaging>war</packaging> diff -Nru jetty9-9.4.50/tests/test-jmx/jmx-webapp-it/pom.xml jetty9-9.4.57/tests/test-jmx/jmx-webapp-it/pom.xml --- jetty9-9.4.50/tests/test-jmx/jmx-webapp-it/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-jmx/jmx-webapp-it/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-jmx-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>jmx-webapp-it</artifactId> diff -Nru jetty9-9.4.50/tests/test-jmx/pom.xml jetty9-9.4.57/tests/test-jmx/pom.xml --- jetty9-9.4.50/tests/test-jmx/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-jmx/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>tests-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>test-jmx-parent</artifactId> diff -Nru jetty9-9.4.50/tests/test-loginservice/pom.xml jetty9-9.4.57/tests/test-loginservice/pom.xml --- jetty9-9.4.50/tests/test-loginservice/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-loginservice/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>tests-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <artifactId>test-loginservice</artifactId> <name>Jetty Tests :: Login Service</name> @@ -43,6 +43,11 @@ <version>${project.version}</version> </dependency> <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.testcontainers</groupId> <artifactId>testcontainers</artifactId> <scope>test</scope> diff -Nru jetty9-9.4.50/tests/test-quickstart/pom.xml jetty9-9.4.57/tests/test-quickstart/pom.xml --- jetty9-9.4.50/tests/test-quickstart/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-quickstart/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>tests-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> <relativePath>../pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> diff -Nru jetty9-9.4.50/tests/test-quickstart/src/test/resources/test-jndi.xml jetty9-9.4.57/tests/test-quickstart/src/test/resources/test-jndi.xml --- jetty9-9.4.50/tests/test-quickstart/src/test/resources/test-jndi.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-quickstart/src/test/resources/test-jndi.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <!-- =============================================================== --> <!-- Configure the test-jndi webapp --> diff -Nru jetty9-9.4.50/tests/test-quickstart/src/test/resources/test-spec.xml jetty9-9.4.57/tests/test-quickstart/src/test/resources/test-spec.xml --- jetty9-9.4.50/tests/test-quickstart/src/test/resources/test-spec.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-quickstart/src/test/resources/test-spec.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ <?xml version="1.0"?> -<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"> diff -Nru jetty9-9.4.50/tests/test-quickstart/src/test/resources/test.xml jetty9-9.4.57/tests/test-quickstart/src/test/resources/test.xml --- jetty9-9.4.50/tests/test-quickstart/src/test/resources/test.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-quickstart/src/test/resources/test.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <!-- ================================================================== Configure and deploy the test web application in $(jetty.home)/webapps/test diff -Nru jetty9-9.4.50/tests/test-sessions/pom.xml jetty9-9.4.57/tests/test-sessions/pom.xml --- jetty9-9.4.50/tests/test-sessions/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-sessions/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>tests-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <artifactId>test-sessions-parent</artifactId> <name>Jetty Tests :: Sessions :: Parent</name> diff -Nru jetty9-9.4.50/tests/test-sessions/test-file-sessions/pom.xml jetty9-9.4.57/tests/test-sessions/test-file-sessions/pom.xml --- jetty9-9.4.50/tests/test-sessions/test-file-sessions/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-sessions/test-file-sessions/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-sessions-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <artifactId>test-file-sessions</artifactId> <name>Jetty Tests :: Sessions :: File</name> diff -Nru jetty9-9.4.50/tests/test-sessions/test-gcloud-sessions/pom.xml jetty9-9.4.57/tests/test-sessions/test-gcloud-sessions/pom.xml --- jetty9-9.4.50/tests/test-sessions/test-gcloud-sessions/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-sessions/test-gcloud-sessions/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-sessions-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <artifactId>test-gcloud-sessions</artifactId> <name>Jetty Tests :: Sessions :: GCloud</name> @@ -43,6 +43,11 @@ <scope>test</scope> </dependency> <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.testcontainers</groupId> <artifactId>testcontainers</artifactId> <scope>test</scope> diff -Nru jetty9-9.4.50/tests/test-sessions/test-hazelcast-sessions/pom.xml jetty9-9.4.57/tests/test-sessions/test-hazelcast-sessions/pom.xml --- jetty9-9.4.50/tests/test-sessions/test-hazelcast-sessions/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-sessions/test-hazelcast-sessions/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-sessions-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <artifactId>test-hazelcast-sessions</artifactId> <name>Jetty Tests :: Sessions :: Hazelcast</name> diff -Nru jetty9-9.4.50/tests/test-sessions/test-infinispan-sessions/pom.xml jetty9-9.4.57/tests/test-sessions/test-infinispan-sessions/pom.xml --- jetty9-9.4.50/tests/test-sessions/test-infinispan-sessions/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-sessions/test-infinispan-sessions/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-sessions-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <artifactId>test-infinispan-sessions</artifactId> <name>Jetty Tests :: Sessions :: Infinispan</name> @@ -157,6 +157,11 @@ <scope>test</scope> </dependency> <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.testcontainers</groupId> <artifactId>testcontainers</artifactId> <scope>test</scope> diff -Nru jetty9-9.4.50/tests/test-sessions/test-jdbc-sessions/pom.xml jetty9-9.4.57/tests/test-sessions/test-jdbc-sessions/pom.xml --- jetty9-9.4.50/tests/test-sessions/test-jdbc-sessions/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-sessions/test-jdbc-sessions/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-sessions-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <artifactId>test-jdbc-sessions</artifactId> <name>Jetty Tests :: Sessions :: JDBC</name> @@ -52,6 +52,11 @@ <scope>test</scope> </dependency> <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.testcontainers</groupId> <artifactId>testcontainers</artifactId> <scope>test</scope> diff -Nru jetty9-9.4.50/tests/test-sessions/test-memcached-sessions/pom.xml jetty9-9.4.57/tests/test-sessions/test-memcached-sessions/pom.xml --- jetty9-9.4.50/tests/test-sessions/test-memcached-sessions/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-sessions/test-memcached-sessions/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-sessions-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <artifactId>test-memcached-sessions</artifactId> <name>Jetty Tests :: Sessions :: Memcached</name> @@ -49,6 +49,11 @@ <scope>test</scope> </dependency> <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.testcontainers</groupId> <artifactId>testcontainers</artifactId> <scope>test</scope> diff -Nru jetty9-9.4.50/tests/test-sessions/test-mongodb-sessions/pom.xml jetty9-9.4.57/tests/test-sessions/test-mongodb-sessions/pom.xml --- jetty9-9.4.50/tests/test-sessions/test-mongodb-sessions/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-sessions/test-mongodb-sessions/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-sessions-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <artifactId>test-mongodb-sessions</artifactId> <name>Jetty Tests :: Sessions :: Mongo</name> @@ -89,6 +89,11 @@ <scope>test</scope> </dependency> <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.testcontainers</groupId> <artifactId>testcontainers</artifactId> <scope>test</scope> diff -Nru jetty9-9.4.50/tests/test-sessions/test-sessions-common/pom.xml jetty9-9.4.57/tests/test-sessions/test-sessions-common/pom.xml --- jetty9-9.4.50/tests/test-sessions/test-sessions-common/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-sessions/test-sessions-common/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-sessions-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <artifactId>test-sessions-common</artifactId> <name>Jetty Tests :: Sessions :: Common</name> diff -Nru jetty9-9.4.50/tests/test-webapps/pom.xml jetty9-9.4.57/tests/test-webapps/pom.xml --- jetty9-9.4.50/tests/test-webapps/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>tests-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> <relativePath>../pom.xml</relativePath> </parent> <artifactId>test-webapps-parent</artifactId> diff -Nru jetty9-9.4.50/tests/test-webapps/test-cdi-common-webapp/pom.xml jetty9-9.4.57/tests/test-webapps/test-cdi-common-webapp/pom.xml --- jetty9-9.4.50/tests/test-webapps/test-cdi-common-webapp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-cdi-common-webapp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-webapps-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <modelVersion>4.0.0</modelVersion> diff -Nru jetty9-9.4.50/tests/test-webapps/test-felix-webapp/pom.xml jetty9-9.4.57/tests/test-webapps/test-felix-webapp/pom.xml --- jetty9-9.4.50/tests/test-webapps/test-felix-webapp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-felix-webapp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-webapps-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <modelVersion>4.0.0</modelVersion> diff -Nru jetty9-9.4.50/tests/test-webapps/test-http2-webapp/pom.xml jetty9-9.4.57/tests/test-webapps/test-http2-webapp/pom.xml --- jetty9-9.4.50/tests/test-webapps/test-http2-webapp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-http2-webapp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-webapps-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <modelVersion>4.0.0</modelVersion> diff -Nru jetty9-9.4.50/tests/test-webapps/test-jaas-webapp/pom.xml jetty9-9.4.57/tests/test-webapps/test-jaas-webapp/pom.xml --- jetty9-9.4.50/tests/test-webapps/test-jaas-webapp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-jaas-webapp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-webapps-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <artifactId>test-jaas-webapp</artifactId> <name>Jetty Tests :: WebApp :: JAAS</name> diff -Nru jetty9-9.4.50/tests/test-webapps/test-jaas-webapp/src/main/config/demo-base/webapps/test-jaas.xml jetty9-9.4.57/tests/test-webapps/test-jaas-webapp/src/main/config/demo-base/webapps/test-jaas.xml --- jetty9-9.4.50/tests/test-webapps/test-jaas-webapp/src/main/config/demo-base/webapps/test-jaas.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-jaas-webapp/src/main/config/demo-base/webapps/test-jaas.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <!-- =============================================================== --> <!-- Configure the test-jaas webapp --> diff -Nru jetty9-9.4.50/tests/test-webapps/test-jaas-webapp/src/main/webapp/WEB-INF/jetty-web.xml jetty9-9.4.57/tests/test-webapps/test-jaas-webapp/src/main/webapp/WEB-INF/jetty-web.xml --- jetty9-9.4.50/tests/test-webapps/test-jaas-webapp/src/main/webapp/WEB-INF/jetty-web.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-jaas-webapp/src/main/webapp/WEB-INF/jetty-web.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Get class="org.eclipse.jetty.util.log.Log" name="rootLogger"> diff -Nru jetty9-9.4.50/tests/test-webapps/test-jaas-webapp/src/main/webapp/index.html jetty9-9.4.57/tests/test-webapps/test-jaas-webapp/src/main/webapp/index.html --- jetty9-9.4.50/tests/test-webapps/test-jaas-webapp/src/main/webapp/index.html 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-jaas-webapp/src/main/webapp/index.html 2024-12-19 21:51:26.000000000 +0000 @@ -24,7 +24,7 @@ $JETTY_BASE/start.ini file. The Jetty demo-base already has JAAS enabled in its start.ini file. </p> <p>The full source of this demonstration is available <a -href="https://github.com/eclipse/jetty.project/tree/jetty-9.4.x/tests/test-webapps/test-jaas-webapp">here</a>.</p> +href="https://github.com/jetty/jetty.project/tree/jetty-9.4.x/tests/test-webapps/test-jaas-webapp">here</a>.</p> <h2>Using the Demo</h2> <P> @@ -34,11 +34,11 @@ <p> This demo uses a simple login module that stores its configuration in a properties file. There are other types of login module provided with the jetty distro. For full information, please refer to the - <a href="https://www.eclipse.org/jetty/documentation/current/">Jetty 9 documentation</a>. + <a href="https://jetty.org/docs/9/">Jetty 9 documentation</a>. </p> <hr/> - <center><a href="https://www.eclipse.org/jetty/"><img style="border:0" src="images/small_powered_by.gif"/></a></center> + <center><a href="https://jetty.org/"><img style="border:0" src="images/small_powered_by.gif"/></a></center> </BODY> </HTML> diff -Nru jetty9-9.4.50/tests/test-webapps/test-jetty-webapp/pom.xml jetty9-9.4.57/tests/test-webapps/test-jetty-webapp/pom.xml --- jetty9-9.4.50/tests/test-webapps/test-jetty-webapp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-jetty-webapp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-webapps-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> <relativePath>../pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> @@ -201,7 +201,6 @@ <dependency> <groupId>javax.websocket</groupId> <artifactId>javax.websocket-api</artifactId> - <version>1.0</version> <scope>provided</scope> </dependency> </dependencies> diff -Nru jetty9-9.4.50/tests/test-webapps/test-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml jetty9-9.4.57/tests/test-webapps/test-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml --- jetty9-9.4.50/tests/test-webapps/test-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <!-- ================================================================== Configure and deploy the test web application in $(jetty.home)/webapps/test diff -Nru jetty9-9.4.50/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/etc/demo-rewrite-rules.xml jetty9-9.4.57/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/etc/demo-rewrite-rules.xml --- jetty9-9.4.50/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/etc/demo-rewrite-rules.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/etc/demo-rewrite-rules.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <!-- =============================================================== --> <!-- Configure the demos --> diff -Nru jetty9-9.4.50/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/etc/test-realm.xml jetty9-9.4.57/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/etc/test-realm.xml --- jetty9-9.4.50/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/etc/test-realm.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/etc/test-realm.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure id="Server" class="org.eclipse.jetty.server.Server"> <!-- =========================================================== --> <!-- Configure Authentication Login Service --> diff -Nru jetty9-9.4.50/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/webapps/test.xml jetty9-9.4.57/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/webapps/test.xml --- jetty9-9.4.50/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/webapps/test.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/webapps/test.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <!-- ================================================================== Configure and deploy the test web application in $(jetty.home)/webapps/test diff -Nru jetty9-9.4.50/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/jetty-web.xml jetty9-9.4.57/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/jetty-web.xml --- jetty9-9.4.50/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/jetty-web.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/jetty-web.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <!-- This is the jetty specific web application configuration file. When starting diff -Nru jetty9-9.4.50/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml jetty9-9.4.57/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml --- jetty9-9.4.50/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml 2024-12-19 21:51:26.000000000 +0000 @@ -122,18 +122,6 @@ </servlet-mapping> <servlet> - <servlet-name>CGI</servlet-name> - <servlet-class>org.eclipse.jetty.servlets.CGI</servlet-class> - <load-on-startup>1</load-on-startup> - <async-supported>true</async-supported> - </servlet> - - <servlet-mapping> - <servlet-name>CGI</servlet-name> - <url-pattern>/cgi-bin/*</url-pattern> - </servlet-mapping> - - <servlet> <servlet-name>Chat</servlet-name> <servlet-class>com.acme.ChatServlet</servlet-class> <load-on-startup>1</load-on-startup> diff -Nru jetty9-9.4.50/tests/test-webapps/test-jetty-webapp/src/main/webapp/index.html jetty9-9.4.57/tests/test-webapps/test-jetty-webapp/src/main/webapp/index.html --- jetty9-9.4.50/tests/test-webapps/test-jetty-webapp/src/main/webapp/index.html 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-jetty-webapp/src/main/webapp/index.html 2024-12-19 21:51:26.000000000 +0000 @@ -58,10 +58,10 @@ <h2>Useful links:</h2> <ul> <li><a - href="https://github.com/eclipse/jetty.project/tree/jetty-9.4.x/tests/test-webapps/test-jetty-webapp">Source + href="https://github.com/jetty/jetty.project/tree/jetty-9.4.x/tests/test-webapps/test-jetty-webapp">Source tree of this webapp</a></li> - <li><a href="https://www.eclipse.org/jetty/">Jetty project home</a></li> - <li><a href="https://www.eclipse.org/jetty/documentation/current/">Documentation</a></li> + <li><a href="https://jetty.org/">Jetty project home</a></li> + <li><a href="https://jetty.org/docs/">Documentation</a></li> <li><a href="https://webtide.com">Commercial Support</a></li> </ul> </p> diff -Nru jetty9-9.4.50/tests/test-webapps/test-jetty-webapp/src/main/webapp/remote.html jetty9-9.4.57/tests/test-webapps/test-jetty-webapp/src/main/webapp/remote.html --- jetty9-9.4.50/tests/test-webapps/test-jetty-webapp/src/main/webapp/remote.html 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-jetty-webapp/src/main/webapp/remote.html 2024-12-19 21:51:26.000000000 +0000 @@ -5,13 +5,13 @@ <META http-equiv="Cache-Control" content="no-cache,no-store"> </HEAD> <BODY> -<A HREF="https://www.eclipse.org/jetty/"><IMG SRC="jetty_banner.gif"></A> +<A HREF="https://jetty.org/"><IMG SRC="jetty_banner.gif"></A> <h1>Welcome to Jetty 9 - REMOTE ACCESS!!</h1> <p> This is the Test webapp for the Jetty 9 HTTP Server and Servlet Container. For more information about Jetty, please visit our - <a href="https://www.eclipse.org/jetty/">website</a> - or <a href="https://www.eclipse.org/jetty/documentation/current/">documentation</a>. + <a href="https://jetty.org/">website</a> + or <a href="https://jetty.org/docs/">documentation</a>. Commercial support for Jetty is available via <a href="http://www.webtide.com">webtide</a>. </p> <p> diff -Nru jetty9-9.4.50/tests/test-webapps/test-jndi-webapp/pom.xml jetty9-9.4.57/tests/test-webapps/test-jndi-webapp/pom.xml --- jetty9-9.4.50/tests/test-webapps/test-jndi-webapp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-jndi-webapp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-webapps-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <artifactId>test-jndi-webapp</artifactId> <name>Jetty Tests :: WebApp :: JNDI</name> diff -Nru jetty9-9.4.50/tests/test-webapps/test-jndi-webapp/src/main/templates/jetty-test-jndi-header.xml jetty9-9.4.57/tests/test-webapps/test-jndi-webapp/src/main/templates/jetty-test-jndi-header.xml --- jetty9-9.4.50/tests/test-webapps/test-jndi-webapp/src/main/templates/jetty-test-jndi-header.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-jndi-webapp/src/main/templates/jetty-test-jndi-header.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <!-- =============================================================== --> <!-- Configure the test-jndi webapp --> diff -Nru jetty9-9.4.50/tests/test-webapps/test-jndi-webapp/src/main/templates/plugin-context-header.xml jetty9-9.4.57/tests/test-webapps/test-jndi-webapp/src/main/templates/plugin-context-header.xml --- jetty9-9.4.50/tests/test-webapps/test-jndi-webapp/src/main/templates/plugin-context-header.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-jndi-webapp/src/main/templates/plugin-context-header.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <!-- =============================================================== --> <!-- Configure the test-jndi webapp --> diff -Nru jetty9-9.4.50/tests/test-webapps/test-jndi-webapp/src/main/webapp/WEB-INF/jetty-env.xml jetty9-9.4.57/tests/test-webapps/test-jndi-webapp/src/main/webapp/WEB-INF/jetty-env.xml --- jetty9-9.4.50/tests/test-webapps/test-jndi-webapp/src/main/webapp/WEB-INF/jetty-env.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-jndi-webapp/src/main/webapp/WEB-INF/jetty-env.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"> diff -Nru jetty9-9.4.50/tests/test-webapps/test-jndi-webapp/src/main/webapp/WEB-INF/jetty-web.xml jetty9-9.4.57/tests/test-webapps/test-jndi-webapp/src/main/webapp/WEB-INF/jetty-web.xml --- jetty9-9.4.50/tests/test-webapps/test-jndi-webapp/src/main/webapp/WEB-INF/jetty-web.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-jndi-webapp/src/main/webapp/WEB-INF/jetty-web.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Get class="org.eclipse.jetty.util.log.Log" name="rootLogger"> diff -Nru jetty9-9.4.50/tests/test-webapps/test-jndi-webapp/src/main/webapp/index.html jetty9-9.4.57/tests/test-webapps/test-jndi-webapp/src/main/webapp/index.html --- jetty9-9.4.50/tests/test-webapps/test-jndi-webapp/src/main/webapp/index.html 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-jndi-webapp/src/main/webapp/index.html 2024-12-19 21:51:26.000000000 +0000 @@ -27,7 +27,7 @@ </p> <p>This will create a $JETTY_BASE/start.d/jndi.ini file to enable and parameterise JNDI. If the --add-to-start option instead, then the same initialisation will be appended to the $JETTY_BASE/start.ini file instead. The jetty demo-base already has JNDI enabled in the start.ini file and some mock resources included. </p> -<p>The full source of this demonstration is available <a href="https://github.com/eclipse/jetty.project/tree/jetty-9.4.x/tests/test-webapps/test-jndi-webapp">here</a>.</p> +<p>The full source of this demonstration is available <a href="https://github.com/jetty/jetty.project/tree/jetty-9.4.x/tests/test-webapps/test-jndi-webapp">here</a>.</p> <h2>Execution</h2> @@ -40,7 +40,7 @@ <hr/> - <center><a href="https://www.eclipse.org/jetty/"><img style="border:0" src="images/small_powered_by.gif"/></a></center> + <center><a href="https://jetty.org/"><img style="border:0" src="images/small_powered_by.gif"/></a></center> </BODY> </HTML> diff -Nru jetty9-9.4.50/tests/test-webapps/test-mock-resources/pom.xml jetty9-9.4.57/tests/test-webapps/test-mock-resources/pom.xml --- jetty9-9.4.50/tests/test-webapps/test-mock-resources/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-mock-resources/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-webapps-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <name>Jetty Tests :: WebApp :: Mock Resources</name> <artifactId>test-mock-resources</artifactId> diff -Nru jetty9-9.4.50/tests/test-webapps/test-owb-cdi-webapp/pom.xml jetty9-9.4.57/tests/test-webapps/test-owb-cdi-webapp/pom.xml --- jetty9-9.4.50/tests/test-webapps/test-owb-cdi-webapp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-owb-cdi-webapp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-webapps-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <modelVersion>4.0.0</modelVersion> diff -Nru jetty9-9.4.50/tests/test-webapps/test-owb-cdi-webapp/src/main/webapp/WEB-INF/jetty-env.xml jetty9-9.4.57/tests/test-webapps/test-owb-cdi-webapp/src/main/webapp/WEB-INF/jetty-env.xml --- jetty9-9.4.50/tests/test-webapps/test-owb-cdi-webapp/src/main/webapp/WEB-INF/jetty-env.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-owb-cdi-webapp/src/main/webapp/WEB-INF/jetty-env.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure id="webAppCtx" class="org.eclipse.jetty.webapp.WebAppContext"> <New id="BeanManager" class="org.eclipse.jetty.plus.jndi.Resource"> diff -Nru jetty9-9.4.50/tests/test-webapps/test-owb-cdi-webapp/src/main/webapp/WEB-INF/jetty-web-owb.xml jetty9-9.4.57/tests/test-webapps/test-owb-cdi-webapp/src/main/webapp/WEB-INF/jetty-web-owb.xml --- jetty9-9.4.50/tests/test-webapps/test-owb-cdi-webapp/src/main/webapp/WEB-INF/jetty-web-owb.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-owb-cdi-webapp/src/main/webapp/WEB-INF/jetty-web-owb.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,6 @@ -<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> + <Configure id="wac" class="org.eclipse.jetty.webapp.WebAppContext"> <!-- Rename this file to jetty-web.xml if the cdi-spi module is not used--> <Get id="wal" name="classLoader"/> diff -Nru jetty9-9.4.50/tests/test-webapps/test-proxy-webapp/pom.xml jetty9-9.4.57/tests/test-webapps/test-proxy-webapp/pom.xml --- jetty9-9.4.50/tests/test-webapps/test-proxy-webapp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-proxy-webapp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-webapps-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> <relativePath>../pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> diff -Nru jetty9-9.4.50/tests/test-webapps/test-proxy-webapp/src/main/webapp/WEB-INF/jetty-web.xml jetty9-9.4.57/tests/test-webapps/test-proxy-webapp/src/main/webapp/WEB-INF/jetty-web.xml --- jetty9-9.4.50/tests/test-webapps/test-proxy-webapp/src/main/webapp/WEB-INF/jetty-web.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-proxy-webapp/src/main/webapp/WEB-INF/jetty-web.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Set name="contextPath">/proxy</Set> diff -Nru jetty9-9.4.50/tests/test-webapps/test-proxy-webapp/src/main/webapp/WEB-INF/web.xml jetty9-9.4.57/tests/test-webapps/test-proxy-webapp/src/main/webapp/WEB-INF/web.xml --- jetty9-9.4.50/tests/test-webapps/test-proxy-webapp/src/main/webapp/WEB-INF/web.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-proxy-webapp/src/main/webapp/WEB-INF/web.xml 2024-12-19 21:51:26.000000000 +0000 @@ -8,11 +8,11 @@ <servlet-class>org.eclipse.jetty.proxy.ProxyServlet$Transparent</servlet-class> <init-param> <param-name>proxyTo</param-name> - <param-value>https://www.eclipse.org/jetty/javadoc/jetty-11/index.html?overview-summary.html</param-value> + <param-value>https://javadoc.jetty.org/</param-value> </init-param> <init-param> <param-name>hostHeader</param-name> - <param-value>www.eclipse.org</param-value> + <param-value>javadoc.jetty.org</param-value> </init-param> <load-on-startup>1</load-on-startup> <async-supported>true</async-supported> @@ -20,7 +20,7 @@ <servlet-mapping> <servlet-name>JavadocTransparentProxy</servlet-name> - <url-pattern>/current/*</url-pattern> + <url-pattern>/*</url-pattern> </servlet-mapping> </web-app> diff -Nru jetty9-9.4.50/tests/test-webapps/test-proxy-webapp/src/test/java/org/eclipse/jetty/ProxyWebAppTest.java jetty9-9.4.57/tests/test-webapps/test-proxy-webapp/src/test/java/org/eclipse/jetty/ProxyWebAppTest.java --- jetty9-9.4.50/tests/test-webapps/test-proxy-webapp/src/test/java/org/eclipse/jetty/ProxyWebAppTest.java 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-proxy-webapp/src/test/java/org/eclipse/jetty/ProxyWebAppTest.java 2024-12-19 21:51:26.000000000 +0000 @@ -81,7 +81,7 @@ @Tag("external") public void testProxyRequest() throws InterruptedException, ExecutionException, TimeoutException { - ContentResponse response = client.newRequest(server.getURI().resolve("/proxy/current/")) + ContentResponse response = client.newRequest(server.getURI().resolve("/proxy/jetty-12/index.html")) .followRedirects(false) .send(); @@ -91,6 +91,7 @@ // this proxy configuration, not redirected to the actual website. assertThat("response status", response.getStatus(), is(HttpStatus.OK_200)); // Expecting a Javadoc / APIDoc response - look for something unique for APIdoc. - assertThat("response", response.getContentAsString(), containsString("All Classes")); + String body = response.getContentAsString(); + assertThat(body, containsString("<title>Overview (Eclipse Jetty API Doc")); } } diff -Nru jetty9-9.4.50/tests/test-webapps/test-servlet-spec/pom.xml jetty9-9.4.57/tests/test-webapps/test-servlet-spec/pom.xml --- jetty9-9.4.50/tests/test-webapps/test-servlet-spec/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-servlet-spec/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-webapps-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <artifactId>test-servlet-spec-parent</artifactId> <name>Jetty Tests :: Spec Test WebApp :: Parent</name> diff -Nru jetty9-9.4.50/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml jetty9-9.4.57/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml --- jetty9-9.4.50/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-servlet-spec-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <artifactId>test-container-initializer</artifactId> <packaging>jar</packaging> diff -Nru jetty9-9.4.50/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml jetty9-9.4.57/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml --- jetty9-9.4.50/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-servlet-spec-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <name>Jetty Tests :: Webapps :: Spec Webapp</name> <artifactId>test-spec-webapp</artifactId> diff -Nru jetty9-9.4.50/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/templates/annotations-context-header.xml jetty9-9.4.57/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/templates/annotations-context-header.xml --- jetty9-9.4.50/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/templates/annotations-context-header.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/templates/annotations-context-header.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ <?xml version="1.0"?> -<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <!-- =============================================================== --> diff -Nru jetty9-9.4.50/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/templates/plugin-context-header.xml jetty9-9.4.57/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/templates/plugin-context-header.xml --- jetty9-9.4.50/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/templates/plugin-context-header.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/templates/plugin-context-header.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,5 +1,5 @@ <?xml version="1.0"?> -<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <!-- =============================================================== --> diff -Nru jetty9-9.4.50/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/WEB-INF/jetty-env.xml jetty9-9.4.57/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/WEB-INF/jetty-env.xml --- jetty9-9.4.50/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/WEB-INF/jetty-env.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/WEB-INF/jetty-env.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"> diff -Nru jetty9-9.4.50/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/WEB-INF/jetty-web.xml jetty9-9.4.57/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/WEB-INF/jetty-web.xml --- jetty9-9.4.50/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/WEB-INF/jetty-web.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/WEB-INF/jetty-web.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Get class="org.eclipse.jetty.util.log.Log" name="rootLogger"> diff -Nru jetty9-9.4.50/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/index.html jetty9-9.4.57/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/index.html --- jetty9-9.4.50/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/index.html 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/index.html 2024-12-19 21:51:26.000000000 +0000 @@ -6,7 +6,7 @@ <link rel="stylesheet" type="text/css" href="stylesheet.css"/> </HEAD> <BODY > - <A HREF="https://www.eclipse.org/jetty/"><IMG SRC="images/jetty_banner.gif"></A> + <A HREF="https://jetty.org/"><IMG SRC="images/jetty_banner.gif"></A> <br/> <b><a href="http://localhost:8080/">Demo Home</a></b> <hr/> @@ -21,7 +21,7 @@ <li>servlet container initializers. <li>multi-part upload support. </ul> -The source repository for this test is available <a href="https://github.com/eclipse/jetty.project/tree/jetty-9.4.x/tests/test-webapps/test-servlet-spec/test-spec-webapp">here</a>. +The source repository for this test is available <a href="https://github.com/jetty/jetty.project/tree/jetty-9.4.x/tests/test-webapps/test-servlet-spec/test-spec-webapp">here</a>. </p> <h3>Test Servlet 2.5/3.0 Annotations, Fragments and Initializers</h3> @@ -71,7 +71,7 @@ <div style="text-align: center;"> <hr/> - <a href="https://www.eclipse.org/jetty/"><img style="border:0" src="images/small_powered_by.gif"/></a> + <a href="https://jetty.org/"><img style="border:0" src="images/small_powered_by.gif"/></a> </div> </BODY> diff -Nru jetty9-9.4.50/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/test/jetty-plugin-env.xml jetty9-9.4.57/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/test/jetty-plugin-env.xml --- jetty9-9.4.50/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/test/jetty-plugin-env.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/test/jetty-plugin-env.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"> diff -Nru jetty9-9.4.50/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml jetty9-9.4.57/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml --- jetty9-9.4.50/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-servlet-spec-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <name>Jetty Tests :: WebApp :: Servlet Spec :: Fragment Jar</name> diff -Nru jetty9-9.4.50/tests/test-webapps/test-simple-session-webapp/pom.xml jetty9-9.4.57/tests/test-webapps/test-simple-session-webapp/pom.xml --- jetty9-9.4.50/tests/test-webapps/test-simple-session-webapp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-simple-session-webapp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-webapps-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <artifactId>test-simple-session-webapp</artifactId> diff -Nru jetty9-9.4.50/tests/test-webapps/test-simple-webapp/pom.xml jetty9-9.4.57/tests/test-webapps/test-simple-webapp/pom.xml --- jetty9-9.4.50/tests/test-webapps/test-simple-webapp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-simple-webapp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-webapps-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <artifactId>test-simple-webapp</artifactId> diff -Nru jetty9-9.4.50/tests/test-webapps/test-webapp-rfc2616/pom.xml jetty9-9.4.57/tests/test-webapps/test-webapp-rfc2616/pom.xml --- jetty9-9.4.50/tests/test-webapps/test-webapp-rfc2616/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-webapp-rfc2616/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -4,7 +4,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-webapps-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <artifactId>test-webapp-rfc2616</artifactId> <name>Jetty Tests :: WebApp :: RFC2616</name> diff -Nru jetty9-9.4.50/tests/test-webapps/test-websocket-client-provided-webapp/pom.xml jetty9-9.4.57/tests/test-webapps/test-websocket-client-provided-webapp/pom.xml --- jetty9-9.4.50/tests/test-webapps/test-websocket-client-provided-webapp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-websocket-client-provided-webapp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-webapps-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <modelVersion>4.0.0</modelVersion> diff -Nru jetty9-9.4.50/tests/test-webapps/test-websocket-client-provided-webapp/src/main/resources/jetty-websocket-httpclient.xml jetty9-9.4.57/tests/test-webapps/test-websocket-client-provided-webapp/src/main/resources/jetty-websocket-httpclient.xml --- jetty9-9.4.50/tests/test-webapps/test-websocket-client-provided-webapp/src/main/resources/jetty-websocket-httpclient.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-websocket-client-provided-webapp/src/main/resources/jetty-websocket-httpclient.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure class="org.eclipse.jetty.client.HttpClient"> <Arg> diff -Nru jetty9-9.4.50/tests/test-webapps/test-websocket-client-webapp/pom.xml jetty9-9.4.57/tests/test-webapps/test-websocket-client-webapp/pom.xml --- jetty9-9.4.50/tests/test-webapps/test-websocket-client-webapp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-websocket-client-webapp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-webapps-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <modelVersion>4.0.0</modelVersion> diff -Nru jetty9-9.4.50/tests/test-webapps/test-weld-cdi-webapp/pom.xml jetty9-9.4.57/tests/test-webapps/test-weld-cdi-webapp/pom.xml --- jetty9-9.4.50/tests/test-webapps/test-weld-cdi-webapp/pom.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-weld-cdi-webapp/pom.xml 2024-12-19 21:51:26.000000000 +0000 @@ -3,7 +3,7 @@ <parent> <groupId>org.eclipse.jetty.tests</groupId> <artifactId>test-webapps-parent</artifactId> - <version>9.4.50.v20221107</version> + <version>9.4.57.v20241219</version> </parent> <modelVersion>4.0.0</modelVersion> diff -Nru jetty9-9.4.50/tests/test-webapps/test-weld-cdi-webapp/src/main/webapp/WEB-INF/jetty-env.xml jetty9-9.4.57/tests/test-webapps/test-weld-cdi-webapp/src/main/webapp/WEB-INF/jetty-env.xml --- jetty9-9.4.50/tests/test-webapps/test-weld-cdi-webapp/src/main/webapp/WEB-INF/jetty-env.xml 2022-11-07 20:40:40.000000000 +0000 +++ jetty9-9.4.57/tests/test-webapps/test-weld-cdi-webapp/src/main/webapp/WEB-INF/jetty-env.xml 2024-12-19 21:51:26.000000000 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd"> <Configure id="webAppCtx" class="org.eclipse.jetty.webapp.WebAppContext"> <New id="BeanManager" class="org.eclipse.jetty.plus.jndi.Resource">