From 04acdb72f041a15267bb79c36d8fc4d517beaadb Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Tue, 3 May 2022 15:50:54 +0200
Subject: [PATCH] Jetty-12 Restructure
Copied over non ee10 components from the hackathon branch
Co-authored-by: Greg Wilkins
Co-authored-by: Jan Bartel
Co-authored-by: Joakim Erdfelt
Co-authored-by: Lachlan Roberts
Co-authored-by: Ludovic Orban
Co-authored-by: Olivier Lamy
Co-authored-by: Simone Bordet
---
Jenkinsfile | 162 +-
Jenkinsfile-autobahn | 40 +-
SECURITY.md | 47 -
VERSION.txt | 294 +-
...akarta.servlet.ServletContainerInitializer | 1 -
.../services/org.apache.juli.logging.Log | 1 -
.../jetty-codestyle-eclipse-ide.xml | 0
.../jetty-codestyle-intellij.xml | 0
.../build-resources}/pom.xml | 4 +-
.../src/main/resources/jetty-checkstyle.xml | 0
{jetty-unixsocket => build}/pom.xml | 21 +-
.../clirr-gen-master-index.output-foot.html | 0
.../clirr-gen-master-index.output-head.html | 0
.../clirr-gen-master-index.output-html.xslt | 0
.../scripts}/clirr-gen-master-index.sh | 0
{scripts => build/scripts}/git-log-csv.sh | 0
{scripts => build/scripts}/looptest.sh | 0
{scripts => build/scripts}/query-git-stats.sh | 0
{scripts => build/scripts}/release-jetty.sh | 0
demos/demo-async-rest/pom.xml | 19 -
.../test/resources/jetty-logging.properties | 3 -
.../resources/META-INF/javaxmail.providers | 1 -
...akarta.servlet.ServletContainerInitializer | 1 -
.../jetty-asciidoctor-extensions/pom.xml | 4 +-
documentation/jetty-documentation/pom.xml | 43 +-
.../annotations/quick-annotations-setup.adoc | 2 +-
.../using-annotations-embedded.adoc | 8 +-
.../main/asciidoc/old_docs/ant/jetty-ant.adoc | 2 +-
.../architecture/jetty-classloading.adoc | 20 +-
.../old_docs/contexts/custom-error-pages.adoc | 10 +-
.../contexts/setting-context-path.adoc | 2 +-
.../old_docs/contexts/setting-form-size.adoc | 2 +-
.../contexts/temporary-directories.adoc | 12 +-
...onfiguring-specific-webapp-deployment.adoc | 12 +-
.../deploying/deployment-architecture.adoc | 8 +-
.../deployment-processing-webapps.adoc | 56 +-
.../old_docs/deploying/quickstart-webapp.adoc | 6 +-
.../asciidoc/old_docs/extras/cgi-servlet.adoc | 2 +-
.../old_docs/extras/cross-origin-filter.adoc | 4 +-
.../old_docs/extras/default-servlet.adoc | 2 +-
.../asciidoc/old_docs/extras/dos-filter.adoc | 4 +-
.../old_docs/extras/header-filter.adoc | 4 +-
.../asciidoc/old_docs/extras/qos-filter.adoc | 4 +-
.../old_docs/fastcgi/configuring-fastcgi.adoc | 10 +-
.../asciidoc/old_docs/frameworks/cdi.adoc | 8 +-
.../asciidoc/old_docs/frameworks/osgi.adoc | 14 +-
.../configuring/what-to-configure.adoc | 4 +-
.../getting-started/jetty-running.adoc | 6 +-
.../old_docs/http2/configuring-push.adoc | 2 +-
.../old_docs/jetty-xml/jetty-env-xml.adoc | 6 +-
.../jetty-xml/jetty-web-xml-config.adoc | 4 +-
.../old_docs/jetty-xml/override-web-xml.adoc | 4 +-
.../old_docs/jetty-xml/webdefault-xml.adoc | 4 +-
.../old_docs/jndi/jndi-configuration.adoc | 10 +-
.../asciidoc/old_docs/jndi/jndi-embedded.adoc | 6 +-
.../asciidoc/old_docs/jndi/using-jndi.adoc | 2 +-
.../old_docs/jsp/configuring-jsp.adoc | 6 +-
.../old_docs/runner/jetty-runner.adoc | 10 +-
.../old_docs/security/authentication.adoc | 6 +-
.../security/configuring-form-size.adoc | 2 +-
.../old_docs/security/jaas-support.adoc | 2 +-
.../troubleshooting-locked-files.adoc | 6 +-
.../jetty/jetty-websocket-server-api.adoc | 2 +-
.../operations-guide/annotations/chapter.adoc | 10 +-
.../operations-guide/begin/deploy.adoc | 2 +-
.../deploy/deploy-extract-war.adoc | 2 +-
.../operations-guide/deploy/deploy-jetty.adoc | 4 +-
.../operations-guide/deploy/deploy-jndi.adoc | 2 +-
.../deploy/deploy-override-webxml.adoc | 2 +-
.../deploy/deploy-virtual-hosts.adoc | 10 +-
.../operations-guide/jaas/chapter.adoc | 2 +-
.../operations-guide/jndi/chapter.adoc | 12 +-
.../operations-guide/jsp/chapter.adoc | 2 +-
.../sessions/session-xml.adoc | 2 +-
.../operations-guide/xml/xml-syntax.adoc | 2 +-
.../client/http/client-http-transport.adoc | 15 +-
.../client/websocket/client-websocket.adoc | 4 +-
.../maven/jetty-maven-plugin.adoc | 6 +-
.../server/http/server-http-handler-use.adoc | 2 +-
.../server/http/server-http.adoc | 10 +-
.../sessions/session-sessionhandler.adoc | 12 +-
.../websocket/server-websocket-filter.adoc | 2 +-
.../websocket/server-websocket-jetty.adoc | 2 +-
.../asciidoc/programming-guide/websocket.adoc | 10 +-
.../jetty/docs/programming/WebSocketDocs.java | 24 +-
.../client/http2/HTTP2ClientDocs.java | 2 +-
.../client/websocket/WebSocketClientDocs.java | 8 +-
.../server/http/HTTPServerDocs.java | 16 +-
.../server/http2/HTTP2ServerDocs.java | 2 +-
.../server/session/SessionDocs.java | 32 +-
.../server/websocket/WebSocketServerDocs.java | 18 +-
documentation/pom.xml | 4 +-
javadoc/pom.xml | 20 +-
.../org.eclipse.jetty.webapp.Configuration | 1 -
.../jetty/client/AsyncContentProvider.java | 44 -
.../jetty/client/api/ContentProvider.java | 94 -
.../internal/RequestContentAdapter.java | 324 -
.../util/ByteBufferContentProvider.java | 96 -
.../client/util/BytesContentProvider.java | 89 -
.../client/util/DeferredContentProvider.java | 343 -
.../client/util/FormContentProvider.java | 50 -
.../util/InputStreamContentProvider.java | 256 -
.../client/util/MultiPartContentProvider.java | 408 -
.../util/OutputStreamContentProvider.java | 158 -
.../client/util/PathContentProvider.java | 188 -
.../client/util/StringContentProvider.java | 51 -
.../jetty/client/ssl/SslBytesServerTest.java | 1950 -
.../jetty-alpn/jetty-alpn-client/pom.xml | 6 +-
.../src/main/java/module-info.java | 0
.../jetty-alpn-conscrypt-client/pom.xml | 6 +-
.../src/main/java/module-info.java | 0
....eclipse.jetty.io.ssl.ALPNProcessor$Client | 0
.../test/resources/jetty-logging.properties | 0
.../jetty-alpn-conscrypt-server/pom.xml | 6 +-
.../src/main/java/module-info.java | 0
....eclipse.jetty.io.ssl.ALPNProcessor$Server | 0
.../server/ConscryptHTTP2ServerTest.java | 18 +-
.../test/resources/jetty-logging.properties | 0
.../src/test/resources/keystore.p12 | Bin
.../jetty-alpn/jetty-alpn-java-client/pom.xml | 6 +-
.../src/main/java/module-info.java | 0
....eclipse.jetty.io.ssl.ALPNProcessor$Client | 0
.../test/resources/jetty-logging.properties | 0
.../jetty-alpn/jetty-alpn-java-server/pom.xml | 6 +-
.../src/main/java/module-info.java | 0
....eclipse.jetty.io.ssl.ALPNProcessor$Server | 0
.../jetty/alpn/java/server/JDK9ALPNTest.java | 23 +-
.../test/resources/jetty-logging.properties | 0
.../src/test/resources/keystore.p12 | Bin
.../jetty-alpn/jetty-alpn-server/pom.xml | 6 +-
.../src/main/java/module-info.java | 0
jetty-core/jetty-alpn/pom.xml | 8 +-
jetty-core/{jetty-bom => jetty-bom/pom.xml} | 260 +-
jetty-core/jetty-client/pom.xml | 22 +-
.../src/main/java/module-info.java | 0
.../org/eclipse/jetty/client/HttpRequest.java | 24 -
.../org/eclipse/jetty/client/api/Request.java | 24 -
.../jetty/client/api/package-info.java | 0
.../dynamic/HttpClientTransportDynamic.java | 4 +-
.../eclipse/jetty/client/package-info.java | 0
.../jetty/client/util/package-info.java | 0
.../client/ClientConnectionCloseTest.java | 64 +-
.../jetty/client/ConnectionPoolTest.java | 97 +-
.../jetty/client/ContentResponseTest.java | 44 +-
.../jetty/client/EmptyServerHandler.java | 36 +-
.../client/HostnameVerificationTest.java | 18 +-
.../client/HttpAuthenticationStoreTest.java | 4 +-
.../client/HttpClientAsyncContentTest.java | 64 +-
.../client/HttpClientAuthenticationTest.java | 69 +-
.../client/HttpClientChunkedContentTest.java | 35 +-
.../client/HttpClientCorrelationDataTest.java | 9 +-
.../client/HttpClientCustomProxyTest.java | 21 +-
.../jetty/client/HttpClientGZIPTest.java | 61 +-
.../client/HttpClientIdleTimeoutTest.java | 16 +-
.../client/HttpClientProxyProtocolTest.java | 33 +-
.../jetty/client/HttpClientProxyTest.java | 74 +-
.../jetty/client/HttpClientRedirectTest.java | 146 +-
.../jetty/client/HttpClientTLSTest.java | 2 +
.../eclipse/jetty/client/HttpClientTest.java | 319 +-
.../jetty/client/HttpClientURITest.java | 149 +-
...pClientUploadDuringServerShutdownTest.java | 48 +-
.../client/HttpConnectionLifecycleTest.java | 17 +-
.../eclipse/jetty/client/HttpCookieTest.java | 301 +-
.../jetty/client/HttpRequestAbortTest.java | 96 +-
.../jetty/client/HttpResponseAbortTest.java | 29 +-
.../HttpResponseConcurrentAbortTest.java | 53 +-
.../client/NetworkTrafficListenerTest.java | 101 +-
.../jetty/client/ProxyConfigurationTest.java | 10 +-
.../client/ServerConnectionCloseTest.java | 3 +-
.../client/TLSServerConnectionCloseTest.java | 3 +-
.../client/ValidatingConnectionPoolTest.java | 37 +-
.../jetty/client/ssl/SslBytesTest.java | 2 +-
.../client/util/InputStreamContentTest.java | 21 +-
.../client/util/MultiPartContentTest.java | 50 +-
.../client/util/SPNEGOAuthenticationTest.java | 55 +-
.../client/util/TypedContentProviderTest.java | 49 +-
jetty-core/jetty-deploy/pom.xml | 10 +-
.../src/main/config/etc/jetty-decorate.xml | 2 +-
.../src/main/config/etc/jetty-deploy.xml | 2 +-
.../main/config/etc/jetty-web-decorate.xml | 6 +-
.../src/main/config/modules/decorate.mod | 4 +-
.../global-webapp-common.xml | 2 +-
.../global-webapp-common.d/webapp-common.xml | 2 +-
.../src/main/java/module-info.java | 3 +-
.../java/org/eclipse/jetty/deploy/App.java | 45 +-
.../jetty/deploy/DeploymentManager.java | 22 +-
.../jetty/deploy/bindings/package-info.java | 0
.../jetty/deploy/graph/package-info.java | 0
.../jetty/deploy/jmx/package-info.java | 0
.../eclipse/jetty/deploy/package-info.java | 0
.../deploy/providers/ScanningAppProvider.java | 5 +-
.../deploy/providers/WebAppProvider.java | 131 +-
.../jetty/deploy/providers/package-info.java | 0
.../jetty/deploy/util/package-info.java | 0
.../jetty/deploy/DeploymentManagerTest.java | 2 +
.../eclipse/jetty/deploy/MockAppProvider.java | 11 +-
...ScanningAppProviderRuntimeUpdatesTest.java | 12 +-
.../ScanningAppProviderStartupTest.java | 4 +-
.../jetty/deploy/test/XmlConfiguredJetty.java | 30 +-
.../resources/binding-test-contexts-1.xml | 8 +-
.../test/resources/context-binding-test-1.xml | 2 +-
.../src/test/resources/etc/realm.properties | 2 +-
.../src/test/resources/etc/webdefault.xml | 12 +-
.../src/test/resources/jetty-deploy-wars.xml | 2 +-
.../resources/jetty-deploymgr-contexts.xml | 2 +-
.../test/resources/jetty-logging.properties | 2 +-
.../test/resources/webapps/badapp/badapp.xml | 2 +-
.../src/test/resources/webapps/foo.xml | 2 +-
jetty-core/jetty-fcgi/fcgi-client/pom.xml | 6 +-
.../src/main/java/module-info.java | 5 +-
.../java/org/eclipse/jetty/fcgi/FCGI.java | 53 +-
.../fcgi/client/http/HttpChannelOverFCGI.java | 500 +-
.../http/HttpClientTransportOverFCGI.java | 7 +-
.../client/http/HttpConnectionOverFCGI.java | 18 +-
.../eclipse/jetty/fcgi/generator/Flusher.java | 4 +-
.../jetty/fcgi/generator/Generator.java | 2 +-
.../jetty/fcgi/parser/ClientParser.java | 10 +-
.../fcgi/parser/ResponseContentParser.java | 2 +-
.../test/resources/jetty-logging.properties | 0
jetty-core/jetty-fcgi/fcgi-server/pom.xml | 25 +-
.../src/main/java/module-info.java | 6 +-
.../server/ServerFCGIConnectionFactory.java | 1 +
.../server/internal/HttpStreamOverFCGI.java | 379 +
.../server/internal/ServerFCGIConnection.java | 208 +-
.../server/AbstractHttpClientServerTest.java | 3 +-
.../jetty/fcgi/server/HttpClientTest.java | 237 +-
.../test/resources/jetty-logging.properties | 0
jetty-core/jetty-fcgi/pom.xml | 8 +-
jetty-core/jetty-http-spi/pom.xml | 23 +-
.../src/main/java/module-info.java | 0
.../jetty/http/spi/HttpSpiContextHandler.java | 122 +-
.../jetty/http/spi/JettyHttpContext.java | 13 +-
.../jetty/http/spi/JettyHttpExchange.java | 8 +-
.../http/spi/JettyHttpExchangeDelegate.java | 105 +-
.../jetty/http/spi/JettyHttpServer.java | 22 +-
.../jetty/http/spi/JettyHttpsExchange.java | 8 +-
.../eclipse/jetty/http/spi/TestSPIServer.java | 27 +-
.../jetty-http-tools/pom.xml | 8 +-
.../matchers/HttpFieldsContainsHeaderKey.java | 0
.../HttpFieldsContainsHeaderValue.java | 0
.../tools/matchers/HttpFieldsHeaderValue.java | 0
.../tools/matchers/HttpFieldsMatchers.java | 0
.../matchers/HttpFieldsMatchersTest.java | 0
jetty-core/jetty-http/pom.xml | 6 +-
.../src/main/java/module-info.java | 3 +-
.../jetty/http/BadMessageException.java | 9 +-
.../jetty/http/CachingContentFactory.java | 407 +
.../org/eclipse/jetty/http/CookieCache.java | 118 +
.../org/eclipse/jetty/http/CookieCutter.java | 23 +-
.../jetty/http/GZIPContentDecoder.java | 33 +-
.../jetty/http/Http10FieldPreEncoder.java | 26 +
.../jetty/http/Http11FieldPreEncoder.java | 26 +
.../jetty/http/Http1FieldPreEncoder.java | 9 +-
.../org/eclipse/jetty/http/HttpContent.java | 27 +-
.../org/eclipse/jetty/http/HttpCookie.java | 60 +-
.../org/eclipse/jetty/http/HttpField.java | 24 +-
.../org/eclipse/jetty/http/HttpFields.java | 1112 +-
.../org/eclipse/jetty/http/HttpGenerator.java | 10 +-
.../org/eclipse/jetty/http/HttpParser.java | 40 +-
.../org/eclipse/jetty/http/HttpTester.java | 2 +-
.../java/org/eclipse/jetty/http/HttpURI.java | 95 +-
.../org/eclipse/jetty/http/HttpVersion.java | 8 +
.../java/org/eclipse/jetty/http/MetaData.java | 11 +-
.../org/eclipse/jetty/http/MimeTypes.java | 47 +-
.../jetty/http/PreEncodedHttpField.java | 74 +-
.../jetty/http/PrecompressedHttpContent.java | 64 +-
.../jetty/http/ResourceHttpContent.java | 61 +-
.../org/eclipse/jetty/http/package-info.java | 0
...org.eclipse.jetty.http.HttpFieldPreEncoder | 3 +-
.../jetty/http/GZIPContentDecoderTest.java | 58 +-
.../eclipse/jetty/http/HttpFieldsTest.java | 261 +-
.../eclipse/jetty/http/HttpParserTest.java | 78 +-
.../org/eclipse/jetty/http/HttpURITest.java | 402 +-
jetty-core/jetty-http2/http2-client/pom.xml | 42 +-
.../src/main/java/module-info.java | 0
.../client/HTTP2ClientConnectionFactory.java | 7 +-
.../client/internal/HTTP2ClientSession.java | 8 +-
jetty-core/jetty-http2/http2-common/pom.xml | 6 +-
.../src/main/java/module-info.java | 6 +-
.../http2/AbstractFlowControlStrategy.java | 2 +-
.../http2/BufferingFlowControlStrategy.java | 4 +
.../java/org/eclipse/jetty/http2/IStream.java | 24 +
.../org/eclipse/jetty/http2/RateControl.java | 2 +-
.../http2/SimpleFlowControlStrategy.java | 4 +
.../jetty/http2/WindowRateControl.java | 2 +-
.../jetty/http2/frames/GoAwayFrame.java | 2 +-
.../jetty/http2/frames/ResetFrame.java | 2 +-
.../jetty/http2/internal/ErrorCode.java | 2 +-
.../eclipse/jetty/http2/internal/Flags.java | 2 +-
.../jetty/http2/internal/HTTP2Channel.java | 9 +-
.../jetty/http2/internal/HTTP2Connection.java | 5 +-
.../jetty/http2/internal/HTTP2Flusher.java | 4 +-
.../jetty/http2/internal/HTTP2Session.java | 10 +-
.../jetty/http2/internal/HTTP2Stream.java | 21 +-
.../http2/internal/HTTP2StreamEndPoint.java | 3 +-
.../internal/generator/DataGenerator.java | 4 +-
.../internal/generator/FrameGenerator.java | 2 +-
.../http2/internal/generator/Generator.java | 2 +-
.../internal/generator/GoAwayGenerator.java | 4 +-
.../internal/generator/HeaderGenerator.java | 2 +-
.../internal/generator/HeadersGenerator.java | 4 +-
.../internal/generator/NoOpGenerator.java | 2 +-
.../internal/generator/PingGenerator.java | 4 +-
.../internal/generator/PrefaceGenerator.java | 2 +-
.../internal/generator/PriorityGenerator.java | 4 +-
.../generator/PushPromiseGenerator.java | 4 +-
.../internal/generator/ResetGenerator.java | 4 +-
.../internal/generator/SettingsGenerator.java | 4 +-
.../generator/WindowUpdateGenerator.java | 4 +-
.../http2/internal/parser/BodyParser.java | 6 +-
.../parser/ContinuationBodyParser.java | 6 +-
.../http2/internal/parser/DataBodyParser.java | 4 +-
.../internal/parser/GoAwayBodyParser.java | 4 +-
.../internal/parser/HeaderBlockFragments.java | 2 +-
.../internal/parser/HeaderBlockParser.java | 4 +-
.../http2/internal/parser/HeaderParser.java | 3 +-
.../internal/parser/HeadersBodyParser.java | 6 +-
.../jetty/http2/internal/parser/Parser.java | 7 +-
.../http2/internal/parser/PingBodyParser.java | 6 +-
.../http2/internal/parser/PrefaceParser.java | 4 +-
.../internal/parser/PriorityBodyParser.java | 4 +-
.../parser/PushPromiseBodyParser.java | 6 +-
.../internal/parser/ResetBodyParser.java | 4 +-
.../http2/internal/parser/ServerParser.java | 7 +-
.../internal/parser/SettingsBodyParser.java | 7 +-
.../internal/parser/UnknownBodyParser.java | 4 +-
.../parser/WindowUpdateBodyParser.java | 4 +-
.../http2/frames/ContinuationParseTest.java | 8 +-
.../http2/frames/DataGenerateParseTest.java | 6 +-
.../jetty/http2/frames/FrameFloodTest.java | 6 +-
.../http2/frames/GoAwayGenerateParseTest.java | 6 +-
.../frames/HeadersGenerateParseTest.java | 6 +-
.../frames/HeadersTooLargeParseTest.java | 8 +-
.../http2/frames/MaxFrameSizeParseTest.java | 4 +-
.../http2/frames/PingGenerateParseTest.java | 6 +-
.../frames/PriorityGenerateParseTest.java | 6 +-
.../frames/PushPromiseGenerateParseTest.java | 6 +-
.../http2/frames/ResetGenerateParseTest.java | 6 +-
.../frames/SettingsGenerateParseTest.java | 8 +-
.../jetty/http2/frames/UnknownParseTest.java | 4 +-
.../frames/WindowUpdateGenerateParseTest.java | 6 +-
.../test/resources/jetty-logging.properties | 0
jetty-core/jetty-http2/http2-hpack/pom.xml | 8 +-
.../src/main/java/module-info.java | 1 +
.../jetty/http2/hpack/HpackContext.java | 5 +-
.../jetty/http2/hpack/HpackDecoder.java | 8 +-
.../jetty/http2/hpack/HpackEncoder.java | 2 +
.../jetty/http2/hpack/HpackException.java | 5 +-
.../http2/hpack/HpackFieldPreEncoder.java | 2 +
.../hpack/internal/AuthorityHttpField.java | 6 +-
.../jetty/http2/hpack/internal/Huffman.java | 3 +-
.../http2/hpack/internal/MetaDataBuilder.java | 10 +-
.../http2/hpack/internal/NBitInteger.java | 2 +-
.../hpack/internal/StaticTableHttpField.java | 2 +-
.../jetty/http2/hpack/HpackContextTest.java | 2 +
.../jetty/http2/hpack/HpackDecoderTest.java | 47 +-
.../jetty/http2/hpack/HuffmanTest.java | 7 +-
.../jetty/http2/hpack/NBitIntegerTest.java | 19 +-
.../test/resources/jetty-logging.properties | 0
.../http2-http-client-transport/pom.xml | 37 +-
.../src/main/java/module-info.java | 0
.../ClientConnectionFactoryOverHTTP2.java | 2 +
.../http/HttpClientTransportOverHTTP2.java | 11 +-
.../internal/ClientHTTP2StreamEndPoint.java | 6 +-
.../internal/HTTPSessionListenerPromise.java | 10 +-
.../http/internal}/HttpChannelOverHTTP2.java | 6 +-
.../internal/HttpConnectionOverHTTP2.java | 6 +-
.../http/internal/HttpReceiverOverHTTP2.java | 6 +-
.../http/internal/HttpSenderOverHTTP2.java | 2 +-
jetty-core/jetty-http2/http2-server/pom.xml | 87 +-
.../src/main/config/etc/jetty-http2.xml | 2 +-
.../src/main/config/etc/jetty-http2c.xml | 2 +-
.../src/main/java/module-info.java | 0
.../AbstractHTTP2ServerConnectionFactory.java | 27 +-
.../server/HTTP2CServerConnectionFactory.java | 6 +-
.../server/HTTP2ServerConnectionFactory.java | 13 +-
.../internal/HTTP2ServerConnection.java | 215 +-
.../server/internal/HTTP2ServerSession.java | 10 +-
.../server/internal/HttpChannelOverHTTP2.java | 760 +
.../server/internal/HttpStreamOverHTTP2.java | 562 +
.../internal/HttpTransportOverHTTP2.java | 1116 +-
.../internal/ServerHTTP2StreamEndPoint.java | 6 +-
.../jetty-http2/jetty-http2-tests/pom.xml | 114 +
.../jetty/http2/tests/AbstractServerTest.java | 17 +-
.../jetty/http2/tests/AbstractTest.java | 58 +-
.../jetty/http2/tests/AsyncIOTest.java | 110 +-
.../jetty/http2/tests/AsyncServletTest.java | 731 +-
.../BlockedWritesWithSmallThreadPoolTest.java | 16 +-
.../BufferingFlowControlStrategyTest.java | 2 +-
.../eclipse/jetty/http2/tests/CloseTest.java | 11 +-
.../tests/ConcurrentStreamCreationTest.java | 6 +-
.../jetty/http2/tests/ConnectTimeoutTest.java | 9 +-
.../jetty/http2/tests/ConnectTunnelTest.java | 6 +-
.../jetty/http2/tests/ContentLengthTest.java | 82 +-
.../jetty/http2/tests/DataDemandTest.java | 16 +-
.../http2/tests/FlowControlStalledTest.java | 3 +-
.../http2/tests/FlowControlStrategyTest.java | 9 +-
.../http2/tests/FlowControlWindowsTest.java | 3 +-
.../eclipse/jetty/http2/tests/GoAwayTest.java | 34 +-
.../jetty/http2/tests/H2SpecServer.java | 3 +-
.../jetty/http2/tests/HTTP2CServer.java | 41 +-
.../jetty/http2/tests/HTTP2CServerTest.java | 23 +-
.../jetty/http2/tests/HTTP2ServerTest.java | 87 +-
.../eclipse/jetty/http2/tests/HTTP2Test.java | 192 +-
.../HttpClientTransportOverHTTP2Test.java | 89 +-
.../jetty/http2/tests/IdleTimeoutTest.java | 121 +-
.../jetty/http2/tests/InterleavingTest.java | 4 +-
.../http2/tests/MaxConcurrentStreamsTest.java | 162 +-
.../http2/tests/MaxPushedStreamsTest.java | 10 +-
.../tests/MultiplexedConnectionPoolTest.java | 84 +-
.../eclipse/jetty/http2/tests/PingTest.java | 4 +-
.../jetty/http2/tests/PrefaceTest.java | 32 +-
.../tests/PriorKnowledgeHTTP2OverTLSTest.java | 57 +-
.../jetty/http2/tests/PriorityTest.java | 10 +-
.../jetty/http2/tests/ProxyProtocolTest.java | 65 +-
.../eclipse/jetty/http2/tests/ProxyTest.java | 356 +-
.../http2/tests/PushCacheFilterTest.java | 1939 +-
.../http2/tests/PushedResourcesTest.java | 56 +-
.../jetty/http2/tests/RawHTTP2ProxyTest.java | 62 +-
.../http2/tests/RequestTrailersTest.java | 8 +-
.../http2/tests/ResponseTrailerTest.java | 19 +-
.../jetty/http2/tests/SessionFailureTest.java | 6 +-
.../tests/SimpleFlowControlStrategyTest.java | 2 +-
.../http2/tests/SmallThreadPoolLoadTest.java | 56 +-
.../jetty/http2/tests/StreamCloseTest.java | 22 +-
.../jetty/http2/tests/StreamCountTest.java | 10 +-
.../jetty/http2/tests/StreamResetTest.java | 315 +-
.../jetty/http2/tests/TrailersTest.java | 117 +-
.../test/resources/jetty-logging.properties | 1 -
jetty-core/jetty-http2/pom.xml | 9 +-
jetty-core/jetty-http3/http3-client/pom.xml | 6 +-
.../src/main/java/module-info.java | 0
jetty-core/jetty-http3/http3-common/pom.xml | 6 +-
.../src/main/java/module-info.java | 0
.../http3/internal/HTTP3StreamConnection.java | 20 +-
.../http3-http-client-transport/pom.xml | 6 +-
.../src/main/java/module-info.java | 0
.../http/internal/HttpChannelOverHTTP3.java | 503 +-
jetty-core/jetty-http3/http3-qpack/pom.xml | 8 +-
.../src/main/java/module-info.java | 0
.../qpack/internal/metadata/Http3Fields.java | 10 +-
.../test/resources/jetty-logging.properties | 0
jetty-core/jetty-http3/http3-server/pom.xml | 6 +-
.../src/main/java/module-info.java | 0
.../server/HTTP3ServerConnectionFactory.java | 17 +-
.../server/internal/HttpStreamOverHTTP3.java | 489 +
.../internal/ServerHTTP3StreamConnection.java | 142 +-
jetty-core/jetty-http3/http3-tests/pom.xml | 6 +-
.../jetty/http3/tests/ClientServerTest.java | 8 +-
.../jetty/http3/tests/DataDemandTest.java | 57 -
.../http3/tests/HandlerClientServerTest.java | 22 +-
.../HttpClientTransportOverHTTP3Test.java | 40 +-
.../test/resources/jetty-logging.properties | 1 +
jetty-core/jetty-http3/pom.xml | 8 +-
jetty-core/jetty-io/pom.xml | 6 +-
.../jetty-io}/src/main/java/module-info.java | 0
.../eclipse/jetty/io/AbstractConnection.java | 30 +-
.../eclipse/jetty/io/AbstractEndPoint.java | 9 +-
.../io/ArrayRetainableByteBufferPool.java | 30 +
.../java/org/eclipse/jetty/io/Connection.java | 51 +-
.../java/org/eclipse/jetty/io/EndPoint.java | 4 +-
.../org/eclipse/jetty/io/IdleTimeout.java | 5 +-
.../io/LogarithmicArrayByteBufferPool.java | 2 +
.../jetty/io/MappedByteBufferPool.java | 2 +
.../org/eclipse/jetty/io/QuietException.java | 22 +
.../jetty/io/SocketChannelEndPoint.java | 3 +-
.../org/eclipse/jetty/io/package-info.java | 0
.../eclipse/jetty/io/ssl/SslConnection.java | 24 +-
.../eclipse/jetty/io/ssl/package-info.java | 0
.../io/ArrayRetainableByteBufferPoolTest.java | 2 +-
jetty-core/jetty-jmx/pom.xml | 6 +-
.../jetty-jmx}/src/main/java/module-info.java | 0
.../org/eclipse/jetty/jmx/package-info.java | 0
jetty-core/jetty-jndi/pom.xml | 23 +-
.../src/main/java/module-info.java | 4 +-
.../jndi/factories/MailSessionReference.java | 28 +-
.../jetty/jndi/factories/package-info.java | 0
.../eclipse/jetty/jndi/java/package-info.java | 0
.../jetty/jndi/local/package-info.java | 0
.../org/eclipse/jetty/jndi/package-info.java | 0
.../org/eclipse/jetty/jndi/java/TestJNDI.java | 248 +-
jetty-core/jetty-keystore/pom.xml | 6 +-
jetty-core/jetty-quic/pom.xml | 8 +-
jetty-core/jetty-quic/quic-client/pom.xml | 6 +-
.../src/main/java/module-info.java | 0
.../jetty/quic/client/End2EndClientTest.java | 29 +-
.../test/resources/jetty-logging.properties | 0
.../src/test/resources/keystore.p12 | Bin
jetty-core/jetty-quic/quic-common/pom.xml | 6 +-
.../src/main/java/module-info.java | 0
.../jetty/quic/common/package-info.java | 0
jetty-core/jetty-quic/quic-quiche/pom.xml | 6 +-
.../quic-quiche/quic-quiche-common/pom.xml | 4 +-
.../src/main/java/module-info.java | 0
.../quic-quiche-foreign-incubator/pom.xml | 4 +-
.../src/main/java/module-info.java | 0
.../quiche/foreign/incubator/sockaddr.java | 0
...rg.eclipse.jetty.quic.quiche.QuicheBinding | 0
.../foreign/incubator/LowLevelQuicheTest.java | 4 +
.../test/resources/jetty-logging.properties | 0
.../src/test/resources/keystore.p12 | Bin
.../quic-quiche/quic-quiche-jna/pom.xml | 4 +-
.../src/main/java/module-info.java | 0
.../jetty/quic/quiche/jna/sockaddr.java | 0
...rg.eclipse.jetty.quic.quiche.QuicheBinding | 0
.../quic/quiche/jna/LowLevelQuicheTest.java | 0
.../test/resources/jetty-logging.properties | 0
.../src/test/resources/keystore.p12 | Bin
jetty-core/jetty-quic/quic-server/pom.xml | 6 +-
.../src/main/java/module-info.java | 0
.../quic/server/ServerQuicConnectorTest.java | 36 +-
.../test/resources/jetty-logging.properties | 0
.../src/test/resources/keystore.p12 | Bin
jetty-core/jetty-rewrite/pom.xml | 18 +-
.../src/main/config/etc/jetty-rewrite.xml | 0
.../src/main/java/module-info.java | 4 +-
.../jetty/rewrite/RewriteCustomizer.java | 9 +-
.../rewrite/handler/CompactPathRule.java | 40 +-
.../rewrite/handler/CookiePatternRule.java | 65 +-
.../handler/ForceRequestHeaderValueRule.java | 54 +-
.../handler/ForwardedSchemeHeaderRule.java | 21 +-
.../rewrite/handler/HeaderPatternRule.java | 118 +-
.../rewrite/handler/HeaderRegexRule.java | 115 +-
.../jetty/rewrite/handler/HeaderRule.java | 55 +-
.../jetty/rewrite/handler/InvalidURIRule.java | 130 +
.../jetty/rewrite/handler/PatternRule.java | 47 +-
.../rewrite/handler/RedirectPatternRule.java | 79 +-
.../rewrite/handler/RedirectRegexRule.java | 88 +-
.../jetty/rewrite/handler/RegexRule.java | 66 +-
.../rewrite/handler/ResponsePatternRule.java | 88 +-
.../jetty/rewrite/handler/RewriteHandler.java | 122 +-
.../rewrite/handler/RewritePatternRule.java | 70 +-
.../rewrite/handler/RewriteRegexRule.java | 95 +-
.../eclipse/jetty/rewrite/handler/Rule.java | 64 +-
.../jetty/rewrite/handler/RuleContainer.java | 178 +-
.../handler/TerminatingPatternRule.java | 24 +-
.../rewrite/handler/TerminatingRegexRule.java | 20 +-
.../handler/VirtualHostRuleContainer.java | 99 +-
.../jetty/rewrite/handler/package-info.java | 0
.../rewrite/handler/AbstractRuleTest.java | 41 +
.../handler/CookiePatternRuleTest.java | 187 +-
.../ForceRequestHeaderValueRuleTest.java | 159 +-
.../ForwardedSchemeHeaderRuleTest.java | 133 +-
.../handler/HeaderPatternRuleTest.java | 131 +-
.../rewrite/handler/HeaderRegexRuleTest.java | 182 +-
.../rewrite/handler/InvalidURIRuleTest.java | 254 +
.../rewrite/handler/PatternRuleTest.java | 248 +-
.../handler/RedirectPatternRuleTest.java | 68 +-
.../handler/RedirectRegexRuleTest.java | 104 +-
.../jetty/rewrite/handler/RegexRuleTest.java | 170 +-
.../handler/ResponsePatternRuleTest.java | 79 +-
.../rewrite/handler/RewriteHandlerTest.java | 216 +-
.../handler/RewritePatternRuleTest.java | 163 +-
.../rewrite/handler/RewriteRegexRuleTest.java | 186 +-
.../handler/TerminatingPatternRuleTest.java | 91 +-
.../handler/TerminatingRegexRuleTest.java | 91 +-
.../handler/VirtualHostRuleContainerTest.java | 274 +-
.../test/resources/jetty-logging.properties | 2 +
.../jetty-rewrite.xml | 2 +-
jetty-core/jetty-server/pom.xml | 38 +-
.../main/config/etc/jetty-bytebufferpool.xml | 4 +-
.../src/main/config/etc/jetty-requestlog.xml | 2 +-
.../etc/sessions/file/session-store.xml | 0
.../etc/sessions/jdbc/session-store.xml | 0
.../etc/sessions/session-cache-hash.xml | 2 +-
.../main/config/modules/bytebufferpool.mod | 12 +-
.../src/main/config/modules/requestlog.mod | 25 +-
.../src/main/config/modules/server.mod | 2 +-
.../config/modules/session-cache-hash.mod | 2 +-
.../src/main/config/modules/stats.mod | 2 +-
.../modules/test-keystore/test-keystore.p12 | Bin 0 -> 2565 bytes
.../src/main/java/module-info.java | 11 +-
.../jetty/server/AbstractConnector.java | 45 +-
.../server/AllowedResourceAliasChecker.java | 20 +-
.../jetty/server/CachedContentFactory.java | 128 +-
.../org/eclipse/jetty/server/Components.java | 47 +
.../jetty/server/ConnectionFactory.java | 1 -
.../jetty/server/ConnectionMetaData.java | 166 +
.../org/eclipse/jetty/server/Content.java | 1020 +
.../jetty/server/ContentProcessor.java | 225 +
.../org/eclipse/jetty/server/Context.java | 59 +
.../jetty/server/CustomRequestLog.java | 143 +-
.../server/DetectorConnectionFactory.java | 18 +-
.../server/ForwardedRequestCustomizer.java | 230 +-
.../jetty/server/FutureFormFields.java | 240 +
.../org/eclipse/jetty/server/Handler.java | 697 +-
.../jetty/server/HandlerContainer.java | 35 +-
.../jetty/server/HostHeaderCustomizer.java | 50 +-
.../org/eclipse/jetty/server/HttpChannel.java | 1601 +-
.../jetty/server/HttpChannelListeners.java | 18 +-
.../jetty/server/HttpConfiguration.java | 26 +-
.../jetty/server/HttpConnectionFactory.java | 1 +
.../org/eclipse/jetty/server/HttpStream.java | 189 +
.../eclipse/jetty/server/LocalConnector.java | 17 +
.../jetty/server/ProxyConnectionFactory.java | 32 +-
.../eclipse/jetty/server/ProxyCustomizer.java | 39 +-
.../org/eclipse/jetty/server/Request.java | 2936 +-
.../org/eclipse/jetty/server/RequestLog.java | 13 +-
.../jetty/server/ResourceContentFactory.java | 1 +
.../eclipse/jetty/server/ResourceService.java | 56 +-
.../org/eclipse/jetty/server/Response.java | 1706 +-
.../jetty/server/SecureRequestCustomizer.java | 317 +-
.../java/org/eclipse/jetty/server/Server.java | 502 +-
.../eclipse/jetty/server/ServerConnector.java | 37 +-
.../eclipse/jetty/server/ShutdownMonitor.java | 8 +-
.../jetty/server/SslConnectionFactory.java | 2 +-
.../SymlinkAllowedResourceAliasChecker.java | 2 +-
.../jetty/server/handler/AbstractHandler.java | 143 +-
.../handler/AbstractHandlerContainer.java | 110 +-
.../handler/BufferedResponseHandler.java | 299 +-
.../jetty/server/handler/ContextHandler.java | 2983 +-
.../handler/ContextHandlerCollection.java | 154 +-
.../jetty/server/handler/ContextRequest.java | 134 +
.../jetty/server/handler/ContextResponse.java | 51 +
.../jetty/server/handler/DebugHandler.java | 18 +-
.../jetty/server/handler/DefaultHandler.java | 77 +-
.../jetty/server/handler/DelayedHandler.java | 260 +
.../jetty/server/handler/ErrorProcessor.java | 569 +
.../handler/FileBufferedResponseHandler.java | 16 +-
.../jetty/server/handler/HandlerList.java | 30 +-
.../jetty/server/handler/HandlerWrapper.java | 124 +-
.../jetty/server/handler/HotSwapHandler.java | 103 +-
.../server/handler/IdleTimeoutHandler.java | 61 +-
.../server/handler/InetAccessHandler.java | 41 +-
.../handler/ManagedAttributeListener.java | 9 +-
.../server/handler/MovedContextHandler.java | 46 +-
.../server/handler/ProxiedRequestHandler.java | 77 +
.../jetty/server/handler/ResourceHandler.java | 1436 +-
.../handler/SecuredRedirectHandler.java | 60 +-
.../jetty/server/handler/ShutdownHandler.java | 20 +-
.../server/handler/StatisticsHandler.java | 803 +-
.../server/handler/ThreadLimitHandler.java | 140 +-
.../server/handler/gzip/GzipHandler.java | 296 +-
.../server/handler/gzip/GzipRequest.java | 203 +
.../server/handler/gzip/GzipResponse.java | 171 +-
.../handler/gzip/HeaderWrappingRequest.java | 24 +-
.../server/handler/gzip/package-info.java | 0
.../handler/jmx/AbstractHandlerMBean.java | 97 +
.../handler/jmx/ContextHandlerMBean.java | 19 +-
.../server/handler/jmx/package-info.java | 0
.../jetty/server/handler/package-info.java | 0
.../server/internal/HttpChannelState.java | 2544 +-
.../jetty/server/internal/HttpConnection.java | 1216 +-
.../server/internal/MultiPartParser.java | 5 +-
.../server/internal/ResponseHttpFields.java | 336 +
.../server/jmx/AbstractHandlerMBean.java | 82 +
.../eclipse/jetty/server/jmx/ServerMBean.java | 14 +-
.../jetty/server/jmx/package-info.java | 2 +-
.../eclipse/jetty/server/package-info.java | 0
.../org/eclipse/jetty/server/ssl/FixJPMS.java | 20 +
.../jetty/server/AbstractHttpTest.java | 13 +-
.../jetty/server/ConnectionOpenCloseTest.java | 26 +-
.../jetty/server/ConnectorCloseTestBase.java | 6 +-
.../jetty/server/ConnectorTimeoutTest.java | 95 +-
.../org/eclipse/jetty/server/ContentTest.java | 910 +
.../jetty/server/CustomRequestLogTest.java | 663 +
.../server/CustomResourcesMonitorTest.java | 2 +
.../jetty/server/DelayedServerTest.java | 45 +-
.../jetty/server/DetectorConnectionTest.java | 26 +-
.../jetty/server/ErrorProcessorTest.java | 699 +
.../jetty/server/ExtendedServerTest.java | 41 +-
.../ForwardedRequestCustomizerTest.java | 254 +-
.../jetty/server/GracefulStopTest.java | 59 +-
.../eclipse/jetty/server/HalfCloseTest.java | 22 +-
.../server/HostHeaderCustomizerTest.java | 12 +-
.../jetty/server/HttpChannelEventTest.java | 58 +-
.../eclipse/jetty/server/HttpChannelTest.java | 1283 +
...ttpConfigurationAuthorityOverrideTest.java | 193 +-
.../jetty/server/HttpConnectionTest.java | 716 +-
.../jetty/server/HttpServerTestBase.java | 1201 +-
.../jetty/server/HttpServerTestFixture.java | 253 +-
.../eclipse/jetty/server/LargeHeaderTest.java | 18 +-
.../jetty/server/LocalConnectorTest.java | 295 +-
.../jetty/server/LowResourcesMonitorTest.java | 3 +-
.../jetty/server/MockConnectionMetaData.java | 110 +
.../eclipse/jetty/server/MockConnector.java | 35 +-
.../eclipse/jetty/server/MockHttpStream.java | 267 +
.../jetty/server/MultiPartCaptureTest.java | 28 +-
.../server/MultiPartFormInputStreamTest.java | 44 +-
.../jetty/server/MultiPartParserTest.java | 3 +-
.../jetty/server/NotAcceptingTest.java | 33 +-
.../server/OptionalSslConnectionTest.java | 10 +-
.../jetty/server/PartialRFC2616Test.java | 6 +-
.../jetty/server/ProxyConnectionTest.java | 17 +-
.../jetty/server/ProxyCustomizerTest.java | 38 +-
.../jetty/server/ProxyProtocolTest.java | 55 +-
.../eclipse/jetty/server/RequestLogTest.java | 56 +-
.../org/eclipse/jetty/server/RequestTest.java | 2276 +-
.../jetty/server/ResourceCacheTest.java | 38 +-
.../server/ServerConnectorAcceptTest.java | 19 +-
.../server/ServerConnectorCloseTest.java | 2 +-
.../server/ServerConnectorHttpServerTest.java | 104 +-
.../jetty/server/ServerConnectorTest.java | 41 +-
.../server/ServerConnectorTimeoutTest.java | 29 +-
.../jetty/server/ShutdownMonitorTest.java | 1 +
.../SlowClientWithPipelinedRequestTest.java | 25 +-
.../org/eclipse/jetty/server/StopTest.java | 32 +-
.../jetty/server/ThreadStarvationTest.java | 25 +-
.../handler/AllowSymLinkAliasCheckerTest.java | 13 +-
.../handler/BufferedResponseHandlerTest.java | 74 +-
.../handler/ContextHandlerCollectionTest.java | 33 +-
.../ContextHandlerGetResourceTest.java | 28 +-
.../server/handler/ContextHandlerTest.java | 1366 +-
.../server/handler/DebugHandlerTest.java | 9 +-
.../server/handler/DefaultHandlerTest.java | 3 +-
.../server/handler/DelayedHandlerTest.java | 460 +
.../jetty/server/handler/DumpHandler.java | 300 +-
.../jetty/server/handler/EchoHandler.java | 56 +
.../FileBufferedResponseHandlerTest.java | 102 +-
.../jetty/server/handler/HandlerTest.java | 155 +-
.../jetty/server/handler/HelloHandler.java | 54 +
.../server/handler/InetAccessHandlerTest.java | 9 +-
.../server/handler/NcsaRequestLogTest.java | 35 +-
.../handler/ResourceHandlerRangeTest.java | 4 +-
.../server/handler/ResourceHandlerTest.java | 725 +-
.../SecuredRedirectHandlerCodeTest.java | 15 +-
.../handler/SecuredRedirectHandlerTest.java | 38 +-
.../server/handler/ShutdownHandlerTest.java | 10 +-
.../server/handler/StatisticsHandlerTest.java | 1477 +-
.../handler/ThreadLimitHandlerTest.java | 110 +-
.../server/handler/gzip}/GzipHandlerTest.java | 407 +-
.../jetty/server/jmh/HandlerBenchmark.java | 165 +
.../server/resource/RangeWriterTest.java | 2 +
.../jetty/server/ssl/SSLCloseTest.java | 51 +-
.../jetty/server/ssl/SSLEngineTest.java | 147 +-
.../ssl/SSLReadEOFAfterResponseTest.java | 51 +-
.../SSLSelectChannelConnectorLoadTest.java | 36 +-
.../ssl/ServerConnectorSslServerTest.java | 84 +-
.../jetty/server/ssl/SlowClientsTest.java | 39 +-
.../ssl/SniSslConnectionFactoryTest.java | 52 +-
.../server/ssl/SslConnectionFactoryTest.java | 18 +-
.../ssl/SslContextFactoryReloadTest.java | 30 +-
.../ssl/SslSelectChannelTimeoutTest.java | 4 +-
.../jetty/server/ssl/SslUploadTest.java | 62 +-
.../test/resources/jetty-logging.properties | 6 +-
jetty-core/jetty-session/pom.xml | 61 +
.../src/main/java/module-info.java | 25 +
.../jetty}/session/AbstractSessionCache.java | 67 +-
.../session/AbstractSessionCacheFactory.java | 14 +-
.../session/AbstractSessionDataStore.java | 3 +-
.../AbstractSessionDataStoreFactory.java | 2 +-
.../jetty/session/AbstractSessionManager.java | 1252 +
.../session/CachingSessionDataStore.java | 2 +-
.../CachingSessionDataStoreFactory.java | 6 +-
.../jetty}/session/DatabaseAdaptor.java | 2 +-
.../jetty}/session/DefaultSessionCache.java | 16 +-
.../session/DefaultSessionCacheFactory.java | 6 +-
.../session/DefaultSessionIdManager.java | 96 +-
.../jetty}/session/FileSessionDataStore.java | 3 +-
.../session/FileSessionDataStoreFactory.java | 4 +-
.../eclipse/jetty}/session/HouseKeeper.java | 21 +-
.../jetty}/session/JDBCSessionDataStore.java | 2 +-
.../session/JDBCSessionDataStoreFactory.java | 4 +-
.../jetty}/session/NullSessionCache.java | 16 +-
.../session/NullSessionCacheFactory.java | 10 +-
.../jetty}/session/NullSessionDataStore.java | 2 +-
.../session/NullSessionDataStoreFactory.java | 4 +-
.../org/eclipse/jetty}/session/Session.java | 435 +-
.../eclipse/jetty}/session/SessionCache.java | 26 +-
.../jetty}/session/SessionCacheFactory.java | 4 +-
.../eclipse/jetty/session/SessionConfig.java | 108 +
.../jetty}/session/SessionContext.java | 51 +-
.../eclipse/jetty}/session/SessionData.java | 2 +-
.../jetty}/session/SessionDataMap.java | 2 +-
.../jetty}/session/SessionDataMapFactory.java | 2 +-
.../jetty}/session/SessionDataStore.java | 2 +-
.../session/SessionDataStoreFactory.java | 4 +-
.../jetty/session}/SessionIdManager.java | 26 +-
.../jetty/session/SessionInactivityTimer.java | 121 +
.../eclipse/jetty/session/SessionManager.java | 155 +
.../UnreadableSessionDataException.java | 2 +-
.../UnwriteableSessionDataException.java | 2 +-
.../eclipse/jetty}/session/package-info.java | 2 +-
.../session/AbstractSessionCacheTest.java | 409 +-
.../session/AbstractSessionDataStoreTest.java | 503 +-
.../session/AbstractSessionManagerTest.java | 345 +
.../session/DefaultSessionCacheTest.java | 663 +
.../session/DefaultSessionIdManagerTest.java | 120 +
.../jetty/session/DirtyAttributeTest.java | 101 +
.../session/FileSessionDataStoreTest.java | 2 +-
.../jetty/session/FileSessionsTest.java | 70 +-
.../jetty}/session/FileTestHelper.java | 3 +-
.../jetty}/session/HouseKeeperTest.java | 6 +-
.../jetty}/session/NullSessionCacheTest.java | 105 +-
.../jetty/session/SessionListenerTest.java | 124 +
.../jetty/session/SimpleSessionHandler.java | 187 +
.../session/SimpleSessionHandlerTest.java | 322 +
.../jetty/session/TestableRequest.java | 159 +
.../session/TestableSessionDataStore.java | 119 +
.../jetty/session/TestableSessionManager.java | 176 +
.../src/test}/resources/Foo.clazz | Bin
.../src/test}/resources/Foo.java | 0
.../src/test}/resources/Proxyable.clazz | Bin
.../src/test}/resources/Proxyable.java | 0
.../test}/resources/ProxyableFactory.clazz | Bin
.../src/test}/resources/ProxyableFactory.java | 0
.../ProxyableInvocationHandler.clazz | Bin
.../resources/ProxyableInvocationHandler.java | 0
jetty-core/jetty-slf4j-impl/pom.xml | 6 +-
.../src/main/java/module-info.java | 0
jetty-core/jetty-start/pom.xml | 6 +-
.../org/eclipse/jetty/start/BaseBuilder.java | 4 +-
.../org/eclipse/jetty/start/Classpath.java | 8 +-
.../org/eclipse/jetty/start/Environment.java | 295 +
.../java/org/eclipse/jetty/start/Main.java | 137 +-
.../java/org/eclipse/jetty/start/Module.java | 24 +-
.../jetty/start/ModuleGraphWriter.java | 18 +-
.../java/org/eclipse/jetty/start/Modules.java | 45 +-
.../org/eclipse/jetty/start/StartArgs.java | 915 +-
.../org/eclipse/jetty/start/package-info.java | 0
.../jetty/start/IncludeJettyDirTest.java | 2 +-
.../org/eclipse/jetty/start/MainTest.java | 57 +-
.../jetty/start/ModuleGraphWriterTest.java | 52 +-
.../org/eclipse/jetty/start/ModulesTest.java | 11 +-
.../org/eclipse/jetty/start/PropertyDump.java | 2 +
.../jetty/start/usecases/AbstractUseCase.java | 18 +-
.../jetty/start/usecases/BasicTest.java | 6 +-
.../start/usecases/EnvironmentsTest.java | 124 +
.../test/resources/dist-home/modules/base.mod | 0
.../src/test/resources/dist-home/start.ini | 0
.../src/test/resources/empty.home/start.ini | 0
.../extra-jetty-dirs/logging/start.ini | 0
.../test/resources/hb.1/base/start.d/jmx.ini | 0
.../resources/hb.1/base/start.d/logging.ini | 0
.../src/test/resources/hb.1/base/start.ini | 0
.../test/resources/hb.1/home/start.d/jmx.ini | 0
.../resources/hb.1/home/start.d/logging.ini | 0
.../src/test/resources/hb.1/home/start.ini | 0
.../lib/example of a library with spaces.jar | 0
.../jetty home with spaces/modules/base.mod | 0
.../jetty home with spaces/start.ini | 0
.../usecases/minimal-start-ini/start.ini | 0
jetty-core/jetty-unixdomain-server/pom.xml | 6 +-
.../src/main/java/module-info.java | 0
.../unixdomain/server/UnixDomainTest.java | 34 +-
jetty-core/jetty-util-ajax/pom.xml | 11 +-
.../src/main/java/module-info.java | 0
.../eclipse/jetty/util/ajax/package-info.java | 0
jetty-core/jetty-util/pom.xml | 8 +-
.../src/main/java/module-info.java | 0
.../eclipse/jetty/util/ArrayTernaryTrie.java | 6 +-
.../org/eclipse/jetty/util/ArrayTrie.java | 2 +-
.../org/eclipse/jetty/util/Attributes.java | 411 +-
.../org/eclipse/jetty/util/AttributesMap.java | 44 +-
.../java/org/eclipse/jetty/util/Blocking.java | 377 +
.../java/org/eclipse/jetty/util/Callback.java | 8 +-
.../jetty/util/CharsetStringBuilder.java | 155 +
.../java/org/eclipse/jetty/util/Fields.java | 128 +-
.../eclipse/jetty/util/FutureCallback.java | 9 +-
.../org/eclipse/jetty/util/FuturePromise.java | 9 +-
.../main/java/org/eclipse/jetty/util/IO.java | 14 +
.../jetty/util/IteratingCallback_State.puml | 35 +
.../java/org/eclipse/jetty/util/MultiMap.java | 16 +-
.../jetty/util/SharedBlockingCallback.java | 14 +-
.../org/eclipse/jetty/util/StringUtil.java | 14 +
.../java/org/eclipse/jetty/util/TreeTrie.java | 10 +-
.../java/org/eclipse/jetty/util/TypeUtil.java | 58 +
.../java/org/eclipse/jetty/util/URIUtil.java | 308 +-
.../org/eclipse/jetty/util/UrlEncoded.java | 88 +-
.../eclipse/jetty/util/Utf8Appendable.java | 8 +-
.../eclipse/jetty/util/Utf8StringBuffer.java | 22 +
.../eclipse/jetty/util/Utf8StringBuilder.java | 22 +
.../jetty/util/annotation/package-info.java | 0
.../util/component/AbstractLifeCycle.java | 6 +-
.../util/component/AttributeContainerMap.java | 17 +-
.../jetty/util/component/Dumpable.java | 5 +-
.../jetty/util/component/Environment.java | 49 +
.../jetty/util/component/package-info.java | 0
.../org/eclipse/jetty/util/package-info.java | 0
.../jetty/util/preventers/package-info.java | 0
.../jetty/util/resource/PathCollators.java | 113 +
.../eclipse/jetty/util/resource/Resource.java | 13 +
.../util/resource/ResourceCollators.java | 1 +
.../jetty/util/resource/ResourceFactory.java | 1 +
.../jetty/util/resource/package-info.java | 0
.../eclipse/jetty/util/security/Password.java | 2 +-
.../jetty/util/security/package-info.java | 0
.../eclipse/jetty/util/ssl/package-info.java | 0
.../jetty/util/statistic/package-info.java | 0
.../eclipse/jetty/util/thread/Invocable.java | 25 +-
.../util/thread/ReservedThreadExecutor.java | 7 +-
.../jetty/util/thread/SerializedExecutor.java | 109 +-
.../jetty/util/thread/SerializedInvoker.java | 155 +
.../jetty/util/thread/package-info.java | 0
.../strategy/AdaptiveExecutionStrategy.java | 2 +-
.../eclipse/jetty/util/AttributesTest.java | 138 +
.../org/eclipse/jetty/util/BlockingTest.java | 416 +
.../jetty/util/CharsetStringBuilderTest.java | 59 +
.../org/eclipse/jetty/util/FieldsTest.java | 85 +
.../util/SharedBlockingCallbackTest.java | 1 +
.../org/eclipse/jetty/util/URIUtilTest.java | 52 +-
.../component/ContainerLifeCycleTest.java | 142 +-
.../LifeCycleListenerNestedTest.java | 284 +
.../util/thread/SerializedExecutorTest.java | 121 +-
.../util/thread/SerializedInvokerTest.java | 150 +
.../src/test/resources/TestData/test/alphabet | 0
.../src/test/resources/TestData/test/numbers | 0
.../resources/TestData/test/subdir/alphabet | 0
.../resources/TestData/test/subdir/numbers | 0
.../TestData/test/subdir/subsubdir/alphabet | 0
.../TestData/test/subdir/subsubdir/numbers | 0
.../org/eclipse/jetty/util/resource/four/four | 0
.../org/eclipse/jetty/util/resource/one/1.txt | 0
.../eclipse/jetty/util/resource/one/dir/1.txt | 0
.../eclipse/jetty/util/resource/resource.txt | 0
.../eclipse/jetty/util/resource/three/2.txt | 0
.../eclipse/jetty/util/resource/three/3.txt | 0
.../jetty/util/resource/three/dir/3.txt | 0
.../org/eclipse/jetty/util/resource/two/1.txt | 0
.../org/eclipse/jetty/util/resource/two/2.txt | 0
.../eclipse/jetty/util/resource/two/dir/2.txt | 0
.../src/test/resources/resource.txt | 0
jetty-core/jetty-websocket/pom.xml | 42 +-
.../websocket-core-client/pom.xml | 6 +-
.../src/main/java/module-info.java | 0
.../websocket-core-common/pom.xml | 6 +-
.../src/main/java/module-info.java | 36 +-
.../core/internal/NullAppendable.java | 6 +
.../websocket-core-server/pom.xml | 10 +-
.../src/main/java/module-info.java | 0
.../websocket/core/server/Handshaker.java | 7 +-
.../core/server/ServerUpgradeRequest.java | 357 +-
.../core/server/ServerUpgradeResponse.java | 144 +-
.../core/server/WebSocketCreator.java | 6 +-
.../core/server/WebSocketMappings.java | 55 +-
.../core/server/WebSocketNegotiation.java | 41 +-
.../server/WebSocketServerComponents.java | 36 +-
.../core/server/WebSocketUpgradeHandler.java | 68 +-
.../server/internal/AbstractHandshaker.java | 101 +-
.../server/internal/CreatorNegotiator.java | 32 +-
.../server/internal/HandshakerSelector.java | 11 +-
.../server/internal/HttpFieldsWrapper.java | 113 +
.../server/internal/RFC6455Handshaker.java | 38 +-
.../server/internal/RFC6455Negotiation.java | 10 +-
.../server/internal/RFC8441Handshaker.java | 34 +-
.../server/internal/RFC8441Negotiation.java | 10 +-
.../internal/WebSocketHttpFieldsWrapper.java | 88 +
.../websocket-core-tests}/fuzzingclient.json | 0
.../websocket-core-tests}/fuzzingserver.json | 0
.../websocket-core-tests/pom.xml | 66 +-
.../websocket/core/WebSocketEchoTest.java | 89 +
.../core/WebSocketNegotiationTest.java | 4 +-
.../core/WebSocketServerComponentsTest.java | 45 +-
.../core/autobahn}/AutobahnFrameHandler.java | 3 +-
.../core/autobahn/AutobahnTests.java | 113 +-
.../core/autobahn}/CoreAutobahnClient.java | 60 +-
.../core/autobahn}/CoreAutobahnServer.java | 40 +-
.../core/chat/ChatWebSocketServer.java | 15 +-
.../PermessageDeflateDemandTest.java | 1 -
.../core/proxy/WebSocketProxyTest.java | 22 +-
.../test/resources/jetty-logging.properties | 23 +-
jetty-core/jetty-xml/pom.xml | 6 +-
.../jetty-xml}/src/main/java/module-info.java | 0
.../eclipse/jetty/xml/XmlConfiguration.java | 2 +-
.../org/eclipse/jetty/xml/package-info.java | 0
jetty-core/pom.xml | 58 +
.../deploy/bindings/DebugListenerBinding.java | 48 -
.../bindings/GlobalWebappConfigBinding.java | 113 -
.../providers/jmx/WebAppProviderMBean.java | 39 -
.../jetty/deploy/BadAppDeployTest.java | 167 -
.../jetty/deploy/DeploymentTempDirTest.java | 235 -
.../GlobalWebappConfigBindingTest.java | 105 -
.../deploy/providers/WebAppProviderTest.java | 259 -
.../jetty-ee9-annotations}/pom.xml | 22 +-
.../src/main/java/module-info.java | 15 +-
...AbstractDiscoverableAnnotationHandler.java | 9 +-
.../annotations/AnnotationConfiguration.java | 39 +-
.../ee9/annotations/AnnotationDecorator.java | 4 +-
.../annotations/AnnotationIntrospector.java | 10 +-
.../ee9/annotations/AnnotationParser.java | 2 +-
.../annotations/ClassInheritanceHandler.java | 8 +-
...ContainerInitializerAnnotationHandler.java | 24 +-
.../DeclareRolesAnnotationHandler.java | 10 +-
.../MultiPartConfigAnnotationHandler.java | 12 +-
.../PostConstructAnnotationHandler.java | 14 +-
.../PreDestroyAnnotationHandler.java | 14 +-
.../ResourceAnnotationHandler.java | 29 +-
.../ResourcesAnnotationHandler.java | 11 +-
.../annotations/RunAsAnnotationHandler.java | 12 +-
.../ServletContainerInitializersStarter.java | 8 +-
.../ServletSecurityAnnotationHandler.java | 16 +-
.../ee9/annotations/WebFilterAnnotation.java | 16 +-
.../WebFilterAnnotationHandler.java | 13 +-
.../annotations/WebListenerAnnotation.java | 14 +-
.../WebListenerAnnotationHandler.java | 13 +-
.../ee9/annotations/WebServletAnnotation.java | 16 +-
.../WebServletAnnotationHandler.java | 13 +-
.../jetty/ee9}/annotations/package-info.java | 2 +-
...org.eclipse.jetty.ee9.webapp.Configuration | 1 +
.../eclipse/jetty/ee9/annotations/ClassA.java | 2 +-
.../eclipse/jetty/ee9/annotations/ClassB.java | 2 +-
.../jetty/ee9/annotations/FilterC.java | 2 +-
.../jetty/ee9/annotations/InterfaceD.java | 2 +-
.../jetty/ee9/annotations/ListenerC.java | 2 +-
.../eclipse/jetty/ee9/annotations/Multi.java | 2 +-
.../eclipse/jetty/ee9/annotations/Sample.java | 2 +-
.../jetty/ee9/annotations/ServletC.java | 2 +-
.../jetty/ee9/annotations/ServletD.java | 2 +-
.../jetty/ee9/annotations/ServletE.java | 2 +-
.../TestAnnotationConfiguration.java | 8 +-
.../annotations/TestAnnotationDecorator.java | 14 +-
.../TestAnnotationInheritance.java | 14 +-
.../TestAnnotationIntrospector.java | 12 +-
.../ee9/annotations/TestAnnotationParser.java | 34 +-
...eredServletContainerInitializerHolder.java | 9 +-
.../ee9/annotations/TestRunAsAnnotation.java | 8 +-
.../TestSecurityAnnotationConversions.java | 14 +-
.../annotations/TestServletAnnotations.java | 12 +-
.../ee9/annotations/resources/ResourceA.java | 2 +-
.../ee9/annotations/resources/ResourceB.java | 2 +-
.../resources/TestResourceAnnotations.java | 23 +-
.../jetty-ee9-ant}/pom.xml | 36 +-
.../ee9/ant/AntMetaInfConfiguration.java | 8 +-
.../jetty/ee9/ant/AntWebAppContext.java | 30 +-
.../jetty/ee9/ant/AntWebInfConfiguration.java | 12 +-
.../jetty/ee9/ant/AntWebXmlConfiguration.java | 6 +-
.../eclipse/jetty/ee9/ant/JettyRunTask.java | 18 +-
.../eclipse/jetty/ee9/ant/JettyStopTask.java | 4 +-
.../jetty/ee9/ant/ServerProxyImpl.java | 12 +-
.../eclipse/jetty/ee9}/ant/package-info.java | 2 +-
.../jetty/ee9/ant/types/Attribute.java | 2 +-
.../jetty/ee9/ant/types/Attributes.java | 2 +-
.../jetty/ee9/ant/types/Connector.java | 2 +-
.../jetty/ee9/ant/types/Connectors.java | 2 +-
.../jetty/ee9/ant/types/ContextHandlers.java | 2 +-
.../ant/types/FileMatchingConfiguration.java | 2 +-
.../jetty/ee9/ant/types/LoginServices.java | 4 +-
.../jetty/ee9/ant/types/SystemProperties.java | 4 +-
.../jetty/ee9}/ant/types/package-info.java | 2 +-
.../jetty/ee9/ant/utils/ServerProxy.java | 4 +-
.../eclipse/jetty/ee9/ant/utils/TaskLog.java | 2 +-
.../jetty/ee9}/ant/utils/package-info.java | 2 +-
.../org.eclipse.jetty.webapp.Configuration | 4 +-
.../src/main/resources/tasks.properties | 4 +-
.../org/eclipse/jetty/ee9/ant/AntBuild.java | 2 +-
.../jetty/ee9/ant/JettyAntTaskTest.java | 2 +-
.../src/test/resources/connector-test.xml | 2 +-
.../src/test/resources/foo/index.html | 0
.../src/test/resources/foo/jsp/index.html | 0
.../src/test/resources/webapp-test.xml | 2 +-
.../jetty-ee9-apache-jsp}/pom.xml | 26 +-
.../src/main/config/modules/apache-jsp.mod | 0
.../src/main/java/module-info.java | 10 +-
.../apache/jsp/JettyJasperInitializer.java | 2 +-
.../ee9}/apache/jsp/JettyTldPreScanned.java | 2 +-
.../jetty/ee9}/apache/jsp/JuliLog.java | 2 +-
.../jetty/ee9}/jsp/JettyJspServlet.java | 2 +-
...akarta.servlet.ServletContainerInitializer | 1 +
.../services/org.apache.juli.logging.Log | 1 +
.../jetty/ee9}/jsp/TestJettyJspServlet.java | 6 +-
.../ee9}/jsp/TestJettyTldPreScanned.java | 6 +-
.../ee9}/jsp/TestJspFileNameToClass.java | 4 +-
.../test/resources/META-INF/foo-taglib.tld | 0
.../src/test/resources/base/dir/empty.txt | 0
.../src/test/resources/base/foo.jsp | 0
.../src/test/resources/taglib.jar | Bin
jetty-ee9/jetty-ee9-bom/pom.xml | 214 +
.../jetty-ee9-cdi}/pom.xml | 23 +-
.../src/main/config/etc/cdi/jetty-cdi.xml | 2 +-
.../src/main/config/modules/cdi.mod | 6 +-
.../src/main/java/module-info.java | 8 +-
.../jetty/ee9/cdi/CdiConfiguration.java | 10 +-
.../jetty/ee9/cdi/CdiDecoratingListener.java | 10 +-
.../cdi/CdiServletContainerInitializer.java | 14 +-
.../jetty/ee9/cdi/CdiSpiDecorator.java | 4 +-
...akarta.servlet.ServletContainerInitializer | 2 +-
.../org.eclipse.jetty.webapp.Configuration | 2 +-
.../demo-ee9-async-rest-jar}/pom.xml | 10 +-
.../jetty/ee9}/demos/AbstractRestServlet.java | 2 +-
.../jetty/ee9}/demos/AsyncRestServlet.java | 2 +-
.../jetty/ee9}/demos/SerialRestServlet.java | 2 +-
.../META-INF/resources/asyncrest.html | 0
.../META-INF/resources/asyncrest/green.png | Bin
.../META-INF/resources/asyncrest/red.png | Bin
.../main/resources/META-INF/web-fragment.xml | 0
.../demo-ee9-async-rest-server}/pom.xml | 14 +-
.../jetty/ee9}/demos/AsyncRestServer.java | 4 +-
.../demo-ee9-async-rest-webapp}/pom.xml | 14 +-
.../main/config/modules/demo-async-rest.mod | 0
.../src/main/webapp/META-INF/MANIFEST.MF | 0
.../src/main/webapp/WEB-INF/jetty-web.xml | 4 +-
.../src/main/webapp/WEB-INF/web.xml | 0
.../src/main/webapp/demo.css | 0
.../src/main/webapp/index.html | 0
.../src/main/webapp/small_powered_by.gif | Bin
.../demo-ee9-async-rest/pom.xml | 19 +
.../demo-ee9-embedded}/pom.xml | 64 +-
.../demo-ee9-embedded}/prodDb.properties | 0
.../demo-ee9-embedded}/prodDb.script | 0
.../jetty/ee9}/demos/AsyncEchoServlet.java | 2 +-
.../eclipse/jetty/ee9}/demos/DumpServlet.java | 2 +-
.../jetty/ee9}/demos/ExampleServer.java | 4 +-
.../jetty/ee9}/demos/ExampleServerXml.java | 2 +-
.../eclipse/jetty/ee9}/demos/ExampleUtil.java | 2 +-
.../jetty/ee9}/demos/FastFileServer.java | 4 +-
.../eclipse/jetty/ee9}/demos/FileServer.java | 4 +-
.../jetty/ee9}/demos/FileServerXml.java | 2 +-
.../jetty/ee9}/demos/HelloHandler.java | 2 +-
.../jetty/ee9}/demos/HelloServlet.java | 2 +-
.../jetty/ee9}/demos/HelloSessionServlet.java | 2 +-
.../eclipse/jetty/ee9}/demos/HelloWorld.java | 2 +-
.../eclipse/jetty/ee9}/demos/Http2Server.java | 13 +-
.../eclipse/jetty/ee9}/demos/JarServer.java | 8 +-
.../eclipse/jetty/ee9}/demos/JettyDemos.java | 2 +-
.../jetty/ee9}/demos/LikeJettyXml.java | 17 +-
.../jetty/ee9}/demos/ManyConnectors.java | 2 +-
.../jetty/ee9}/demos/ManyContexts.java | 2 +-
.../jetty/ee9}/demos/ManyHandlers.java | 2 +-
.../jetty/ee9}/demos/ManyServletContexts.java | 8 +-
.../jetty/ee9}/demos/MinimalServlets.java | 4 +-
.../jetty/ee9}/demos/OneConnector.java | 2 +-
.../eclipse/jetty/ee9}/demos/OneContext.java | 2 +-
.../eclipse/jetty/ee9}/demos/OneHandler.java | 2 +-
.../jetty/ee9}/demos/OneServletContext.java | 10 +-
.../ee9}/demos/OneServletContextJmxStats.java | 6 +-
.../demos/OneServletContextWithSession.java | 12 +-
.../eclipse/jetty/ee9}/demos/OneWebApp.java | 6 +-
.../jetty/ee9}/demos/OneWebAppWithJsp.java | 8 +-
.../eclipse/jetty/ee9}/demos/ProxyServer.java | 10 +-
.../jetty/ee9}/demos/RewriteServer.java | 4 +-
.../jetty/ee9}/demos/SecuredHelloHandler.java | 12 +-
.../ee9}/demos/ServerWithAnnotations.java | 24 +-
.../jetty/ee9}/demos/ServerWithJMX.java | 2 +-
.../jetty/ee9}/demos/ServerWithJNDI.java | 20 +-
.../jetty/ee9}/demos/SimplestServer.java | 2 +-
.../jetty/ee9}/demos/SplitFileServer.java | 2 +-
.../jetty/ee9}/demos/WebSocketServer.java | 18 +-
.../src/main/other/content.jar | Bin
.../main/resources/demo/demo-realm.properties | 2 +-
.../src/main/resources/demo/webdefault.xml | 12 +-
.../src/main/resources/docroot/push.html | 0
.../main/resources/docroot/pushed/tile00.jpg | Bin
.../main/resources/docroot/pushed/tile01.jpg | Bin
.../main/resources/docroot/pushed/tile02.jpg | Bin
.../main/resources/docroot/pushed/tile03.jpg | Bin
.../main/resources/docroot/pushed/tile04.jpg | Bin
.../main/resources/docroot/pushed/tile05.jpg | Bin
.../main/resources/docroot/pushed/tile06.jpg | Bin
.../main/resources/docroot/pushed/tile07.jpg | Bin
.../main/resources/docroot/pushed/tile08.jpg | Bin
.../main/resources/docroot/pushed/tile09.jpg | Bin
.../main/resources/docroot/pushed/tile10.jpg | Bin
.../main/resources/docroot/pushed/tile11.jpg | Bin
.../main/resources/docroot/pushed/tile12.jpg | Bin
.../main/resources/docroot/pushed/tile13.jpg | Bin
.../main/resources/docroot/pushed/tile14.jpg | Bin
.../main/resources/docroot/pushed/tile15.jpg | Bin
.../main/resources/docroot/pushed/tile16.jpg | Bin
.../main/resources/docroot/pushed/tile17.jpg | Bin
.../main/resources/docroot/pushed/tile18.jpg | Bin
.../main/resources/docroot/pushed/tile19.jpg | Bin
.../main/resources/docroot/pushed/tile20.jpg | Bin
.../main/resources/docroot/pushed/tile21.jpg | Bin
.../main/resources/docroot/pushed/tile22.jpg | Bin
.../main/resources/docroot/pushed/tile23.jpg | Bin
.../main/resources/docroot/pushed/tile24.jpg | Bin
.../main/resources/docroot/pushed/tile25.jpg | Bin
.../main/resources/docroot/pushed/tile26.jpg | Bin
.../main/resources/docroot/pushed/tile27.jpg | Bin
.../main/resources/docroot/pushed/tile28.jpg | Bin
.../main/resources/docroot/pushed/tile29.jpg | Bin
.../main/resources/docroot/pushed/tile30.jpg | Bin
.../main/resources/docroot/pushed/tile31.jpg | Bin
.../main/resources/docroot/pushed/tile32.jpg | Bin
.../main/resources/docroot/pushed/tile33.jpg | Bin
.../main/resources/docroot/pushed/tile34.jpg | Bin
.../main/resources/docroot/pushed/tile35.jpg | Bin
.../main/resources/docroot/pushed/tile36.jpg | Bin
.../main/resources/docroot/pushed/tile37.jpg | Bin
.../main/resources/docroot/pushed/tile38.jpg | Bin
.../main/resources/docroot/pushed/tile39.jpg | Bin
.../main/resources/docroot/pushed/tile40.jpg | Bin
.../main/resources/docroot/pushed/tile41.jpg | Bin
.../main/resources/docroot/pushed/tile42.jpg | Bin
.../main/resources/docroot/pushed/tile43.jpg | Bin
.../main/resources/docroot/pushed/tile44.jpg | Bin
.../main/resources/docroot/pushed/tile45.jpg | Bin
.../main/resources/docroot/pushed/tile46.jpg | Bin
.../main/resources/docroot/pushed/tile47.jpg | Bin
.../main/resources/docroot/pushed/tile48.jpg | Bin
.../main/resources/docroot/pushed/tile49.jpg | Bin
.../src/main/resources/docroot/readme.txt | 0
.../main/resources/docroot/tiles/tile00.jpg | Bin
.../main/resources/docroot/tiles/tile01.jpg | Bin
.../main/resources/docroot/tiles/tile02.jpg | Bin
.../main/resources/docroot/tiles/tile03.jpg | Bin
.../main/resources/docroot/tiles/tile04.jpg | Bin
.../main/resources/docroot/tiles/tile05.jpg | Bin
.../main/resources/docroot/tiles/tile06.jpg | Bin
.../main/resources/docroot/tiles/tile07.jpg | Bin
.../main/resources/docroot/tiles/tile08.jpg | Bin
.../main/resources/docroot/tiles/tile09.jpg | Bin
.../main/resources/docroot/tiles/tile10.jpg | Bin
.../main/resources/docroot/tiles/tile11.jpg | Bin
.../main/resources/docroot/tiles/tile12.jpg | Bin
.../main/resources/docroot/tiles/tile13.jpg | Bin
.../main/resources/docroot/tiles/tile14.jpg | Bin
.../main/resources/docroot/tiles/tile15.jpg | Bin
.../main/resources/docroot/tiles/tile16.jpg | Bin
.../main/resources/docroot/tiles/tile17.jpg | Bin
.../main/resources/docroot/tiles/tile18.jpg | Bin
.../main/resources/docroot/tiles/tile19.jpg | Bin
.../main/resources/docroot/tiles/tile20.jpg | Bin
.../main/resources/docroot/tiles/tile21.jpg | Bin
.../main/resources/docroot/tiles/tile22.jpg | Bin
.../main/resources/docroot/tiles/tile23.jpg | Bin
.../main/resources/docroot/tiles/tile24.jpg | Bin
.../main/resources/docroot/tiles/tile25.jpg | Bin
.../main/resources/docroot/tiles/tile26.jpg | Bin
.../main/resources/docroot/tiles/tile27.jpg | Bin
.../main/resources/docroot/tiles/tile28.jpg | Bin
.../main/resources/docroot/tiles/tile29.jpg | Bin
.../main/resources/docroot/tiles/tile30.jpg | Bin
.../main/resources/docroot/tiles/tile31.jpg | Bin
.../main/resources/docroot/tiles/tile32.jpg | Bin
.../main/resources/docroot/tiles/tile33.jpg | Bin
.../main/resources/docroot/tiles/tile34.jpg | Bin
.../main/resources/docroot/tiles/tile35.jpg | Bin
.../main/resources/docroot/tiles/tile36.jpg | Bin
.../main/resources/docroot/tiles/tile37.jpg | Bin
.../main/resources/docroot/tiles/tile38.jpg | Bin
.../main/resources/docroot/tiles/tile39.jpg | Bin
.../main/resources/docroot/tiles/tile40.jpg | Bin
.../main/resources/docroot/tiles/tile41.jpg | Bin
.../main/resources/docroot/tiles/tile42.jpg | Bin
.../main/resources/docroot/tiles/tile43.jpg | Bin
.../main/resources/docroot/tiles/tile44.jpg | Bin
.../main/resources/docroot/tiles/tile45.jpg | Bin
.../main/resources/docroot/tiles/tile46.jpg | Bin
.../main/resources/docroot/tiles/tile47.jpg | Bin
.../main/resources/docroot/tiles/tile48.jpg | Bin
.../main/resources/docroot/tiles/tile49.jpg | Bin
.../src/main/resources/etc/keystore.p12 | Bin
.../src/main/resources/etc/realm.properties | 0
.../src/main/resources/exampleserver.xml | 2 +-
.../src/main/resources/fileserver.xml | 0
.../resources/java-util-logging.properties | 0
.../main/resources/jetty-logging.properties | 2 +-
.../src/main/resources/logback-access.xml | 0
.../ee9}/demos/AbstractEmbeddedTest.java | 2 +-
.../jetty/ee9}/demos/ExampleServerTest.java | 2 +-
.../ee9}/demos/ExampleServerXmlTest.java | 2 +-
.../jetty/ee9}/demos/FastFileServerTest.java | 2 +-
.../jetty/ee9}/demos/FileServerTest.java | 2 +-
.../jetty/ee9}/demos/FileServerXmlTest.java | 2 +-
.../jetty/ee9}/demos/JarServerTest.java | 2 +-
.../jetty/ee9}/demos/LikeJettyXmlTest.java | 2 +-
.../jetty/ee9}/demos/ManyConnectorsTest.java | 2 +-
.../jetty/ee9}/demos/ManyContextsTest.java | 2 +-
.../jetty/ee9}/demos/ManyHandlersTest.java | 2 +-
.../ee9}/demos/ManyServletContextsTest.java | 2 +-
.../jetty/ee9}/demos/MinimalServletsTest.java | 2 +-
.../jetty/ee9}/demos/OneConnectorTest.java | 2 +-
.../jetty/ee9}/demos/OneContextTest.java | 2 +-
.../jetty/ee9}/demos/OneHandlerTest.java | 2 +-
.../demos/OneServletContextJmxStatsTest.java | 2 +-
.../ee9}/demos/OneServletContextTest.java | 2 +-
.../OneServletContextWithSessionTest.java | 2 +-
.../jetty/ee9}/demos/OneWebAppTest.java | 2 +-
.../ee9}/demos/OneWebAppWithJspTest.java | 2 +-
.../jetty/ee9}/demos/ProxyServerTest.java | 2 +-
.../jetty/ee9}/demos/RewriteServerTest.java | 2 +-
.../ee9}/demos/SecuredHelloHandlerTest.java | 2 +-
.../eclipse/jetty/ee9}/demos/ServerUtil.java | 2 +-
.../ee9}/demos/ServerWithAnnotationsTest.java | 2 +-
.../jetty/ee9}/demos/ServerWithJMXTest.java | 2 +-
.../jetty/ee9}/demos/ServerWithJNDITest.java | 2 +-
.../jetty/ee9}/demos/SimplestServerTest.java | 2 +-
.../jetty/ee9}/demos/SplitFileServerTest.java | 2 +-
.../jetty/ee9}/demos/WebSocketServerTest.java | 16 +-
.../src/test/resources/dir0/test0.txt | 0
.../src/test/resources/dir1/test1.txt | 0
.../test/resources/jetty-logging.properties | 2 +-
.../src/test/resources}/realm.properties | 0
.../demo-ee9-jaas-webapp}/pom.xml | 12 +-
.../src/main/config/modules/demo-jaas.mod | 0
.../main/config/modules/demo.d/demo-jaas.xml | 2 +-
.../config/modules/demo.d/demo-login.conf | 0
.../modules/demo.d/demo-login.properties | 0
.../src/main/webapp/WEB-INF/jetty-web.xml | 2 +-
.../src/main/webapp/WEB-INF/web.xml | 0
.../src/main/webapp/auth.html | 0
.../src/main/webapp/authfail.html | 0
.../src/main/webapp/demo.css | 0
.../src/main/webapp/index.html | 0
.../src/main/webapp/login.html | 0
.../src/main/webapp/logout.jsp | 0
.../src/main/webapp/small_powered_by.gif | Bin
.../src/main/webapp/stylesheet.css | 0
.../demo-ee9-jetty-webapp}/jetty-chat.jmx | 0
.../demo-ee9-jetty-webapp}/pom.xml | 33 +-
.../embedded-jetty-web-for-webbundle.xml | 2 +-
.../src/main/assembly/web-bundle.xml | 0
.../src/main/config/modules/demo-jetty.mod | 0
.../config/modules/demo-moved-context.mod | 0
.../src/main/config/modules/demo-rewrite.mod | 0
.../demo.d/demo-jetty-override-web.xml | 4 +-
.../main/config/modules/demo.d/demo-jetty.xml | 2 +-
.../modules/demo.d/demo-moved-context.xml | 0
.../modules/demo.d/demo-rewrite-rules.xml | 0
.../AddListServletRequestListener.java | 2 +-
.../main/java/org/example}/ChatServlet.java | 2 +-
.../main/java/org/example}/CookieDump.java | 2 +-
.../java/org/example}/DispatchServlet.java | 2 +-
.../src/main/java/org/example}/Dump.java | 4 +-
.../main/java/org/example}/HelloWorld.java | 2 +-
.../org/example}/JakartaWebSocketChat.java | 2 +-
.../main/java/org/example}/LoginServlet.java | 2 +-
.../src/main/java/org/example}/RegTest.java | 2 +-
.../java/org/example}/RewriteServlet.java | 2 +-
.../java/org/example}/SecureModeServlet.java | 2 +-
.../main/java/org/example}/SessionDump.java | 2 +-
.../main/java/org/example}/TestFilter.java | 2 +-
.../main/java/org/example}/TestListener.java | 2 +-
.../main/java/org/example}/TestServlet.java | 2 +-
.../org/example}/WebSocketChatServlet.java | 24 +-
.../src/main/webapp/WEB-INF/jetty-web.xml | 6 +-
.../src/main/webapp/WEB-INF/web.xml | 30 +-
.../src/main/webapp/auth.html | 0
.../src/main/webapp/auth/file.txt | 0
.../src/main/webapp/auth/relax.txt | 0
.../src/main/webapp/auth2/index.html | 0
.../src/main/webapp/cgi-bin/hello.sh | 0
.../src/main/webapp/chat/index.html | 0
.../src/main/webapp/d.txt | 0
.../src/main/webapp/da.txt | 0
.../src/main/webapp/da.txt.gz | Bin
.../src/main/webapp/dat.txt | 0
.../src/main/webapp/data.txt | 0
.../src/main/webapp/data.txt.gz | Bin
.../src/main/webapp/demo.css | 0
.../src/main/webapp/error404.html | 0
.../src/main/webapp/favicon.ico | Bin
.../src/main/webapp/index.html | 0
.../main/webapp/jakarta.websocket/index.html | 0
.../src/main/webapp/logon.html | 0
.../src/main/webapp/logonError.html | 0
.../src/main/webapp/remote.html | 0
.../src/main/webapp/rewrite/index.html | 0
.../src/main/webapp/rewrite/info.html | 0
.../src/main/webapp/small_powered_by.gif | Bin
.../src/main/webapp/ws/index.html | 0
.../eclipse/jetty/ee9}/ChatServletTest.java | 6 +-
.../jetty/ee9}/DispatchServletTest.java | 14 +-
.../org/eclipse/jetty/ee9}/TestServer.java | 12 +-
.../test/resources/jetty-logging.properties | 3 +
.../src/test/resources/test-realm.properties | 2 +-
.../demo-ee9-jndi-webapp}/pom.xml | 20 +-
.../src/main/config/modules/demo-jndi.mod | 0
.../main/config/modules/demo.d/demo-jndi.xml | 6 +-
.../src/main/java/org/example}/JNDITest.java | 2 +-
.../src/main/templates/env-definitions.xml | 2 +-
.../main/templates/jetty-test-jndi-header.xml | 4 +-
.../main/templates/plugin-context-header.xml | 4 +-
.../src/main/webapp/WEB-INF/jetty-env.xml | 2 +-
.../src/main/webapp/WEB-INF/jetty-web.xml | 2 +-
.../src/main/webapp/WEB-INF/web.xml | 10 +-
.../src/main/webapp/demo.css | 0
.../src/main/webapp/index.html | 0
.../src/main/webapp/small_powered_by.gif | Bin
.../src/main/webapp/stylesheet.css | 0
.../demo-ee9-jsp-webapp}/pom.xml | 14 +-
.../src/main/assembly/web-bundle.xml | 0
.../src/main/config/modules/demo-jsp.mod | 0
.../src/main/java/org/example}/Counter.java | 2 +-
.../src/main/java/org/example}/Date2Tag.java | 2 +-
.../src/main/java/org/example}/DateTag.java | 2 +-
.../main/java/org/example}/TagListener.java | 2 +-
.../src/main/webapp/WEB-INF/acme-taglib.tld | 4 +-
.../src/main/webapp/WEB-INF/acme-taglib2.tld | 2 +-
.../src/main/webapp/WEB-INF/jetty-web.xml | 2 +-
.../src/main/webapp/WEB-INF/tags/panel.tag | 0
.../src/main/webapp/WEB-INF/web.xml | 0
.../src/main/webapp/bean1.jsp | 2 +-
.../src/main/webapp/bean2.jsp | 2 +-
.../src/main/webapp/demo.css | 0
.../src/main/webapp/dump.jsp | 0
.../src/main/webapp/expr.jsp | 0
.../src/main/webapp/foo/foo.jsp | 0
.../src/main/webapp/index.jsp | 0
.../src/main/webapp/jstl.jsp | 0
.../src/main/webapp/small_powered_by.gif | Bin
.../src/main/webapp/tag.jsp | 0
.../src/main/webapp/tag2.jsp | 0
.../src/main/webapp/tagfile.jsp | 0
.../demo-ee9-mock-resources}/pom.xml | 14 +-
.../config/modules/demo-mock-resources.mod | 0
.../java/org/example}/MockDataSource.java | 2 +-
.../main/java/org/example}/MockTransport.java | 2 +-
.../org/example}/MockUserTransaction.java | 2 +-
.../resources/META-INF/javaxmail.providers | 1 +
.../demo-ee9-proxy-webapp}/pom.xml | 22 +-
.../src/main/config/modules/demo-proxy.mod | 0
.../src/main/webapp/META-INF/MANIFEST.MF | 0
.../src/main/webapp/WEB-INF/jetty-web.xml | 2 +-
.../src/main/webapp/WEB-INF/web.xml | 0
.../jetty/ee9}/demos/ProxyWebAppTest.java | 4 +-
.../test/resources/jetty-logging.properties | 0
.../demo-ee9-simple-webapp}/pom.xml | 10 +-
.../src/main/config/modules/demo-simple.mod | 0
.../src/main/webapp/WEB-INF/web.xml | 0
.../src/main/webapp/index.html | 0
.../src/main/webapp/jetty.icon | Bin
.../src/main/webapp/jetty.png | Bin
.../src/main/webapp/jetty.webp | Bin
.../demo-ee9-container-initializer}/pom.xml | 14 +-
.../java/org/example}/initializer/Foo.java | 2 +-
.../example}/initializer/FooInitializer.java | 22 +-
...akarta.servlet.ServletContainerInitializer | 1 +
.../demo-ee9-spec-webapp}/pom.xml | 30 +-
.../src/etc}/realm.properties | 2 +-
.../src/main/assembly/web-bundle.xml | 0
.../src/main/config/modules/demo-spec.mod | 0
.../main/config/modules/demo.d/demo-spec.xml | 6 +-
.../org/example}/test/AnnotatedListener.java | 10 +-
.../org/example}/test/AnnotationTest.java | 54 +-
.../example}/test/AsyncListenerServlet.java | 2 +-
.../src/main/java/org/example}/test/Bar.java | 4 +-
.../org/example}/test/ClassLoaderServlet.java | 2 +-
.../java/org/example}/test/MultiPartTest.java | 2 +-
.../org/example}/test/RoleAnnotationTest.java | 2 +-
.../org/example}/test/SecuredServlet.java | 2 +-
.../java/org/example}/test/TestListener.java | 24 +-
.../templates/annotations-context-header.xml | 4 +-
.../src/main/templates/env-definitions.xml | 2 +-
.../main/templates/plugin-context-header.xml | 4 +-
.../src/main/webapp/WEB-INF/jetty-env.xml | 2 +-
.../src/main/webapp/WEB-INF/jetty-web.xml | 2 +-
.../src/main/webapp/WEB-INF/web.xml | 8 +-
.../src/main/webapp/authfail.html | 0
.../src/main/webapp/demo.css | 0
.../src/main/webapp/dynamic.jsp | 0
.../src/main/webapp/index.html | 0
.../src/main/webapp/login.html | 0
.../src/main/webapp/logout.jsp | 0
.../src/main/webapp/small_powered_by.gif | Bin
.../src/main/webapp/stylesheet.css | 0
.../src/test/jetty-plugin-env.xml | 6 +-
.../demo-ee9-web-fragment}/pom.xml | 10 +-
.../example}/fragment/FragmentServlet.java | 2 +-
.../META-INF/resources/fragmentA/index.html | 0
.../main/resources/META-INF/web-fragment.xml | 4 +-
.../jetty-ee9-demos/demo-ee9-spec}/pom.xml | 16 +-
.../demo-ee9-template}/pom.xml | 10 +-
.../src/main/resources/demo.css | 0
.../src/main/resources/index.html | 0
.../src/main/resources/small_powered_by.gif | Bin
{demos => jetty-ee9/jetty-ee9-demos}/pom.xml | 35 +-
jetty-ee9/jetty-ee9-fcgi-server-proxy/pom.xml | 51 +
.../src/main/java/module-info.java | 19 +
.../server/proxy/FastCGIProxyServlet.java | 8 +-
.../fcgi/server/proxy/TryFilesFilter.java | 2 +-
.../proxy/DrupalHTTP2FastCGIProxyServer.java | 7 +-
.../server/proxy/FastCGIProxyServletTest.java | 6 +-
.../fcgi/server/proxy/TryFilesFilterTest.java | 7 +-
.../WordPressHTTP2FastCGIProxyServer.java | 10 +-
.../jetty-ee9-glassfish-jstl}/pom.xml | 30 +-
.../main/config/modules/glassfish-jstl.mod | 0
.../src/main/resources/readme.txt | 0
.../eclipse/jetty/ee9}/jstl/JspConfig.java | 4 +-
.../jetty/ee9}/jstl/JspIncludeTest.java | 10 +-
.../org/eclipse/jetty/ee9}/jstl/JstlTest.java | 6 +-
.../test/resources/jetty-logging.properties | 0
.../src/test/taglibjar/META-INF/etag.tld | 0
.../taglibjar/META-INF/tags/errorhandler.tag | 0
.../src/test/webapp/WEB-INF/web.xml | 0
.../src/test/webapp/catch-basic.jsp | 0
.../src/test/webapp/catch-taglib.jsp | 0
.../src/test/webapp/included.jsp | 0
.../src/test/webapp/ref.jsp | 0
.../src/test/webapp/top.jsp | 0
.../src/test/webapp/urls.jsp | 0
.../jetty-ee9-jaas}/pom.xml | 15 +-
.../src/main/java/module-info.java | 10 +-
.../jetty/ee9/jaas/JAASLoginService.java | 20 +-
.../eclipse/jetty/ee9/jaas/JAASPrincipal.java | 2 +-
.../org/eclipse/jetty/ee9/jaas/JAASRole.java | 2 +-
.../jetty/ee9/jaas/JAASUserPrincipal.java | 2 +-
.../ee9/jaas/PropertyUserStoreManager.java | 4 +-
.../callback/AbstractCallbackHandler.java | 2 +-
.../jaas/callback/DefaultCallbackHandler.java | 8 +-
.../ee9/jaas/callback/ObjectCallback.java | 2 +-
.../callback/RequestParameterCallback.java | 2 +-
.../jaas/callback/ServletRequestCallback.java | 2 +-
.../ee9}/jaas/callback/package-info.java | 2 +-
.../eclipse/jetty/ee9}/jaas/package-info.java | 2 +-
.../jaas/spi/AbstractDatabaseLoginModule.java | 4 +-
.../ee9/jaas/spi/AbstractLoginModule.java | 8 +-
.../ee9/jaas/spi/DataSourceLoginModule.java | 2 +-
.../jetty/ee9/jaas/spi/JDBCLoginModule.java | 2 +-
.../jetty/ee9/jaas/spi/LdapLoginModule.java | 6 +-
.../ee9/jaas/spi/PropertyFileLoginModule.java | 12 +-
.../jetty/ee9}/jaas/spi/package-info.java | 2 +-
.../ee9/jaas/JAASLdapLoginServiceTest.java | 181 +-
.../jetty/ee9/jaas/JAASLoginServiceTest.java | 26 +-
.../jetty/ee9/jaas/TestLoginModule.java | 8 +-
.../jaas/spi/PropertyFileLoginModuleTest.java | 28 +-
.../jetty-ee9-jaspi}/pom.xml | 14 +-
.../src/main/java/module-info.java | 16 +-
.../jaspi/DefaultAuthConfigFactory.java | 2 +-
.../security/jaspi/JaspiAuthenticator.java | 24 +-
.../jaspi/JaspiAuthenticatorFactory.java | 12 +-
.../ee9/security/jaspi/JaspiMessageInfo.java | 2 +-
.../jaspi/ServletCallbackHandler.java | 12 +-
.../ee9}/security/jaspi/SimpleAuthConfig.java | 2 +-
.../CredentialValidationCallback.java | 2 +-
.../security/jaspi/callback/package-info.java | 2 +-
.../jaspi/modules/BaseAuthModule.java | 8 +-
.../BasicAuthenticationAuthModule.java | 2 +-
.../security/jaspi/modules/package-info.java | 2 +-
.../ee9}/security/jaspi/package-info.java | 2 +-
.../provider/JaspiAuthConfigProvider.java | 4 +-
.../jaspi/provider/SimpleAuthConfig.java | 2 +-
.../provider/SimpleServerAuthContext.java | 2 +-
.../jaspi/DefaultAuthConfigFactoryTest.java | 4 +-
.../security/jaspi/HttpHeaderAuthModule.java | 2 +-
.../jetty/ee9/security/jaspi/JaspiTest.java | 12 +-
.../jetty-ee9-jspc-maven-plugin}/pom.xml | 100 +-
.../src/it/package-root/invoker.properties | 0
.../src/it/package-root/pom.xml | 2 +-
.../src/it/package-root/postbuild.groovy | 0
.../it/package-root/src/main/webapp/foo.jsp | 0
.../src/it/simple-jsp-fail/invoker.properties | 0
.../src/it/simple-jsp-fail/pom.xml | 2 +-
.../src/it/simple-jsp-fail/postbuild.groovy | 0
.../it/simple-jsp-fail/src/main/jsp/foo.jsp | 0
.../src/it/simple-jsp/invoker.properties | 0
.../src/it/simple-jsp/pom.xml | 2 +-
.../src/it/simple-jsp/postbuild.groovy | 0
.../src/it/simple-jsp/src/main/webapp/foo.jsp | 0
.../jetty/ee9/jspc/plugin/JspcMojo.java | 2 +-
.../jetty/ee9}/jspc/plugin/package-info.java | 2 +-
.../jetty-ee9-maven-plugin}/pom.xml | 118 +-
.../src/it/it-parent-pom/invoker.properties | 0
.../src/it/it-parent-pom/pom.xml | 2 +-
.../jetty-cdi-start-forked/invoker.properties | 0
.../src/it/jetty-cdi-start-forked/pom.xml | 0
.../jetty-cdi-start-forked/postbuild.groovy | 0
.../src/main/jetty/jetty-context.xml | 6 +-
.../src/main/jetty/jetty.xml | 0
.../api/pom.xml | 0
.../invoker.properties | 0
.../pom.xml | 0
.../postbuild.groovy | 0
.../web/pom.xml | 0
.../web/src/config/jetty.xml | 0
.../MyLibrary/pom.xml | 0
.../MyWebApp/pom.xml | 0
.../MyWebApp}/src/config/context.xml | 2 +-
.../MyWebApp/src/config/jetty.xml | 0
.../MyWebApp/src/main/webapp/index.html | 0
.../invoker.properties | 0
.../src/it/jetty-run-mojo-jar-scan-it/pom.xml | 0
.../postbuild.groovy | 0
.../invoker.properties | 0
.../jetty-simple-base/pom.xml | 2 +-
.../HelloServlet.java | 0
.../PingServlet.java | 0
.../main/resources/META-INF/web-fragment.xml | 0
.../jetty-simple-webapp/pom.xml | 2 +-
.../src/base/etc/test-jetty.xml | 0
.../src/base/modules/testmod.mod | 0
.../src/main/webapp/WEB-INF/web.xml | 0
.../src/it/jetty-start-distro-mojo-it/pom.xml | 2 +-
.../postbuild.groovy | 0
.../invoker.properties | 0
.../jetty-simple-base/pom.xml | 2 +-
.../jetty/its/jetty_start_forked/Counter.java | 0
.../its/jetty_start_forked/HelloServlet.java | 0
.../its/jetty_start_forked/PingServlet.java | 0
.../main/resources/META-INF/web-fragment.xml | 0
.../jetty-simple-webapp/pom.xml | 2 +-
.../jetty-simple-webapp}/src/config/jetty.xml | 0
.../src/main/webapp/WEB-INF/web.xml | 0
.../src/main/webapp/jsp/bean1.jsp | 0
.../src/it/jetty-start-forked-mojo-it/pom.xml | 2 +-
.../postbuild.groovy | 0
.../it/jetty-start-gwt-it/beer-client/pom.xml | 0
.../it/jetty-start-gwt-it/beer-server/pom.xml | 0
.../beer-server}/src/config/jetty.xml | 0
.../src/main/jettyconf/context.xml | 4 +-
.../src/main/webapp/WEB-INF/web.xml | 0
.../beer-server/src/main/webapp/index.html | 0
.../it/jetty-start-gwt-it/beer-shared/pom.xml | 0
.../it/jetty-start-gwt-it/invoker.properties | 0
.../src/it/jetty-start-gwt-it/pom.xml | 0
.../it/jetty-start-gwt-it/postbuild.groovy | 0
.../it/jetty-start-mojo-it/invoker.properties | 0
.../jetty-simple-base/pom.xml | 2 +-
.../its/jetty_start_mojo_it/Counter.java | 0
.../its/jetty_start_mojo_it/HelloServlet.java | 0
.../its/jetty_start_mojo_it/PingServlet.java | 0
.../main/resources/META-INF/web-fragment.xml | 0
.../jetty-simple-webapp/pom.xml | 2 +-
.../src/config/context.xml | 2 +-
.../jetty-simple-webapp}/src/config/jetty.xml | 0
.../src/main/webapp/WEB-INF/web.xml | 0
.../src/main/webapp/jsp/bean1.jsp | 0
.../src/it/jetty-start-mojo-it/pom.xml | 2 +-
.../it/jetty-start-mojo-it/postbuild.groovy | 0
.../common/pom.xml | 0
.../invoker.properties | 0
.../module/module-api/pom.xml | 0
.../module/module-impl/pom.xml | 0
.../module/pom.xml | 0
.../pom.xml | 2 +-
.../postbuild.groovy | 0
.../webapp-war/pom.xml | 0
.../webapp-war}/src/config/jetty.xml | 0
.../src/main/webapp/WEB-INF/web.xml | 0
.../invoker.properties | 0
.../jetty-simple-base/pom.xml | 2 +-
.../its/jetty_run_mojo_it/HelloServlet.java | 0
.../its/jetty_run_mojo_it/PingServlet.java | 0
.../main/resources/META-INF/web-fragment.xml | 0
.../jetty-simple-webapp/pom.xml | 2 +-
.../src/base/etc/test-jetty.xml | 0
.../src/base/modules/testmod.mod | 0
.../src/main/webapp/WEB-INF/web.xml | 0
.../it/jetty-start-war-distro-mojo-it/pom.xml | 2 +-
.../postbuild.groovy | 0
.../invoker.properties | 0
.../jetty-simple-base/pom.xml | 2 +-
.../HelloServlet.java | 0
.../PingServlet.java | 0
.../main/resources/META-INF/web-fragment.xml | 0
.../jetty-simple-webapp/pom.xml | 2 +-
.../jetty-simple-webapp}/src/config/jetty.xml | 0
.../src/main/webapp/WEB-INF/web.xml | 0
.../it/jetty-start-war-forked-mojo-it/pom.xml | 2 +-
.../postbuild.groovy | 0
.../invoker.properties | 0
.../src/it/jetty-start-war-mojo-it/pom.xml | 2 +-
.../jetty-start-war-mojo-it/postbuild.groovy | 0
.../src/config/jetty.xml | 0
.../ee9/maven/plugin/AbstractForker.java | 2 +-
.../plugin/AbstractUnassembledWebAppMojo.java | 2 +-
.../ee9/maven/plugin/AbstractWebAppMojo.java | 8 +-
.../jetty/ee9/maven/plugin/ConsoleReader.java | 2 +-
.../maven/plugin/JettyEffectiveWebXml.java | 2 +-
.../jetty/ee9/maven/plugin/JettyEmbedder.java | 8 +-
.../ee9/maven/plugin/JettyForkedChild.java | 2 +-
.../jetty/ee9/maven/plugin/JettyForker.java | 2 +-
.../ee9/maven/plugin/JettyHomeForker.java | 2 +-
.../jetty/ee9/maven/plugin/JettyRunMojo.java | 4 +-
.../ee9/maven/plugin/JettyRunWarMojo.java | 2 +-
.../ee9/maven/plugin/JettyStartMojo.java | 2 +-
.../ee9/maven/plugin/JettyStartWarMojo.java | 2 +-
.../jetty/ee9/maven/plugin/JettyStopMojo.java | 2 +-
.../plugin/MavenMetaInfConfiguration.java | 8 +-
.../plugin/MavenQuickStartConfiguration.java | 8 +-
.../maven/plugin/MavenServerConnector.java | 2 +-
.../ee9/maven/plugin/MavenWebAppContext.java | 24 +-
.../plugin/MavenWebInfConfiguration.java | 10 +-
.../jetty/ee9/maven/plugin/Overlay.java | 2 +-
.../jetty/ee9/maven/plugin/OverlayConfig.java | 2 +-
.../ee9/maven/plugin/OverlayManager.java | 2 +-
.../jetty/ee9/maven/plugin/PluginLog.java | 2 +-
.../ee9/maven/plugin/QuickStartGenerator.java | 8 +-
.../jetty/ee9/maven/plugin/ScanPattern.java | 2 +-
.../ee9/maven/plugin/ScanTargetPattern.java | 2 +-
.../maven/plugin/SelectiveJarResource.java | 2 +-
.../maven/plugin/ServerConnectorListener.java | 2 +-
.../ee9/maven/plugin/ServerListener.java | 2 +-
.../jetty/ee9/maven/plugin/ServerSupport.java | 8 +-
.../jetty/ee9/maven/plugin/WarPluginInfo.java | 2 +-
.../maven/plugin/WebAppPropertyConverter.java | 4 +-
.../jetty/ee9}/maven/plugin/package-info.java | 2 +-
.../plugin/utils/MavenProjectHelper.java | 6 +-
.../ee9/maven/plugin/MockShutdownMonitor.java | 2 +-
.../plugin/MockShutdownMonitorRunnable.java | 2 +-
.../ee9/maven/plugin/TestForkedChild.java | 2 +-
.../ee9/maven/plugin/TestJettyEmbedder.java | 5 +-
.../ee9/maven/plugin/TestJettyStopMojo.java | 3 +-
.../maven/plugin/TestQuickStartGenerator.java | 2 +-
.../plugin/TestSelectiveJarResource.java | 2 +-
.../plugin/TestWebAppPropertyConverter.java | 4 +-
.../plugin/it/IntegrationTestGetContent.java | 3 +-
.../src/test/resources/embedder-context.xml | 2 +-
.../src/test/resources/root/index.html | 0
jetty-ee9/jetty-ee9-nested/pom.xml | 90 +
.../src/main/assembly/site-component.xml | 15 +
.../src/main/java/module-info.java | 28 +
.../jetty/ee9/nested/AbstractHandler.java | 149 +
.../ee9/nested/AbstractHandlerContainer.java | 128 +
.../ee9/nested/AllowSymLinkAliasChecker.java | 95 +
.../nested/AllowedResourceAliasChecker.java | 237 +
.../jetty/ee9/nested}/AsyncAttributes.java | 9 +-
.../ee9/nested}/AsyncContentProducer.java | 168 +-
.../jetty/ee9/nested}/AsyncContextEvent.java | 11 +-
.../jetty/ee9/nested}/AsyncContextState.java | 5 +-
.../jetty/ee9/nested}/AsyncDelayHandler.java | 3 +-
.../jetty/ee9/nested}/Authentication.java | 2 +-
.../ee9/nested}/BlockingContentProducer.java | 19 +-
.../ee9/nested/BufferedResponseHandler.java | 325 +
.../ee9/nested/CachedContentFactory.java | 652 +
.../jetty/ee9/nested}/ContentProducer.java | 46 +-
.../jetty/ee9/nested/ContextHandler.java | 2566 +
.../eclipse/jetty/ee9/nested}/Cookies.java | 2 +-
.../jetty/ee9/nested/DebugHandler.java | 166 +
.../jetty/ee9/nested}/DebugListener.java | 11 +-
.../eclipse/jetty/ee9/nested}/Dispatcher.java | 46 +-
.../jetty/ee9/nested}/EncodingHttpWriter.java | 2 +-
.../jetty/ee9/nested}/ErrorHandler.java | 28 +-
.../nested/FileBufferedResponseHandler.java | 233 +
.../org/eclipse/jetty/ee9/nested/Handler.java | 71 +
.../jetty/ee9/nested}/HandlerCollection.java | 5 +-
.../jetty/ee9/nested/HandlerContainer.java | 54 +
.../eclipse/jetty/ee9/nested/HandlerList.java | 55 +
.../jetty/ee9/nested/HandlerWrapper.java | 141 +
.../jetty/ee9/nested/HotSwapHandler.java | 120 +
.../eclipse/jetty/ee9/nested/HttpChannel.java | 1556 +
.../ee9/nested/HttpChannelListeners.java | 282 +
.../jetty/ee9/nested/HttpChannelState.java | 1388 +
.../ee9/nested}/HttpChannelState_input.puml | 0
.../eclipse/jetty/ee9/nested}/HttpInput.java | 374 +-
.../jetty/ee9/nested}/HttpInputState.puml | 0
.../jetty/ee9/nested}/HttpInput_async.puml | 0
.../jetty/ee9/nested}/HttpInput_blocking.puml | 0
.../eclipse/jetty/ee9/nested}/HttpOutput.java | 41 +-
.../eclipse/jetty/ee9/nested}/HttpWriter.java | 2 +-
.../jetty/ee9/nested/IdleTimeoutHandler.java | 114 +
.../jetty/ee9/nested/InclusiveByteRange.java | 264 +
.../jetty/ee9/nested/InetAccessHandler.java | 248 +
.../jetty/ee9/nested/InetAccessSet.java | 153 +
.../jetty/ee9/nested}/Iso88591HttpWriter.java | 2 +-
.../ee9/nested/ManagedAttributeListener.java | 97 +
.../ee9/nested}/MultiPartFormInputStream.java | 2 +-
.../jetty/ee9/nested/MultiPartParser.java | 712 +
.../jetty/ee9/nested}/PushBuilderImpl.java | 4 +-
.../ee9/nested}/QuietServletException.java | 2 +-
.../org/eclipse/jetty/ee9/nested/Request.java | 2199 +
.../ee9/nested/ResourceContentFactory.java | 106 +
.../jetty/ee9/nested/ResourceHandler.java | 430 +
.../jetty/ee9/nested/ResourceService.java | 902 +
.../eclipse/jetty/ee9/nested/Response.java | 1502 +
.../jetty/ee9/nested}/ResponseWriter.java | 2 +-
.../ee9/nested}/SameFileAliasChecker.java | 7 +-
.../jetty/ee9/nested}/ScopedHandler.java | 30 +-
.../ee9/nested/SecuredRedirectHandler.java | 93 +
.../jetty/ee9/nested}/ServletAttributes.java | 17 +-
.../jetty/ee9/nested}/ServletPathMapping.java | 8 +-
.../nested}/ServletRequestHttpWrapper.java | 2 +-
.../nested}/ServletResponseHttpWrapper.java | 2 +-
.../jetty/ee9/nested/SessionHandler.java | 799 +
.../jetty/ee9/nested/ShutdownHandler.java | 265 +
.../jetty/ee9/nested/StatisticsHandler.java | 611 +
.../SymlinkAllowedResourceAliasChecker.java | 88 +
.../jetty/ee9/nested/ThreadLimitHandler.java | 431 +
.../jetty/ee9/nested}/UserIdentity.java | 4 +-
.../jetty/ee9/nested}/Utf8HttpWriter.java | 2 +-
.../ee9/nested}/jmx/AbstractHandlerMBean.java | 20 +-
.../ee9/nested/jmx/ContextHandlerMBean.java | 67 +
.../jetty/ee9/nested/jmx/package-info.java | 18 +
.../jetty/ee9/nested/package-info.java | 18 +
.../resource/ByteBufferRangeWriter.java | 59 +
.../resource/HttpContentRangeWriter.java | 39 +-
.../resource/InputStreamRangeWriter.java | 120 +
.../ee9/nested/resource/RangeWriter.java | 33 +
.../SeekableByteChannelRangeWriter.java | 161 +
.../src/main/resources/jetty-dir.css | 49 +
.../resources/org/eclipse/nested/favicon.ico | Bin 0 -> 1150 bytes
.../jetty/ee9/nested/AbstractHttpTest.java | 133 +
.../ee9/nested}/AsyncCompletionTest.java | 80 +-
.../ee9/nested}/AsyncContentProducerTest.java | 311 +-
.../ee9/nested}/AsyncRequestReadTest.java | 58 +-
.../nested}/BlockingContentProducerTest.java | 224 +-
.../jetty/ee9/nested}/BlockingTest.java | 25 +-
.../jetty/ee9/nested/ContextHandlerTest.java | 582 +
.../jetty/ee9/nested}/CookiesTest.java | 2 +-
.../eclipse/jetty/ee9/nested/DumpHandler.java | 262 +
.../jetty/ee9/nested}/ErrorHandlerTest.java | 21 +-
.../HttpManyWaysToAsyncCommitTest.java | 33 +-
.../ee9/nested}/HttpManyWaysToCommitTest.java | 26 +-
.../jetty/ee9/nested}/HttpOutputTest.java | 34 +-
.../ee9/nested/HttpServerTestFixture.java | 257 +
.../jetty/ee9/nested}/HttpWriterTest.java | 23 +-
.../ee9/nested}/LocalAsyncContextTest.java | 29 +-
.../ee9/nested/MockConnectionMetaData.java | 132 +
.../jetty/ee9/nested/MockConnector.java | 66 +
.../eclipse/jetty/ee9/nested/RequestTest.java | 2268 +
.../jetty/ee9/nested}/ResponseTest.java | 599 +-
.../jetty/ee9/nested}/ScopedHandlerTest.java | 14 +-
.../ServerConnectorAsyncContextTest.java | 10 +-
.../nested}/ServletRequestWrapperTest.java | 30 +-
.../jetty/ee9/nested}/ServletWriterTest.java | 27 +-
.../jetty/ee9/nested/SessionHandlerTest.java | 373 +
.../jetty/ee9/nested}/SuspendHandler.java | 3 +-
.../src/test/resources/example.jar | Bin 0 -> 155993 bytes
.../src/test/resources/fakeRequests.txt | 27 +
.../test/resources/jetty-logging.properties | 8 +
.../src/test/resources/keystore.p12 | Bin 0 -> 2613 bytes
.../src/test/resources/keystore_sni.p12 | Bin 0 -> 10672 bytes
.../test/resources/keystore_sni_key_types.p12 | Bin 0 -> 3348 bytes
.../test/resources/keystore_sni_nowild.p12 | Bin 0 -> 4637 bytes
...ny-urlencoded-apache-httpcomp.expected.txt | 9 +
...ure-company-urlencoded-apache-httpcomp.raw | 7 +
...pture-complex-apache-httpcomp.expected.txt | 15 +
...rowser-capture-complex-apache-httpcomp.raw | Bin 0 -> 22940 bytes
...-capture-complex-jetty-client.expected.txt | 15 +
.../browser-capture-complex-jetty-client.raw | Bin 0 -> 22754 bytes
...plicate-names-apache-httpcomp.expected.txt | 8 +
...apture-duplicate-names-apache-httpcomp.raw | Bin 0 -> 1815 bytes
...-duplicate-names-jetty-client.expected.txt | 8 +
...r-capture-duplicate-names-jetty-client.raw | 51 +
...encoding-mess-apache-httpcomp.expected.txt | 11 +
...-capture-encoding-mess-apache-httpcomp.raw | 1015 +
...re-encoding-mess-jetty-client.expected.txt | 11 +
...ser-capture-encoding-mess-jetty-client.raw | 846 +
...re-form-fileupload-alt-chrome.expected.txt | 21 +
...ser-capture-form-fileupload-alt-chrome.raw | Bin 0 -> 22759 bytes
...ture-form-fileupload-alt-edge.expected.txt | 17 +
...owser-capture-form-fileupload-alt-edge.raw | Bin 0 -> 22824 bytes
...e-form-fileupload-alt-firefox.expected.txt | 17 +
...er-capture-form-fileupload-alt-firefox.raw | Bin 0 -> 22774 bytes
...ture-form-fileupload-alt-msie.expected.txt | 17 +
...owser-capture-form-fileupload-alt-msie.raw | Bin 0 -> 22814 bytes
...re-form-fileupload-alt-safari.expected.txt | 18 +
...ser-capture-form-fileupload-alt-safari.raw | Bin 0 -> 22774 bytes
...orm-fileupload-android-chrome.expected.txt | 17 +
...capture-form-fileupload-android-chrome.raw | Bin 0 -> 22054 bytes
...rm-fileupload-android-firefox.expected.txt | 14 +
...apture-form-fileupload-android-firefox.raw | Bin 0 -> 22105 bytes
...apture-form-fileupload-chrome.expected.txt | 18 +
...browser-capture-form-fileupload-chrome.raw | Bin 0 -> 22054 bytes
...-capture-form-fileupload-edge.expected.txt | 14 +
.../browser-capture-form-fileupload-edge.raw | Bin 0 -> 22085 bytes
...pture-form-fileupload-firefox.expected.txt | 14 +
...rowser-capture-form-fileupload-firefox.raw | Bin 0 -> 22063 bytes
...re-form-fileupload-ios-safari.expected.txt | 15 +
...ser-capture-form-fileupload-ios-safari.raw | Bin 0 -> 22074 bytes
...-capture-form-fileupload-msie.expected.txt | 14 +
.../browser-capture-form-fileupload-msie.raw | Bin 0 -> 22082 bytes
...apture-form-fileupload-safari.expected.txt | 15 +
...browser-capture-form-fileupload-safari.raw | Bin 0 -> 22054 bytes
...-capture-form1-android-chrome.expected.txt | 16 +
.../browser-capture-form1-android-chrome.raw | 9 +
...capture-form1-android-firefox.expected.txt | 13 +
.../browser-capture-form1-android-firefox.raw | 9 +
.../browser-capture-form1-chrome.expected.txt | 17 +
.../browser-capture-form1-chrome.raw | 9 +
.../browser-capture-form1-edge.expected.txt | 13 +
.../multipart/browser-capture-form1-edge.raw | 9 +
...browser-capture-form1-firefox.expected.txt | 13 +
.../browser-capture-form1-firefox.raw | 9 +
...wser-capture-form1-ios-safari.expected.txt | 14 +
.../browser-capture-form1-ios-safari.raw | 9 +
.../browser-capture-form1-msie.expected.txt | 13 +
.../multipart/browser-capture-form1-msie.raw | 9 +
...wser-capture-form1-osx-safari.expected.txt | 14 +
.../browser-capture-form1-osx-safari.raw | 9 +
...apture-nested-apache-httpcomp.expected.txt | 12 +
...browser-capture-nested-apache-httpcomp.raw | 42 +
...nested-binary-apache-httpcomp.expected.txt | 12 +
...-capture-nested-binary-apache-httpcomp.raw | 50 +
...r-capture-nested-jetty-client.expected.txt | 12 +
.../browser-capture-nested-jetty-client.raw | 42 +
...e-number-only-apache-httpcomp.expected.txt | 9 +
...er-capture-number-only-apache-httpcomp.raw | 5 +
...ture-number-only-jetty-client.expected.txt | 12 +
...owser-capture-number-only-jetty-client.raw | 6 +
...-number-only2-apache-httpcomp.expected.txt | 9 +
...r-capture-number-only2-apache-httpcomp.raw | 7 +
...-capture-sjis-apache-httpcomp.expected.txt | 10 +
.../browser-capture-sjis-apache-httpcomp.raw | 13 +
...s-charset-form-android-chrome.expected.txt | 17 +
...pture-sjis-charset-form-android-chrome.raw | 13 +
...-charset-form-android-firefox.expected.txt | 14 +
...ture-sjis-charset-form-android-firefox.raw | 13 +
...ture-sjis-charset-form-chrome.expected.txt | 18 +
...owser-capture-sjis-charset-form-chrome.raw | 13 +
...apture-sjis-charset-form-edge.expected.txt | 14 +
...browser-capture-sjis-charset-form-edge.raw | 13 +
...ure-sjis-charset-form-firefox.expected.txt | 14 +
...wser-capture-sjis-charset-form-firefox.raw | 13 +
...-sjis-charset-form-ios-safari.expected.txt | 15 +
...r-capture-sjis-charset-form-ios-safari.raw | 13 +
...apture-sjis-charset-form-msie.expected.txt | 14 +
...browser-capture-sjis-charset-form-msie.raw | 13 +
...ture-sjis-charset-form-safari.expected.txt | 15 +
...owser-capture-sjis-charset-form-safari.raw | 13 +
...ture-sjis-form-android-chrome.expected.txt | 16 +
...owser-capture-sjis-form-android-chrome.raw | 9 +
...ure-sjis-form-android-firefox.expected.txt | 13 +
...wser-capture-sjis-form-android-firefox.raw | 9 +
...wser-capture-sjis-form-chrome.expected.txt | 17 +
.../browser-capture-sjis-form-chrome.raw | 9 +
...rowser-capture-sjis-form-edge.expected.txt | 13 +
.../browser-capture-sjis-form-edge.raw | 9 +
...ser-capture-sjis-form-firefox.expected.txt | 13 +
.../browser-capture-sjis-form-firefox.raw | 9 +
...-capture-sjis-form-ios-safari.expected.txt | 14 +
.../browser-capture-sjis-form-ios-safari.raw | 9 +
...rowser-capture-sjis-form-msie.expected.txt | 13 +
.../browser-capture-sjis-form-msie.raw | 9 +
...wser-capture-sjis-form-safari.expected.txt | 14 +
.../browser-capture-sjis-form-safari.raw | 9 +
...ser-capture-sjis-jetty-client.expected.txt | 10 +
.../browser-capture-sjis-jetty-client.raw | 11 +
...range-quoting-apache-httpcomp.expected.txt | 11 +
...apture-strange-quoting-apache-httpcomp.raw | 25 +
...re-text-files-apache-httpcomp.expected.txt | 15 +
...ser-capture-text-files-apache-httpcomp.raw | 23 +
...pture-text-files-jetty-client.expected.txt | 15 +
...rowser-capture-text-files-jetty-client.raw | 20 +
...unicode-names-apache-httpcomp.expected.txt | 11 +
...-capture-unicode-names-apache-httpcomp.raw | 13 +
...re-unicode-names-jetty-client.expected.txt | 11 +
...ser-capture-unicode-names-jetty-client.raw | 11 +
...-whitespace-only-jetty-client.expected.txt | 10 +
...r-capture-whitespace-only-jetty-client.raw | 209748 +++++++++++++++
...go-text-plain-apache-httpcomp.expected.txt | 12 +
...pture-zalgo-text-plain-apache-httpcomp.raw | Bin 0 -> 1870 bytes
.../multipart-base64-long.expected.txt | 4 +
.../multipart/multipart-base64-long.raw | 8 +
.../multipart/multipart-base64.expected.txt | 4 +
.../resources/multipart/multipart-base64.raw | 389 +
.../multipart-uppercase.expected.txt | 5 +
.../multipart/multipart-uppercase.raw | 13 +
.../src/test/resources/reload_keystore_1.p12 | Bin 0 -> 2581 bytes
.../src/test/resources/reload_keystore_2.p12 | Bin 0 -> 2581 bytes
.../src/test/resources/simple/big.txt | 400 +
.../resources/simple/directory/content.txt | 1 +
.../resources/simple/directory/welcome.txt | 1 +
.../src/test/resources/simple/simple.txt | 1 +
.../jetty-ee9-openid}/pom.xml | 18 +-
.../src/main/config/etc/jetty-openid.xml | 2 +-
.../src/main/java/module-info.java | 6 +-
.../jetty/ee9/security/openid/JwtDecoder.java | 2 +-
.../openid/OpenIdAuthConfiguration.java | 12 +-
.../security/openid/OpenIdAuthenticator.java | 27 +-
.../openid/OpenIdAuthenticatorFactory.java | 8 +-
.../security/openid/OpenIdConfiguration.java | 2 +-
.../security/openid/OpenIdCredentials.java | 2 +-
.../security/openid/OpenIdLoginService.java | 8 +-
.../security/openid/OpenIdUserIdentity.java | 4 +-
.../security/openid/OpenIdUserPrincipal.java | 2 +-
...e.jetty.ee9.security.Authenticator$Factory | 1 +
...lipse.jetty.security.Authenticator$Factory | 2 +-
.../ee9/security/openid/JwtDecoderTest.java | 2 +-
.../jetty/ee9/security/openid/JwtEncoder.java | 2 +-
.../openid/OpenIdAuthenticationTest.java | 8 +-
.../openid/OpenIdCredentialsTest.java | 2 +-
.../ee9/security/openid/OpenIdProvider.java | 10 +-
.../security/openid/OpenIdReamNameTest.java | 22 +-
.../jetty-ee9-osgi-alpn}/pom.xml | 10 +-
.../jetty-ee9-osgi-boot-jsp}/pom.xml | 27 +-
.../jasper/ContainerTldBundleDiscoverer.java | 16 +-
.../boot/jasper/JSTLBundleDiscoverer.java | 8 +-
.../ee9/osgi/boot/jsp/FragmentActivator.java | 8 +-
.../jetty-ee9-osgi-boot-warurl}/pom.xml | 14 +-
.../ee9/osgi/boot/warurl/WarUrlActivator.java | 2 +-
.../osgi/boot/warurl/WarUrlStreamHandler.java | 6 +-
.../internal/WarBundleManifestGenerator.java | 2 +-
.../warurl/internal/WarURLConnection.java | 2 +-
.../jettyhome/contexts/README | 0
.../jetty-ee9-osgi-boot}/jettyhome/etc/README | 0
.../jettyhome/etc/jetty-deploy.xml | 0
.../jettyhome/etc/jetty-http.xml | 0
.../jettyhome/etc/jetty.xml | 26 +-
.../jettyhome/lib/ext/README | 0
.../jettyhome/logs/README | 0
.../jettyhome/resources/README | 0
.../jettyhome/webapps/README | 0
.../jetty-ee9-osgi-boot}/pom.xml | 26 +-
.../annotations/AnnotationConfiguration.java | 26 +-
.../osgi/annotations/AnnotationParser.java | 6 +-
.../osgi/boot/AbstractContextProvider.java | 8 +-
.../jetty/ee9/osgi/boot/AbstractOSGiApp.java | 2 +-
.../ee9/osgi/boot/AbstractWebAppProvider.java | 12 +-
.../ee9/osgi/boot/BundleContextProvider.java | 4 +-
.../jetty/ee9/osgi/boot/BundleProvider.java | 2 +-
.../ee9/osgi/boot/BundleWebAppProvider.java | 6 +-
.../osgi/boot/JettyBootstrapActivator.java | 8 +-
.../jetty/ee9/osgi/boot/OSGiDeployer.java | 6 +-
.../osgi/boot/OSGiMetaInfConfiguration.java | 28 +-
.../ee9/osgi/boot/OSGiServerConstants.java | 4 +-
.../jetty/ee9/osgi/boot/OSGiUndeployer.java | 6 +-
.../osgi/boot/OSGiWebInfConfiguration.java | 6 +-
.../ee9/osgi/boot/OSGiWebappConstants.java | 2 +-
.../ee9/osgi/boot/ServiceContextProvider.java | 8 +-
.../jetty/ee9/osgi/boot/ServiceProvider.java | 2 +-
.../ee9/osgi/boot/ServiceWebAppProvider.java | 8 +-
.../DefaultJettyAtJettyHomeHelper.java | 12 +-
.../JettyServerServiceTracker.java | 4 +-
.../serverfactory/ServerInstanceWrapper.java | 28 +-
.../webapp/LibExtClassLoaderHelper.java | 2 +-
.../webapp/OSGiWebappClassLoader.java | 10 +-
.../boot/utils/BundleClassLoaderHelper.java | 6 +-
.../utils/BundleClassLoaderHelperFactory.java | 2 +-
.../boot/utils/BundleFileLocatorHelper.java | 6 +-
.../utils/BundleFileLocatorHelperFactory.java | 2 +-
.../ee9/osgi/boot/utils/EventSender.java | 2 +-
.../osgi/boot/utils/FakeURLClassLoader.java | 2 +-
.../ee9/osgi/boot/utils/OSGiClassLoader.java | 2 +-
.../boot/utils/ServerConnectorListener.java | 2 +-
.../osgi/boot/utils/TldBundleDiscoverer.java | 2 +-
.../jetty/ee9/osgi/boot/utils/Util.java | 4 +-
.../DefaultBundleClassLoaderHelper.java | 4 +-
.../internal/DefaultFileLocatorHelper.java | 4 +-
.../internal/PackageAdminServiceTracker.java | 4 +-
.../org.eclipse.jetty.webapp.Configuration | 4 +-
.../contexts/httpservice.xml | 4 +-
.../jetty-ee9-osgi-httpservice}/pom.xml | 18 +-
.../HttpServiceErrorHandlerHelper.java | 2 +-
.../HttpServiceErrorPageErrorHandler.java | 4 +-
.../jetty-ee9-osgi}/pom.xml | 44 +-
.../test-jetty-ee9-osgi-context}/pom.xml | 16 +-
.../main/java/com/acme/osgi/Activator.java | 0
.../src/main/resources/static/index.html | 0
.../test-jetty-ee9-osgi-fragment}/pom.xml | 10 +-
.../test-jetty-ee9-osgi-server}/pom.xml | 14 +-
.../main/java/com/acme/osgi/Activator.java | 12 +-
.../src/main/resources/index.html | 0
.../pom.xml | 8 +-
.../test-jetty-ee9-osgi-webapp}/pom.xml | 16 +-
.../main/java/com/acme/osgi/Activator.java | 4 +-
.../src/main/resources/index.html | 0
.../src/main/resources/webappA/index.html | 0
.../src/main/resources/webappB/index.html | 0
.../test-jetty-ee9-osgi/README.txt | 130 +-
.../test-jetty-ee9-osgi}/pom.xml | 110 +-
.../src/test/config/etc/jetty-deploy.xml | 0
.../jetty-http-boot-context-as-service.xml | 2 +-
.../etc/jetty-http-boot-webapp-as-service.xml | 2 +-
.../etc/jetty-http-boot-with-annotations.xml | 2 +-
.../etc/jetty-http-boot-with-bundle.xml | 2 +-
...jetty-http-boot-with-jakarta-websocket.xml | 2 +-
.../config/etc/jetty-http-boot-with-jsp.xml | 2 +-
.../etc/jetty-http-boot-with-resources.xml | 2 +-
.../etc/jetty-http-boot-with-websocket.xml | 2 +-
.../src/test/config/etc/jetty-http.xml | 2 +-
.../src/test/config/etc/jetty-https.xml | 2 +-
.../config/etc/jetty-with-custom-class.xml | 28 +-
.../src/test/config/etc/jetty.xml | 26 +-
.../src/test/config/etc/realm.properties | 2 +-
.../src/test/config/etc/webdefault.xml | 12 +-
.../jetty/ee9/osgi/test/SimpleEchoSocket.java | 14 +-
.../ee9/osgi/test/SimpleJakartaWebSocket.java | 2 +-
.../jetty/ee9/osgi/test/SomeCustomBean.java | 2 +-
.../test/TestJettyOSGiAnnotationParser.java | 6 +-
.../TestJettyOSGiBootContextAsService.java | 8 +-
.../test/TestJettyOSGiBootHTTP2Conscrypt.java | 4 +-
.../osgi/test/TestJettyOSGiBootHTTP2JDK9.java | 4 +-
.../TestJettyOSGiBootWebAppAsService.java | 10 +-
.../TestJettyOSGiBootWithAnnotations.java | 6 +-
.../test/TestJettyOSGiBootWithBundle.java | 4 +-
...TestJettyOSGiBootWithJakartaWebSocket.java | 2 +-
.../osgi/test/TestJettyOSGiBootWithJsp.java | 5 +-
.../test/TestJettyOSGiBootWithWebSocket.java | 6 +-
.../test/TestJettyOSGiClasspathResources.java | 16 +-
.../jetty/ee9/osgi/test/TestOSGiUtil.java | 9 +-
.../src/test/resources/module-info.java | 0
.../jetty-ee9-plus}/pom.xml | 16 +-
.../src/main/config/etc/jetty-plus.xml | 8 +-
.../src/main/java/module-info.java | 21 +-
.../plus/annotation/ContainerInitializer.java | 4 +-
.../jetty/ee9/plus/annotation/Injection.java | 2 +-
.../plus/annotation/InjectionCollection.java | 2 +-
.../plus/annotation/LifeCycleCallback.java | 2 +-
.../LifeCycleCallbackCollection.java | 2 +-
.../annotation/PostConstructCallback.java | 4 +-
.../plus/annotation/PreDestroyCallback.java | 4 +-
.../jetty/ee9/plus/annotation/RunAs.java | 4 +-
.../ee9/plus/annotation/RunAsCollection.java | 4 +-
.../ee9}/plus/annotation/package-info.java | 2 +-
.../eclipse/jetty/ee9/plus/jndi/EnvEntry.java | 2 +-
.../org/eclipse/jetty/ee9/plus/jndi/Link.java | 2 +-
.../jetty/ee9/plus/jndi/NamingDump.java | 2 +-
.../jetty/ee9/plus/jndi/NamingEntry.java | 2 +-
.../jetty/ee9/plus/jndi/NamingEntryUtil.java | 2 +-
.../eclipse/jetty/ee9/plus/jndi/Resource.java | 2 +-
.../jetty/ee9/plus/jndi/Transaction.java | 2 +-
.../jetty/ee9}/plus/jndi/package-info.java | 2 +-
.../plus/security/DataSourceLoginService.java | 12 +-
.../ee9}/plus/security/package-info.java | 2 +-
.../ee9/plus/webapp/EnvConfiguration.java | 22 +-
.../ee9/plus/webapp/PlusConfiguration.java | 20 +-
.../jetty/ee9/plus/webapp/PlusDecorator.java | 8 +-
.../plus/webapp/PlusDescriptorProcessor.java | 32 +-
.../jetty/ee9}/plus/webapp/package-info.java | 2 +-
...org.eclipse.jetty.ee9.webapp.Configuration | 2 +
.../LifeCycleCallbackCollectionTest.java | 6 +-
.../ee9/plus/jndi/NamingEntryUtilTest.java | 2 +-
.../ee9/plus/jndi/TestNamingEntries.java | 2 +-
.../ee9/plus/jndi/TestNamingEntryUtil.java | 2 +-
.../webapp/PlusDescriptorProcessorTest.java | 35 +-
.../jetty-ee9-plus/src/test/resources/web.xml | 10 +-
.../jetty-ee9-proxy}/pom.xml | 16 +-
.../src/main/config/etc/jetty-proxy.xml | 2 +-
.../src/main/java/module-info.java | 5 +-
.../jetty/ee9/proxy/AbstractProxyServlet.java | 2 +-
.../ee9/proxy/AfterContentTransformer.java | 2 +-
.../ee9/proxy/AsyncMiddleManServlet.java | 2 +-
.../jetty/ee9/proxy/AsyncProxyServlet.java | 2 +-
.../jetty/ee9/proxy/BalancerServlet.java | 2 +-
.../jetty/ee9/proxy/ConnectHandler.java | 6 +-
.../jetty/ee9/proxy/ProxyConnection.java | 2 +-
.../eclipse/jetty/ee9/proxy/ProxyServlet.java | 2 +-
.../jetty/ee9}/proxy/package-info.java | 2 +-
.../ee9/proxy/AbstractConnectHandlerTest.java | 2 +-
.../ee9/proxy/AsyncMiddleManServletTest.java | 10 +-
.../jetty/ee9/proxy/BalancerServletTest.java | 8 +-
.../jetty/ee9/proxy/CachingProxyServlet.java | 2 +-
.../jetty/ee9/proxy/ClientAuthProxyTest.java | 6 +-
.../ee9/proxy/ConnectHandlerSSLTest.java | 2 +-
.../jetty/ee9/proxy/ConnectHandlerTest.java | 2 +-
.../jetty/ee9/proxy/EchoHttpServlet.java | 2 +-
.../jetty/ee9/proxy/EmptyHttpServlet.java | 2 +-
.../jetty/ee9/proxy/EmptyServerHandler.java | 2 +-
.../ee9/proxy/ForwardProxyServerTest.java | 6 +-
.../ee9/proxy/ForwardProxyTLSServerTest.java | 4 +-
.../eclipse/jetty/ee9/proxy/ProxyServer.java | 6 +-
.../ee9/proxy/ProxyServletFailureTest.java | 12 +-
.../jetty/ee9/proxy/ProxyServletLoadTest.java | 6 +-
.../jetty/ee9/proxy/ProxyServletTest.java | 8 +-
.../jetty/ee9/proxy/ReverseProxyTest.java | 6 +-
.../resources/client_auth/client_keystore.p12 | Bin
.../resources/client_auth/proxy_keystore.p12 | Bin
.../resources/client_auth/server_keystore.p12 | Bin
.../src/test/resources/client_keystore.p12 | Bin
.../src/test/resources/proxy_keystore.p12 | Bin
.../src/test/resources/server_keystore.p12 | Bin
.../jetty-ee9-quickstart}/pom.xml | 24 +-
.../jetty-quickstart.d/quickstart-webapp.xml | 2 +-
.../src/main/java/module-info.java | 6 +-
.../ee9/quickstart/AttributeNormalizer.java | 2 +-
.../ExtraXmlDescriptorProcessor.java | 8 +-
.../quickstart/PreconfigureQuickStartWar.java | 12 +-
.../quickstart/QuickStartConfiguration.java | 30 +-
.../QuickStartDescriptorProcessor.java | 22 +-
.../QuickStartGeneratorConfiguration.java | 50 +-
.../ee9/quickstart/FooContextListener.java | 2 +-
.../jetty/ee9/quickstart/FooFilter.java | 2 +-
.../jetty/ee9/quickstart/FooServlet.java | 2 +-
.../jetty/ee9/quickstart/TestQuickStart.java | 10 +-
.../src/test/resources/context.xml | 8 +-
.../jetty-ee9-runner}/pom.xml | 36 +-
.../invoker.properties | 0
.../pom.xml | 4 +-
.../invoker.properties | 0
.../src/it/demo-simple-webapp-runner/pom.xml | 4 +-
.../it/test-jar-manifest/invoker.properties | 0
.../src/it/test-jar-manifest/pom.xml | 0
.../org/eclipse/jetty/ee9/runner/Runner.java | 42 +-
.../jetty/ee9}/runner/package-info.java | 2 +-
.../it/IntegrationTestJettyRunner.java | 2 +-
.../jetty-ee9-security}/pom.xml | 16 +-
.../src/main/java/module-info.java | 11 +-
.../ee9/security/AbstractLoginService.java | 4 +-
.../security/AbstractUserAuthentication.java | 12 +-
.../jetty/ee9/security/Authenticator.java | 12 +-
.../ConfigurableSpnegoLoginService.java | 6 +-
.../jetty/ee9/security/ConstraintAware.java | 2 +-
.../jetty/ee9/security/ConstraintMapping.java | 2 +-
.../security/ConstraintSecurityHandler.java | 12 +-
.../security/DefaultAuthenticatorFactory.java | 37 +-
.../ee9/security/DefaultIdentityService.java | 10 +-
.../ee9/security/DefaultUserIdentity.java | 4 +-
.../jetty/ee9/security/EmptyLoginService.java | 4 +-
.../jetty/ee9/security/HashLoginService.java | 2 +-
.../jetty/ee9/security/IdentityService.java | 7 +-
.../jetty/ee9/security/JDBCLoginService.java | 2 +-
.../ee9/security/LoggedOutAuthentication.java | 8 +-
.../jetty/ee9/security/LoginService.java | 4 +-
.../jetty/ee9/security/PropertyUserStore.java | 2 +-
.../eclipse/jetty/ee9/security/RoleInfo.java | 2 +-
.../jetty/ee9/security/RolePrincipal.java | 2 +-
.../jetty/ee9/security/RoleRunAsToken.java | 2 +-
.../jetty/ee9/security/RunAsToken.java | 2 +-
.../jetty/ee9/security/SecurityHandler.java | 26 +-
.../ee9/security/ServerAuthException.java | 2 +-
.../ee9/security/SpnegoUserIdentity.java | 4 +-
.../ee9/security/SpnegoUserPrincipal.java | 2 +-
.../ee9/security/UserAuthentication.java | 4 +-
.../ee9/security/UserDataConstraint.java | 2 +-
.../jetty/ee9/security/UserPrincipal.java | 2 +-
.../eclipse/jetty/ee9/security/UserStore.java | 2 +-
.../security/WrappedAuthConfiguration.java | 4 +-
.../authentication/AuthorizationService.java | 6 +-
.../authentication/BasicAuthenticator.java | 12 +-
.../ClientCertAuthenticator.java | 12 +-
.../ConfigurableSpnegoAuthenticator.java | 21 +-
.../DeferredAuthentication.java | 18 +-
.../authentication/DigestAuthenticator.java | 16 +-
.../authentication/FormAuthenticator.java | 16 +-
.../authentication/LoginAuthenticator.java | 37 +-
.../authentication/LoginCallback.java | 2 +-
.../authentication/LoginCallbackImpl.java | 4 +-
.../authentication/SessionAuthentication.java | 10 +-
.../SslClientCertAuthenticator.java | 18 +-
.../security/authentication/package-info.java | 2 +-
.../jetty/ee9}/security/package-info.java | 2 +-
.../ee9/security/AliasedConstraintTest.java | 17 +-
.../security/ClientCertAuthenticatorTest.java | 11 +-
.../jetty/ee9/security/ConstraintTest.java | 22 +-
.../ee9/security/DataConstraintsTest.java | 36 +-
.../security/DefaultIdentityServiceTest.java | 8 +-
.../ee9/security/HashLoginServiceTest.java | 2 +-
.../ee9/security/PropertyUserStoreTest.java | 2 +-
.../security/SpecExampleConstraintTest.java | 20 +-
.../jetty/ee9/security/TestLoginService.java | 2 +-
.../ee9/security/UnauthenticatedTest.java | 16 +-
.../jetty/ee9/security/UserStoreTest.java | 2 +-
.../SpnegoAuthenticatorTest.java | 29 +-
.../src/test/resources/docroot/all/index.txt | 0
.../test/resources/docroot/forbid/index.txt | 0
.../src/test/resources/realm.properties | 2 +-
.../jetty-ee9-servlet}/pom.xml | 21 +-
.../src/main/java/module-info.java | 12 +-
.../eclipse/jetty/ee9/servlet/BaseHolder.java | 16 +-
.../jetty/ee9/servlet/DecoratingListener.java | 2 +-
.../jetty/ee9/servlet/DefaultServlet.java | 24 +-
.../ee9/servlet/ErrorPageErrorHandler.java | 24 +-
.../jetty/ee9/servlet/FilterHolder.java | 4 +-
.../jetty/ee9/servlet/FilterMapping.java | 2 +-
.../org/eclipse/jetty/ee9/servlet/Holder.java | 2 +-
.../eclipse/jetty/ee9/servlet/Invoker.java | 14 +-
.../ee9/servlet/JspPropertyGroupServlet.java | 6 +-
.../jetty/ee9/servlet/ListenerHolder.java | 4 +-
.../jetty/ee9/servlet/NoJspServlet.java | 2 +-
.../ServletContainerInitializerHolder.java | 6 +-
.../ee9/servlet/ServletContextHandler.java | 67 +-
.../jetty/ee9/servlet/ServletHandler.java | 33 +-
.../jetty/ee9/servlet/ServletHolder.java | 12 +-
.../jetty/ee9/servlet/ServletMapping.java | 2 +-
.../jetty/ee9/servlet/ServletTester.java | 2 +-
.../org/eclipse/jetty/ee9/servlet/Source.java | 2 +-
.../jetty/ee9/servlet/StatisticsServlet.java | 11 +-
.../ee9/servlet/jmx/FilterMappingMBean.java | 4 +-
.../jetty/ee9/servlet/jmx/HolderMBean.java | 4 +-
.../ee9/servlet/jmx/ServletMappingMBean.java | 4 +-
.../jetty/ee9}/servlet/jmx/package-info.java | 2 +-
.../listener/ContainerInitializer.java | 2 +-
.../servlet/listener/ELContextCleaner.java | 2 +-
.../servlet/listener/IntrospectorCleaner.java | 2 +-
.../ee9}/servlet/listener/package-info.java | 2 +-
.../jetty/ee9}/servlet/package-info.java | 2 +-
.../AsyncContextDispatchWithQueryStrings.java | 8 +-
.../servlet/AsyncContextListenersTest.java | 4 +-
.../jetty/ee9/servlet/AsyncContextTest.java | 22 +-
.../jetty/ee9/servlet/AsyncListenerTest.java | 29 +-
.../jetty/ee9/servlet/AsyncServletIOTest.java | 4 +-
.../ee9/servlet/AsyncServletLongPollTest.java | 4 +-
.../jetty/ee9/servlet/AsyncServletTest.java | 24 +-
.../ee9/servlet/CacheControlHeaderTest.java | 4 +-
.../servlet/ComplianceViolations2616Test.java | 2 +-
.../jetty/ee9/servlet/ComponentWrapTest.java | 2 +-
.../ee9/servlet/CustomRequestLogTest.java | 4 +-
.../ee9/servlet/DefaultServletRangesTest.java | 2 +-
.../jetty/ee9/servlet/DefaultServletTest.java | 37 +-
.../ee9/servlet/DispatcherForwardTest.java | 2 +-
.../jetty/ee9/servlet/DispatcherTest.java | 17 +-
.../jetty/ee9/servlet/EncodedURITest.java | 4 +-
.../jetty/ee9/servlet/ErrorPageTest.java | 44 +-
.../jetty/ee9/servlet/FilterHolderTest.java | 4 +-
.../eclipse/jetty/ee9/servlet/FormTest.java | 4 +-
.../servlet/GzipHandlerBreakEvenSizeTest.java | 2 +-
.../ee9/servlet/GzipHandlerCommitTest.java | 2 +-
.../ee9/servlet/IncludedServletTest.java | 2 +-
.../jetty/ee9/servlet/InitServletTest.java | 2 +-
.../jetty/ee9/servlet/InvokerTest.java | 2 +-
.../jetty/ee9/servlet/ListenerHolderTest.java | 4 +-
.../ee9/servlet/MultiPartServletTest.java | 8 +-
.../jetty/ee9/servlet/PostServletTest.java | 5 +-
.../jetty/ee9/servlet/RegexServletTest.java | 2 +-
.../jetty/ee9/servlet/RequestHeadersTest.java | 2 +-
.../jetty/ee9/servlet/RequestURITest.java | 2 +-
.../ee9/servlet/ResponseHeadersTest.java | 10 +-
.../ee9/servlet/SSLAsyncIOServletTest.java | 2 +-
...ServletContainerInitializerHolderTest.java | 6 +-
.../servlet/ServletContextHandlerTest.java | 141 +-
.../servlet/ServletContextResourcesTest.java | 2 +-
.../jetty/ee9/servlet/ServletHandlerTest.java | 22 +-
.../jetty/ee9/servlet/ServletHolderTest.java | 6 +-
.../ee9/servlet/ServletLifeCycleTest.java | 66 +-
.../ee9/servlet/ServletRequestLogTest.java | 35 +-
.../jetty/ee9/servlet/ServletUpgradeTest.java | 14 +-
.../jetty/ee9/servlet/ServletWrapperTest.java | 8 +-
.../ee9/servlet/StatisticsServletTest.java | 16 +-
.../resources/contextResources/content.txt | 0
.../dispatchResourceTest/content.txt | 0
.../test/resources/jetty-logging.properties | 2 +-
.../jetty-ee9-servlets}/pom.xml | 27 +-
.../src/main/config/modules/servlets.mod | 2 +-
.../src/main/java/module-info.java | 6 +-
.../org/eclipse/jetty/ee9/servlets/CGI.java | 2 +-
.../ee9/servlets/CloseableDoSFilter.java | 19 +-
.../jetty/ee9/servlets/CrossOriginFilter.java | 4 +-
.../eclipse/jetty/ee9/servlets/DoSFilter.java | 2 +-
.../jetty/ee9/servlets/EventSource.java | 2 +-
.../ee9/servlets/EventSourceServlet.java | 2 +-
.../jetty/ee9/servlets/HeaderFilter.java | 2 +-
.../servlets/IncludeExcludeBasedFilter.java | 2 +-
.../jetty/ee9/servlets/PushCacheFilter.java | 2 +-
.../ee9/servlets/PushSessionCacheFilter.java | 2 +-
.../eclipse/jetty/ee9/servlets/QoSFilter.java | 2 +-
.../jetty/ee9}/servlets/package-info.java | 2 +-
.../ee9/servlets/AbstractDoSFilterTest.java | 14 +-
.../servlets/AbstractFileContentServlet.java | 2 +-
.../jetty/ee9/servlets/AbstractGzipTest.java | 2 +-
.../jetty/ee9/servlets/AsyncManipFilter.java | 2 +-
.../servlets/AsyncScheduledDispatchWrite.java | 2 +-
.../servlets/AsyncTimeoutCompleteWrite.java | 2 +-
.../servlets/AsyncTimeoutDispatchWrite.java | 2 +-
.../BlockingServletLengthStreamTypeWrite.java | 2 +-
.../BlockingServletLengthTypeStreamWrite.java | 2 +-
.../BlockingServletStreamLengthTypeWrite.java | 2 +-
...ServletStreamLengthTypeWriteWithFlush.java | 2 +-
.../BlockingServletStreamTypeLengthWrite.java | 2 +-
.../BlockingServletTypeLengthStreamWrite.java | 2 +-
.../BlockingServletTypeStreamLengthWrite.java | 2 +-
.../ee9/servlets/CloseableDoSFilterTest.java | 2 +-
.../ee9/servlets/CrossOriginFilterTest.java | 8 +-
.../jetty/ee9/servlets/DoSFilterJMXTest.java | 6 +-
.../jetty/ee9/servlets/DoSFilterTest.java | 37 +-
.../ee9/servlets/EventSourceServletTest.java | 6 +-
.../ee9/servlets/GzipContentLengthTest.java | 49 +-
...DefaultServletDeferredContentTypeTest.java | 8 +-
.../ee9/servlets/GzipDefaultServletTest.java | 78 +-
.../servlets/GzipHandlerNoReCompressTest.java | 10 +-
.../jetty/ee9/servlets/GzipHandlerTest.java | 4 +-
.../jetty/ee9/servlets/HeaderFilterTest.java | 6 +-
.../HttpOutputWriteFileContentServlet.java | 4 +-
.../IncludeExcludeBasedFilterTest.java | 6 +-
.../jetty/ee9/servlets/NoOpOutputStream.java | 2 +-
.../ee9/servlets/PassThruInputStream.java | 2 +-
.../jetty/ee9/servlets/QoSFilterTest.java | 6 +-
.../ee9/servlets/TestMinGzipSizeServlet.java | 2 +-
.../servlets/TestStaticMimeTypeServlet.java | 2 +-
.../ee9/servlets/ThreadStarvationTest.java | 26 +-
.../test/resources/jetty-logging.properties | 6 +-
jetty-ee9/jetty-ee9-tests/pom.xml | 52 +
.../test-bad-websocket-webapp/pom.xml | 12 +-
.../bad/BadOnCloseServerEndpoint.java | 2 +-
.../bad/BadOnOpenServerEndpoint.java | 2 +-
.../webapp/websocket/bad/StringSequence.java | 2 +-
.../src/main/webapp/WEB-INF/web.xml | 0
.../src/main/webapp/index.jsp | 0
.../jetty-ee9-tests}/test-cdi/pom.xml | 28 +-
.../ee9}/cdi/tests/EmbeddedWeldTest.java | 24 +-
.../ee9}/cdi/tests/FriendlyGreetings.java | 2 +-
.../jetty/ee9}/cdi/tests/Greetings.java | 2 +-
.../ee9}/cdi/tests/GreetingsServlet.java | 2 +-
.../ee9}/cdi/tests/MyContextListener.java | 2 +-
.../jetty/ee9}/cdi/tests/MyFilter.java | 2 +-
.../websocket/JavaxWebSocketCdiTest.java | 16 +-
.../websocket/JettyWebSocketCdiTest.java | 24 +-
.../ee9}/cdi/tests/websocket/LogFactory.java | 2 +-
.../src/test/resources/META-INF/beans.xml | 0
.../test/resources/jetty-logging.properties | 2 +-
.../test-cdi/src/test/weldtest/.donotdelete | 0
.../test-http-client-transport/pom.xml | 12 +-
.../jetty/ee9}/http/client/AbstractTest.java | 2 +-
.../ee9}/http/client/AsyncIOServletTest.java | 22 +-
.../http/client/AsyncRequestContentTest.java | 2 +-
.../jetty/ee9}/http/client/BlockedIOTest.java | 2 +-
.../http/client/ConnectionStatisticsTest.java | 6 +-
.../ee9}/http/client/EmptyServerHandler.java | 2 +-
.../client/HttpChannelAssociationTest.java | 8 +-
.../client/HttpClientConnectTimeoutTest.java | 2 +-
.../http/client/HttpClientContinueTest.java | 4 +-
.../http/client/HttpClientDemandTest.java | 2 +-
.../client/HttpClientIdleTimeoutTest.java | 3 +-
.../ee9}/http/client/HttpClientLoadTest.java | 2 +-
.../http/client/HttpClientStreamTest.java | 2 +-
.../ee9}/http/client/HttpClientTest.java | 2 +-
.../http/client/HttpClientTimeoutTest.java | 2 +-
.../HttpClientTransportDynamicTest.java | 2 +-
.../ee9}/http/client/HttpTrailersTest.java | 4 +-
.../client/ProxyWithDynamicTransportTest.java | 16 +-
.../ee9}/http/client/RequestReaderTest.java | 2 +-
.../client/RoundRobinConnectionPoolTest.java | 2 +-
.../ee9}/http/client/ServerTimeoutsTest.java | 12 +-
.../jetty/ee9}/http/client/Transport.java | 2 +-
.../ee9}/http/client/TransportProvider.java | 2 +-
.../ee9}/http/client/TransportScenario.java | 6 +-
.../test/resources/jetty-logging.properties | 0
.../src/test/resources/keystore.p12 | Bin
.../test-http2-webapp/pom.xml | 21 +-
.../jetty/test/webapp/HTTP1Servlet.java | 0
.../jetty/test/webapp/HTTP2Servlet.java | 0
.../src/main/webapp/WEB-INF/web.xml | 8 +-
.../jetty/test/webapp/HTTP2FromWebAppIT.java | 2 +-
.../test/resources/jetty-logging.properties | 0
.../src/test/resources/keystore.p12 | Bin
.../jetty-ee9-tests}/test-integration/pom.xml | 40 +-
.../ee9}/test/AliasCheckerSymlinkTest.java | 9 +-
.../test/AllowedResourceAliasCheckerTest.java | 6 +-
.../ee9}/test/AnnotatedAsyncListenerTest.java | 26 +-
.../jetty/ee9}/test/CustomRequestLogTest.java | 18 +-
.../jetty/ee9}/test/DefaultHandlerTest.java | 8 +-
.../ee9}/test/DeploymentErrorInitializer.java | 2 +-
.../jetty/ee9}/test/DeploymentErrorTest.java | 18 +-
.../jetty/ee9}/test/DigestPostTest.java | 16 +-
.../jetty/ee9}/test/FailedSelectorTest.java | 6 +-
.../ee9}/test/GzipWithSendErrorTest.java | 12 +-
.../ee9}/test/HttpInputIntegrationTest.java | 10 +-
.../ee9}/test/HttpInputInterceptorTest.java | 2 +-
.../jetty/ee9}/test/KeyStoreScannerTest.java | 2 +-
.../ee9}/test/RecoverFailedSelectorTest.java | 2 +-
.../jetty/ee9}/test/jsp/FakeJspServlet.java | 2 +-
.../jsp/JspAndDefaultWithAliasesTest.java | 10 +-
.../jsp/JspAndDefaultWithoutAliasesTest.java | 10 +-
.../jetty/ee9}/test/rfcs/RFC2616BaseTest.java | 10 +-
.../ee9}/test/rfcs/RFC2616NIOHttpTest.java | 8 +-
.../ee9}/test/rfcs/RFC2616NIOHttpsTest.java | 8 +-
.../jetty/ee9}/test/support/EchoHandler.java | 2 +-
.../jetty/ee9}/test/support/StringUtil.java | 2 +-
.../test/support/XmlBasedJettyServer.java | 2 +-
.../rawhttp/HttpRequestTesterTest.java | 2 +-
.../rawhttp/HttpResponseTesterTest.java | 2 +-
.../ee9}/test/support/rawhttp/HttpSocket.java | 2 +-
.../test/support/rawhttp/HttpSocketImpl.java | 2 +-
.../test/support/rawhttp/HttpTesting.java | 2 +-
.../test/support/rawhttp/HttpsSocketImpl.java | 2 +-
.../websocket/JakartaSimpleEchoSocket.java | 2 +-
.../test/websocket/JakartaWebSocketTest.java | 6 +-
.../test/websocket/JettySimpleEchoSocket.java | 14 +-
.../test/websocket/JettyWebSocketTest.java | 10 +-
.../src/test/resources/DefaultHandler.xml | 0
.../src/test/resources/NIOHttp.xml | 0
.../src/test/resources/NIOHttps.xml | 0
.../src/test/resources/RFC2616Base.xml | 2 +-
.../src/test/resources/RFC2616_Filters.xml | 0
.../src/test/resources/RFC2616_Redirects.xml | 0
.../test/resources/add-jetty-test-webapp.xml | 2 +-
.../src/test/resources/badKeystore | Bin
.../src/test/resources/basic-server.xml | 0
.../src/test/resources/deploy.xml | 2 +-
.../test/resources/docroots/default/R1.txt | 0
.../test/resources/docroots/default/R2.txt | 0
.../test/resources/docroots/default/R3.txt | 0
.../test/resources/docroots/default/alpha.txt | 0
.../resources/docroots/default/index.html | 0
.../resources/docroots/default/quotes.txt | 0
.../deployerror/badapp-unavailable-false.xml | 2 +-
.../resources/docroots/deployerror/badapp.xml | 2 +-
...akarta.servlet.ServletContainerInitializer | 0
.../deployerror/badapp/WEB-INF/web.xml | 0
.../src/test/resources/docroots/jsp/dump.jsp | 0
.../resources/docroots/virtualhost/R1.txt | 0
.../resources/docroots/virtualhost/R2.txt | 0
.../resources/docroots/virtualhost/R3.txt | 0
.../resources/docroots/virtualhost/index.html | 0
.../test-integration/src/test/resources/file | 0
.../test/resources/jetty-logging.properties | 0
.../src/test/resources/keystore.p12 | Bin
.../src/test/resources/logback.xml | 0
.../src/test/resources/login-service.xml | 0
.../src/test/resources/message.txt | 0
.../src/test/resources/newKeystore | Bin
.../src/test/resources/oldKeystore | Bin
.../src/test/resources/realm.properties | 2 +-
.../src/test/resources/sibling/file | 0
.../src/test/resources/ssl.xml | 0
.../RFC2616/rfc2616-webapp.xml | 2 +-
.../src/test/resources/webdefault.xml | 12 +-
.../test/resources/webroot/WEB-INF/web.xml | 0
.../src/test/resources/webroot/documents/file | 0
.../src/test/resources/webroot/file | 0
.../src/test/resources/webroot/index.html | 0
.../src/test/resources/zeros.gz.gz | Bin
.../test-jmx/jmx-webapp-it/pom.xml | 14 +-
.../eclipse/jetty/ee9}/test/jmx/JmxIT.java | 6 +-
.../test-jmx/jmx-webapp/pom.xml | 8 +-
.../jetty/ee9}/test/jmx/CommonComponent.java | 2 +-
.../eclipse/jetty/ee9}/test/jmx/Echoer.java | 2 +-
.../ee9}/test/jmx/MyContainerInitializer.java | 2 +-
.../jetty/ee9}/test/jmx/PingServlet.java | 2 +-
.../eclipse/jetty/ee9}/test/jmx/Pinger.java | 2 +-
.../jetty/ee9}/test/jmx/jmx/EchoerMBean.java | 2 +-
.../jetty/ee9}/test/jmx/jmx/PingerMBean.java | 4 +-
...akarta.servlet.ServletContainerInitializer | 0
.../src/main/webapp/WEB-INF/web.xml | 0
.../jmx-webapp/src/main/webapp/index.html | 0
.../jetty-ee9-tests}/test-jmx/pom.xml | 10 +-
.../jetty-ee9-tests}/test-jndi/pom.xml | 8 +-
.../factories/TestMailSessionReference.java | 3 +-
.../test-loginservice/pom.xml | 20 +-
.../DataSourceLoginServiceTest.java | 6 +-
.../DatabaseLoginServiceTestServer.java | 14 +-
.../loginservice}/JdbcLoginServiceTest.java | 4 +-
.../src/test/resources/createdb.sql | 0
.../src/test/resources/droptables.sql | 0
.../src/test/resources/jdbcrealm.properties | 0
.../test/resources/jetty-logging.properties | 0
.../jetty-ee9-tests}/test-quickstart/pom.xml | 60 +-
.../quickstart/AttributeNormalizerTest.java | 2 +-
...AttributeNormalizerToCanonicalUriTest.java | 2 +-
.../jetty/ee9}/quickstart/EnvUtils.java | 2 +-
.../ee9}/quickstart/PreconfigureJNDIWar.java | 2 +-
.../ee9}/quickstart/PreconfigureSpecWar.java | 2 +-
.../PreconfigureStandardTestWar.java | 2 +-
.../ee9}/quickstart/QuickStartJNDIWar.java | 2 +-
.../ee9}/quickstart/QuickStartSpecWar.java | 2 +-
.../quickstart/QuickStartStandardTestWar.java | 2 +-
.../jetty/ee9}/quickstart/QuickStartTest.java | 12 +-
.../jetty/ee9}/quickstart/Quickstart.java | 10 +-
.../test/resources/jetty-logging.properties | 0
.../src/test/resources/realm.properties | 2 +-
.../src/test/resources/test-jndi.xml | 2 +-
.../src/test/resources/test-spec.xml | 2 +-
.../src/test/resources/test.xml | 2 +-
.../pom.xml | 12 +-
.../tests/webapp/websocket/EchoEndpoint.java | 2 +-
.../websocket/WebSocketClientServlet.java | 16 +-
.../resources/jetty-websocket-httpclient.xml | 0
.../src/main/webapp/WEB-INF/web.xml | 0
.../test-websocket-client-webapp/pom.xml | 12 +-
.../tests/webapp/websocket/EchoEndpoint.java | 2 +-
.../websocket/WebSocketClientServlet.java | 16 +-
.../src/main/webapp/WEB-INF/web.xml | 0
.../test-websocket-webapp/pom.xml | 12 +-
.../tests/webapp/websocket/EchoEndpoint.java | 2 +-
.../webapp/websocket/StringSequence.java | 2 +-
.../websocket/StringSequenceDecoder.java | 2 +-
.../src/main/webapp/WEB-INF/web.xml | 0
.../src/main/webapp/index.jsp | 0
.../jetty-ee9-webapp}/pom.xml | 26 +-
.../src/main/config/etc/jetty-webapp.xml | 4 +-
.../src/main/config/etc/webdefault.xml | 12 +-
.../src/main/java/module-info.java | 53 +
.../jetty/ee9/webapp/AbsoluteOrdering.java | 2 +-
.../ee9/webapp/AbstractConfiguration.java | 2 +-
.../ee9/webapp/CachingWebAppClassLoader.java | 2 +-
.../jetty/ee9/webapp/ClassMatcher.java | 2 +-
.../jetty/ee9/webapp/Configuration.java | 4 +-
.../jetty/ee9/webapp/Configurations.java | 2 +-
.../jetty/ee9/webapp/DecoratingListener.java | 12 +-
.../jetty/ee9/webapp/DefaultsDescriptor.java | 2 +-
.../eclipse/jetty/ee9/webapp/Descriptor.java | 2 +-
.../jetty/ee9/webapp/DescriptorProcessor.java | 2 +-
.../ee9/webapp/DiscoveredAnnotation.java | 2 +-
.../ee9/webapp/FragmentConfiguration.java | 2 +-
.../jetty/ee9/webapp/FragmentDescriptor.java | 2 +-
.../webapp/IterativeDescriptorProcessor.java | 2 +-
.../jetty/ee9/webapp/JaasConfiguration.java | 2 +-
.../jetty/ee9/webapp/JaspiConfiguration.java | 2 +-
.../ee9/webapp/JettyWebXmlConfiguration.java | 4 +-
.../jetty/ee9/webapp/JmxConfiguration.java | 2 +-
.../jetty/ee9/webapp/JndiConfiguration.java | 2 +-
.../jetty/ee9/webapp/JspConfiguration.java | 2 +-
.../eclipse/jetty/ee9/webapp/MetaData.java | 4 +-
.../ee9/webapp/MetaInfConfiguration.java | 2 +-
.../eclipse/jetty/ee9/webapp/Ordering.java | 2 +-
.../org/eclipse/jetty/ee9/webapp/Origin.java | 2 +-
.../jetty/ee9/webapp/OverrideDescriptor.java | 2 +-
.../jetty/ee9/webapp/RelativeOrdering.java | 2 +-
.../ee9/webapp/ServletsConfiguration.java | 10 +-
.../webapp/StandardDescriptorProcessor.java | 33 +-
.../jetty/ee9/webapp/WebAppClassLoader.java | 4 +-
.../jetty/ee9/webapp/WebAppConfiguration.java | 10 +-
.../jetty/ee9/webapp/WebAppContext.java | 88 +-
.../jetty/ee9/webapp/WebDescriptor.java | 2 +-
.../jetty/ee9/webapp/WebInfConfiguration.java | 6 +-
.../jetty/ee9/webapp/WebXmlConfiguration.java | 4 +-
.../jetty/ee9}/webapp/package-info.java | 2 +-
...org.eclipse.jetty.ee9.webapp.Configuration | 12 +
.../java/org/acme/webapp/TestAnnotation.java | 4 +-
.../jetty/ee9/webapp/ClassMatcherTest.java | 8 +-
.../jetty/ee9/webapp/ConfigurationsTest.java | 4 +-
.../jetty/ee9/webapp/ForcedServletTest.java | 10 +-
.../jetty/ee9/webapp/HugeResourceTest.java | 12 +-
.../ee9/webapp/MetaInfConfigurationTest.java | 4 +-
.../jetty/ee9/webapp/OrderingTest.java | 2 +-
.../StandardDescriptorProcessorTest.java | 2 +-
.../eclipse/jetty/ee9/webapp/TempDirTest.java | 2 +-
.../jetty/ee9/webapp/TestMetaData.java | 2 +-
.../ee9/webapp/URLStreamHandlerUtil.java | 2 +-
.../ee9/webapp/WebAppClassLoaderTest.java | 36 +-
.../WebAppClassLoaderUrlStreamTest.java | 2 +-
.../jetty/ee9/webapp/WebAppContextTest.java | 61 +-
.../ee9/webapp/WebAppDefaultServletTest.java | 18 +-
.../ee9/webapp/WebInfConfigurationTest.java | 2 +-
.../test/resources/jetty-logging.properties | 2 +-
.../src/test/resources/org/acme/resource.txt | 0
.../src/test/webapp-alt-jsp/WEB-INF/web.xml | 2 +-
.../WEB-INF/classes/org/acme/resource.txt | 0
.../src/test/webapp/WEB-INF/test.xml | 0
.../src/test/webapp/test.xml | 0
.../pom.xml | 14 +-
.../src/main/java/module-info.java | 12 +-
...kartaWebSocketClientContainerProvider.java | 4 +-
.../JakartaWebSocketShutdownContainer.java | 4 +-
.../AnnotatedClientEndpointConfig.java | 4 +-
.../internal/BasicClientEndpointConfig.java | 4 +-
.../client/internal/EmptyConfigurator.java | 2 +-
.../internal/JakartaClientUpgradeRequest.java | 6 +-
.../JakartaWebSocketClientContainer.java | 12 +-
...rtaWebSocketClientFrameHandlerFactory.java | 8 +-
.../client/internal/JsrUpgradeListener.java | 2 +-
...akarta.servlet.ServletContainerInitializer | 0
.../SecureClientContainerExample.java | 2 +-
.../test/resources/jetty-logging.properties | 0
.../resources/jetty-websocket-httpclient.xml | 0
.../pom.xml | 10 +-
.../src/main/java/module-info.java | 10 +-
.../common/ClientEndpointConfigWrapper.java | 2 +-
.../jakarta/common/ConfiguredEndpoint.java | 2 +-
.../jakarta/common/EndpointConfigWrapper.java | 2 +-
.../jakarta/common/InitException.java | 2 +-
.../common/JakartaWebSocketAsyncRemote.java | 2 +-
.../common/JakartaWebSocketBasicRemote.java | 2 +-
.../common/JakartaWebSocketContainer.java | 2 +-
.../common/JakartaWebSocketExtension.java | 2 +-
.../JakartaWebSocketExtensionConfig.java | 2 +-
.../common/JakartaWebSocketFrameHandler.java | 14 +-
.../JakartaWebSocketFrameHandlerFactory.java | 14 +-
.../JakartaWebSocketFrameHandlerMetadata.java | 6 +-
.../JakartaWebSocketMessageMetadata.java | 4 +-
.../common/JakartaWebSocketPongMessage.java | 2 +-
.../JakartaWebSocketRemoteEndpoint.java | 2 +-
.../common/JakartaWebSocketSession.java | 6 +-
.../JakartaWebSocketSessionListener.java | 2 +-
.../jakarta/common/PathParamProvider.java | 2 +-
.../jakarta/common/PutListenerMap.java | 2 +-
.../common/RegisteredMessageHandler.java | 2 +-
.../jakarta/common/SendHandlerCallback.java | 2 +-
.../common/ServerEndpointConfigWrapper.java | 2 +-
.../jakarta/common/SessionTracker.java | 2 +-
.../jakarta/common/UpgradeRequest.java | 2 +-
.../jakarta/common/UpgradeRequestAdapter.java | 2 +-
.../common/decoders/AbstractDecoder.java | 2 +-
.../common/decoders/AvailableDecoders.java | 2 +-
.../common/decoders/BooleanDecoder.java | 2 +-
.../common/decoders/ByteArrayDecoder.java | 2 +-
.../common/decoders/ByteBufferDecoder.java | 2 +-
.../jakarta/common/decoders/ByteDecoder.java | 2 +-
.../common/decoders/CharacterDecoder.java | 2 +-
.../common/decoders/DoubleDecoder.java | 2 +-
.../jakarta/common/decoders/FloatDecoder.java | 2 +-
.../common/decoders/InputStreamDecoder.java | 2 +-
.../common/decoders/IntegerDecoder.java | 2 +-
.../jakarta/common/decoders/LongDecoder.java | 2 +-
.../common/decoders/ReaderDecoder.java | 2 +-
.../common/decoders/RegisteredDecoder.java | 4 +-
.../jakarta/common/decoders/ShortDecoder.java | 2 +-
.../common/decoders/StringDecoder.java | 2 +-
.../common/encoders/AbstractEncoder.java | 2 +-
.../common/encoders/AvailableEncoders.java | 4 +-
.../common/encoders/BooleanEncoder.java | 2 +-
.../common/encoders/ByteArrayEncoder.java | 2 +-
.../common/encoders/ByteBufferEncoder.java | 2 +-
.../jakarta/common/encoders/ByteEncoder.java | 2 +-
.../common/encoders/CharacterEncoder.java | 2 +-
.../common/encoders/DoubleEncoder.java | 2 +-
.../common/encoders/EncodeFailedFuture.java | 2 +-
.../jakarta/common/encoders/FloatEncoder.java | 2 +-
.../common/encoders/IntegerEncoder.java | 2 +-
.../jakarta/common/encoders/LongEncoder.java | 2 +-
.../common/encoders/RegisteredEncoder.java | 2 +-
.../jakarta/common/encoders/ShortEncoder.java | 2 +-
.../common/encoders/StringEncoder.java | 2 +-
.../messages/AbstractDecodedMessageSink.java | 4 +-
.../messages/DecodedBinaryMessageSink.java | 6 +-
.../DecodedBinaryStreamMessageSink.java | 6 +-
.../messages/DecodedTextMessageSink.java | 6 +-
.../DecodedTextStreamMessageSink.java | 6 +-
...tractJakartaWebSocketFrameHandlerTest.java | 6 +-
.../jakarta/common/AbstractSessionTest.java | 2 +-
.../websocket/jakarta/common/Defaults.java | 2 +-
.../jakarta/common/DummyContainer.java | 2 +-
.../common/DummyFrameHandlerFactory.java | 2 +-
...ebSocketFrameHandlerBadSignaturesTest.java | 2 +-
...kartaWebSocketFrameHandlerOnCloseTest.java | 4 +-
...kartaWebSocketFrameHandlerOnErrorTest.java | 4 +-
...FrameHandlerOnMessageBinaryStreamTest.java | 4 +-
...SocketFrameHandlerOnMessageBinaryTest.java | 4 +-
...etFrameHandlerOnMessageTextStreamTest.java | 4 +-
...ebSocketFrameHandlerOnMessageTextTest.java | 4 +-
...akartaWebSocketFrameHandlerOnOpenTest.java | 4 +-
.../common/coders/tests/BadDualDecoder.java | 2 +-
.../common/coders/tests/BadDualEncoder.java | 2 +-
.../common/coders/tests/ExtDecoder.java | 2 +-
.../jakarta/common/coders/tests/Fruit.java | 2 +-
.../coders/tests/FruitBinaryEncoder.java | 2 +-
.../common/coders/tests/FruitDecoder.java | 2 +-
.../common/coders/tests/FruitTextEncoder.java | 2 +-
.../endpoints/AbstractStringEndpoint.java | 4 +-
.../common/endpoints/DummyEndpoint.java | 2 +-
.../common/endpoints/EchoStringEndpoint.java | 2 +-
.../common/handlers/BaseMessageHandler.java | 2 +-
.../handlers/ByteArrayPartialHandler.java | 2 +-
.../handlers/ByteArrayWholeHandler.java | 2 +-
.../handlers/ByteBufferPartialHandler.java | 2 +-
.../handlers/ByteBufferWholeHandler.java | 2 +-
.../common/handlers/ComboMessageHandler.java | 2 +-
.../handlers/ExtendedMessageHandler.java | 2 +-
.../handlers/InputStreamWholeHandler.java | 2 +-
.../common/handlers/LongMessageHandler.java | 2 +-
.../common/handlers/ReaderWholeHandler.java | 2 +-
.../common/handlers/StringPartialHandler.java | 2 +-
.../common/handlers/StringWholeHandler.java | 2 +-
.../messages/AbstractMessageSinkTest.java | 8 +-
.../DecodedBinaryMessageSinkTest.java | 6 +-
.../DecodedBinaryStreamMessageSinkTest.java | 4 +-
.../messages/DecodedTextMessageSinkTest.java | 4 +-
.../DecodedTextStreamMessageSinkTest.java | 4 +-
.../messages/InputStreamMessageSinkTest.java | 4 +-
.../common/messages/MessageWriterTest.java | 2 +-
.../messages/ReaderMessageSinkTest.java | 2 +-
.../common/sockets/TrackingSocket.java | 2 +-
.../util/InvokerUtilsStaticParamsTest.java | 4 +-
.../jakarta/common/util/InvokerUtilsTest.java | 2 +-
.../common/util/NameParamIdentifier.java | 2 +-
.../jakarta/common/util/ReflectUtilsTest.java | 2 +-
.../test/resources/jetty-logging.properties | 0
.../src/test/resources/quotes-ben.txt | 0
.../src/test/resources/quotes-twain.txt | 0
.../pom.xml | 24 +-
.../src/main/java/module-info.java | 20 +-
.../config/ContainerDefaultConfigurator.java | 2 +-
.../config/JakartaWebSocketConfiguration.java | 16 +-
...aWebSocketServletContainerInitializer.java | 10 +-
.../AnnotatedServerEndpointConfig.java | 8 +-
.../internal/BasicServerEndpointConfig.java | 6 +-
.../internal/JakartaServerUpgradeRequest.java | 4 +-
.../internal/JakartaWebSocketCreator.java | 39 +-
.../JakartaWebSocketServerContainer.java | 10 +-
...rtaWebSocketServerFrameHandlerFactory.java | 8 +-
.../server/internal/JsrHandshakeRequest.java | 2 +-
.../server/internal/JsrHandshakeResponse.java | 2 +-
.../server/internal/PathParamIdentifier.java | 2 +-
.../PathParamServerEndpointConfig.java | 6 +-
...akarta.servlet.ServletContainerInitializer | 0
.../org.eclipse.jetty.webapp.Configuration | 0
.../browser/JsrBrowserConfigurator.java | 2 +-
.../server/browser/JsrBrowserDebugTool.java | 10 +-
.../server/browser/JsrBrowserSocket.java | 2 +-
.../test/resources/jetty-logging.properties | 0
.../jsr-browser-debug-tool/index.html | 0
.../resources/jsr-browser-debug-tool/main.css | 0
.../jsr-browser-debug-tool/websocket.js | 0
.../fuzzingclient.json | 18 +
.../fuzzingserver.json | 10 +
.../pom.xml | 20 +-
.../ee9/websocket/jakarta/tests/BadFrame.java | 2 +-
.../tests/BiConsumerServiceServlet.java | 2 +-
.../tests/CompletableFutureMethodHandle.java | 4 +-
.../websocket/jakarta/tests/CoreServer.java | 6 +-
.../websocket/jakarta/tests/DataUtils.java | 2 +-
.../jakarta/tests/DummyEndpoint.java | 2 +-
.../websocket/jakarta/tests/EchoSocket.java | 2 +-
.../websocket/jakarta/tests/EventSocket.java | 2 +-
.../jakarta/tests/FunctionMethod.java | 2 +-
.../ee9/websocket/jakarta/tests/Fuzzer.java | 2 +-
.../websocket/jakarta/tests/LocalFuzzer.java | 2 +-
.../websocket/jakarta/tests/LocalServer.java | 14 +-
.../websocket/jakarta/tests/MessageType.java | 2 +-
.../jakarta/tests/NetworkFuzzer.java | 2 +-
.../jakarta/tests/ParserCapture.java | 2 +-
.../jakarta/tests/RawFrameBuilder.java | 2 +-
.../jakarta/tests/SessionMatchers.java | 8 +-
.../ee9/websocket/jakarta/tests/Sha1Sum.java | 2 +-
.../ee9/websocket/jakarta/tests/Timeouts.java | 2 +-
.../jakarta/tests/UnitGenerator.java | 2 +-
.../websocket/jakarta/tests/UpgradeUtils.java | 2 +-
.../jakarta/tests/WSEndpointTracker.java | 2 +-
.../jakarta/tests/WSEventTracker.java | 2 +-
.../ee9/websocket/jakarta/tests/WSServer.java | 11 +-
.../ee9}/websocket/jakarta/tests/WSURI.java | 2 +-
.../tests/framehandlers/FrameEcho.java | 2 +-
.../framehandlers/FrameHandlerTracker.java | 2 +-
.../tests/framehandlers/StaticText.java | 2 +-
.../tests/framehandlers/WholeMessageEcho.java | 2 +-
.../tests/matchers/IsMessageHandlerType.java | 8 +-
.../IsMessageHandlerTypeRegistered.java | 10 +-
.../com/acme/websocket/BasicEchoEndpoint.java | 0
...asicEchoEndpointConfigContextListener.java | 0
.../websocket/IdleTimeoutContextListener.java | 0
.../websocket/IdleTimeoutOnOpenEndpoint.java | 0
.../websocket/IdleTimeoutOnOpenSocket.java | 0
.../websocket/LargeEchoContextListener.java | 0
.../websocket/LargeEchoDefaultSocket.java | 0
.../websocket/OnOpenIdleTimeoutEndpoint.java | 0
.../acme/websocket/PongContextListener.java | 0
.../acme/websocket/PongMessageEndpoint.java | 0
.../java/com/acme/websocket/PongSocket.java | 0
.../jakarta/tests/CloseInOnOpenTest.java | 10 +-
.../jakarta/tests/GracefulCloseTest.java | 8 +-
.../tests/JakartaClientClassLoaderTest.java | 12 +-
...aClientShutdownWithServerEmbeddedTest.java | 10 +-
...rtaClientShutdownWithServerWebAppTest.java | 14 +-
.../jakarta/tests/JakartaOnCloseTest.java | 8 +-
.../tests/JakartaWebSocketRestartTest.java | 14 +-
.../tests/JettySpecificConfigTest.java | 8 +-
.../jakarta/tests/PathParamTest.java | 42 +-
.../ProgrammaticWebSocketUpgradeTest.java | 12 +-
.../jakarta/tests/RestartContextTest.java | 8 +-
.../jakarta/tests/ServerConfigTest.java | 6 +-
.../tests/SingleMessageHandlerTest.java | 8 +-
.../jakarta/tests/SyntheticOnMessageTest.java | 6 +-
.../tests/UpgradeRequestResponseTest.java | 8 +-
.../autobahn}/JakartaAutobahnClient.java | 56 +-
.../autobahn}/JakartaAutobahnServer.java | 43 +-
.../autobahn}/JakartaAutobahnSocket.java | 4 +-
.../client/AbstractClientSessionTest.java | 18 +-
.../client/AnnotatedClientEndpointTest.java | 8 +-
.../tests/client/AnnotatedEchoClient.java | 2 +-
.../tests/client/AnnotatedEchoTest.java | 4 +-
.../tests/client/ConfiguratorTest.java | 6 +-
.../jakarta/tests/client/CookiesTest.java | 10 +-
.../client/DecoderReaderManySmallTest.java | 6 +-
.../tests/client/DelayedStartClientTest.java | 2 +-
.../tests/client/EndpointEchoTest.java | 8 +-
.../client/JsrClientEchoTrackingSocket.java | 6 +-
.../tests/client/JsrClientTrackingSocket.java | 6 +-
.../tests/client/MessageReceivingTest.java | 6 +-
.../jakarta/tests/client/OnCloseTest.java | 24 +-
.../client/SessionAddMessageHandlerTest.java | 30 +-
.../tests/client/WriteTimeoutTest.java | 10 +-
.../misbehaving/AnnotatedRuntimeOnOpen.java | 2 +-
.../misbehaving/EndpointRuntimeOnOpen.java | 2 +-
.../misbehaving/MisbehavingClassTest.java | 4 +-
.../samples/CloseEndpointConfigSocket.java | 4 +-
.../samples/CloseReasonSessionSocket.java | 4 +-
.../client/samples/CloseReasonSocket.java | 4 +-
.../samples/CloseSessionReasonSocket.java | 4 +-
.../client/samples/CloseSessionSocket.java | 4 +-
.../tests/client/samples/CloseSocket.java | 4 +-
.../tests/client/samples/IntSocket.java | 4 +-
.../tests/coders/AvailableDecodersTest.java | 8 +-
.../tests/coders/AvailableEncodersTest.java | 8 +-
.../jakarta/tests/coders/BadDualDecoder.java | 2 +-
.../jakarta/tests/coders/BadDualEncoder.java | 2 +-
.../tests/coders/CoderEventTracking.java | 2 +-
.../jakarta/tests/coders/DateDecoder.java | 2 +-
.../jakarta/tests/coders/DateEncoder.java | 2 +-
.../jakarta/tests/coders/DateTimeDecoder.java | 2 +-
.../jakarta/tests/coders/DateTimeEncoder.java | 2 +-
.../jakarta/tests/coders/DecoderListTest.java | 14 +-
.../tests/coders/DecoderTextStreamTest.java | 10 +-
.../jakarta/tests/coders/DecoderTextTest.java | 2 +-
.../tests/coders/EncoderLifeCycleTest.java | 12 +-
.../jakarta/tests/coders/EncoderTextTest.java | 2 +-
.../jakarta/tests/coders/ExtDecoder.java | 2 +-
.../tests/coders/FloatDecoderTest.java | 4 +-
.../websocket/jakarta/tests/coders/Fruit.java | 2 +-
.../tests/coders/FruitBinaryEncoder.java | 2 +-
.../jakarta/tests/coders/FruitDecoder.java | 2 +-
.../tests/coders/FruitTextEncoder.java | 2 +-
.../tests/coders/IntegerDecoderTest.java | 4 +-
.../jakarta/tests/coders/LongDecoderTest.java | 4 +-
.../jakarta/tests/coders/Quotes.java | 2 +-
.../jakarta/tests/coders/QuotesDecoder.java | 2 +-
.../jakarta/tests/coders/QuotesEncoder.java | 2 +-
.../jakarta/tests/coders/QuotesUtil.java | 2 +-
.../tests/coders/ShortDecoderTest.java | 4 +-
.../jakarta/tests/coders/TimeDecoder.java | 2 +-
.../jakarta/tests/coders/TimeEncoder.java | 2 +-
.../tests/coders/ValidDualDecoder.java | 2 +-
.../tests/coders/ValidDualEncoder.java | 2 +-
.../handlers/AbstractAnnotatedHandler.java | 2 +-
.../tests/handlers/AbstractHandler.java | 2 +-
.../tests/handlers/BaseMessageHandler.java | 2 +-
.../tests/handlers/BinaryHandlers.java | 2 +-
.../tests/handlers/ComboMessageHandler.java | 2 +-
.../handlers/ExtendedMessageHandler.java | 2 +-
.../tests/handlers/LongMessageHandler.java | 2 +-
.../tests/handlers/MessageHandlerTest.java | 8 +-
.../jakarta/tests/handlers/TextHandlers.java | 2 +-
.../tests/pathparam/BooleanClassSocket.java | 2 +-
.../tests/pathparam/BooleanTypeSocket.java | 2 +-
.../tests/pathparam/ByteClassSocket.java | 2 +-
.../tests/pathparam/ByteTypeSocket.java | 2 +-
.../tests/pathparam/CharacterClassSocket.java | 2 +-
.../tests/pathparam/CharacterTypeSocket.java | 2 +-
.../tests/pathparam/DoubleClassSocket.java | 2 +-
.../tests/pathparam/DoubleTypeSocket.java | 2 +-
.../tests/pathparam/FloatClassSocket.java | 2 +-
.../tests/pathparam/FloatTypeSocket.java | 2 +-
.../tests/pathparam/IntegerClassSocket.java | 2 +-
.../tests/pathparam/IntegerTypeSocket.java | 2 +-
.../tests/pathparam/LongClassSocket.java | 2 +-
.../tests/pathparam/LongTypeSocket.java | 2 +-
.../tests/pathparam/ShortClassSocket.java | 2 +-
.../tests/pathparam/ShortTypeSocket.java | 2 +-
.../tests/pathparam/StringClassSocket.java | 2 +-
.../jakarta/tests/quotes/Quotes.java | 2 +-
.../jakarta/tests/quotes/QuotesDecoder.java | 2 +-
.../tests/quotes/QuotesDecoderTest.java | 6 +-
.../quotes/QuotesDecoderTextStreamTest.java | 6 +-
.../jakarta/tests/quotes/QuotesEncoder.java | 2 +-
.../tests/quotes/QuotesEncoderTest.java | 6 +-
.../jakarta/tests/quotes/QuotesSocket.java | 4 +-
.../jakarta/tests/quotes/QuotesUtil.java | 2 +-
...akartaWebSocketServerFrameHandlerTest.java | 14 +-
.../jakarta/tests/server/AddEndpointTest.java | 10 +-
.../jakarta/tests/server/AltFilterTest.java | 12 +-
.../server/AnnotatedServerEndpointTest.java | 14 +-
...asicEchoEndpointConfigContextListener.java | 4 +-
.../BasicEchoEndpointContextListener.java | 4 +-
.../BasicEchoSocketConfigContextListener.java | 4 +-
.../BasicEchoSocketContextListener.java | 4 +-
.../tests/server/BinaryStreamTest.java | 10 +-
.../tests/server/ConfiguratorTest.java | 10 +-
.../server/ContainerProviderServerTest.java | 6 +-
.../tests/server/DeploymentExceptionTest.java | 18 +-
.../jakarta/tests/server/DeploymentTest.java | 10 +-
.../tests/server/EndpointViaConfigTest.java | 6 +-
.../server/IdleTimeoutContextListener.java | 4 +-
.../jakarta/tests/server/IdleTimeoutTest.java | 6 +-
.../tests/server/InputStreamEchoTest.java | 6 +-
...etFrameHandlerOnMessageTextStreamTest.java | 10 +-
.../JettyServerEndpointConfiguratorTest.java | 4 +-
.../tests/server/JsrBatchModeTest.java | 4 +-
.../jakarta/tests/server/JsrEchoTest.java | 6 +-
.../tests/server/LargeAnnotatedTest.java | 6 +-
.../tests/server/LargeContainerTest.java | 6 +-
.../server/LargeEchoContextListener.java | 2 +-
.../jakarta/tests/server/MemoryUsageTest.java | 6 +-
.../tests/server/OnMessageReturnTest.java | 6 +-
.../jakarta/tests/server/PartialEchoTest.java | 6 +-
.../jakarta/tests/server/PingPongTest.java | 8 +-
.../tests/server/PongContextListener.java | 4 +-
.../jakarta/tests/server/PongSocket.java | 2 +-
.../server/PrimitivesBinaryEchoTest.java | 8 +-
.../tests/server/PrimitivesTextEchoTest.java | 8 +-
.../jakarta/tests/server/ReaderEchoTest.java | 6 +-
.../tests/server/ServerDecoderTest.java | 12 +-
.../jakarta/tests/server/SessionTest.java | 10 +-
.../tests/server/SessionTrackingTest.java | 8 +-
.../jakarta/tests/server/StreamTest.java | 8 +-
.../jakarta/tests/server/TextStreamTest.java | 12 +-
.../server/UriTemplateParameterTest.java | 6 +-
.../tests/server/WebAppClassLoaderTest.java | 10 +-
.../WebSocketServerContainerExecutorTest.java | 12 +-
.../configs/EchoSocketConfigurator.java | 2 +-
.../examples/GetHttpSessionConfigurator.java | 2 +-
.../server/examples/GetHttpSessionSocket.java | 2 +-
.../server/examples/MyAuthedConfigurator.java | 2 +-
.../tests/server/examples/MyAuthedSocket.java | 2 +-
.../server/examples/StreamingEchoSocket.java | 2 +-
.../examples/WebSocketServerExamplesTest.java | 18 +-
.../BasicBinaryMessageByteBufferSocket.java | 2 +-
.../BasicCloseReasonSessionSocket.java | 2 +-
.../sockets/BasicCloseReasonSocket.java | 2 +-
.../BasicCloseSessionReasonSocket.java | 2 +-
.../server/sockets/BasicCloseSocket.java | 2 +-
.../tests/server/sockets/BasicEchoSocket.java | 2 +-
.../sockets/BasicErrorSessionSocket.java | 2 +-
.../BasicErrorSessionThrowableSocket.java | 2 +-
.../server/sockets/BasicErrorSocket.java | 2 +-
.../BasicErrorThrowableSessionSocket.java | 2 +-
.../sockets/BasicErrorThrowableSocket.java | 2 +-
.../sockets/BasicOpenCloseSessionSocket.java | 2 +-
.../server/sockets/BasicOpenCloseSocket.java | 2 +-
.../sockets/BasicOpenSessionSocket.java | 2 +-
.../tests/server/sockets/BasicOpenSocket.java | 2 +-
.../sockets/BasicPongMessageSocket.java | 2 +-
.../sockets/BasicTextMessageStringSocket.java | 2 +-
.../server/sockets/ByteBufferSocket.java | 2 +-
.../server/sockets/ConfiguredEchoSocket.java | 8 +-
.../tests/server/sockets/DateTextSocket.java | 6 +-
.../sockets/IdleTimeoutOnOpenEndpoint.java | 2 +-
.../sockets/IdleTimeoutOnOpenSocket.java | 2 +-
.../server/sockets/InvalidCloseIntSocket.java | 2 +-
.../sockets/InvalidErrorErrorSocket.java | 2 +-
.../server/sockets/InvalidErrorIntSocket.java | 2 +-
.../sockets/InvalidOpenCloseReasonSocket.java | 2 +-
.../server/sockets/InvalidOpenIntSocket.java | 2 +-
.../sockets/InvalidOpenSessionIntSocket.java | 2 +-
.../StatelessTextMessageStringSocket.java | 2 +-
.../tests/server/sockets/TrackingSocket.java | 2 +-
.../sockets/binary/ByteBufferSocket.java | 2 +-
.../sockets/echo/BasicEchoEndpoint.java | 2 +-
.../server/sockets/echo/BasicEchoSocket.java | 2 +-
.../sockets/echo/EchoAsyncTextSocket.java | 2 +-
.../sockets/echo/EchoBasicTextSocket.java | 2 +-
.../sockets/echo/EchoReturnEndpoint.java | 2 +-
.../sockets/echo/EchoReturnTextSocket.java | 2 +-
.../echo/EchoStatelessAsyncTextSocket.java | 2 +-
.../echo/EchoStatelessBasicTextSocket.java | 2 +-
.../echo/LargeEchoConfiguredSocket.java | 2 +-
.../sockets/echo/LargeEchoDefaultSocket.java | 2 +-
.../OnOpenIdleTimeoutEndpoint.java | 2 +-
.../idletimeout/OnOpenIdleTimeoutSocket.java | 2 +-
.../partial/PartialTextSessionSocket.java | 2 +-
.../sockets/partial/PartialTextSocket.java | 2 +-
.../partial/PartialTrackingSocket.java | 4 +-
.../sockets/pong/PongMessageEndpoint.java | 2 +-
.../BooleanObjectTextParamSocket.java | 2 +-
.../primitives/BooleanObjectTextSocket.java | 2 +-
.../primitives/BooleanTextParamSocket.java | 2 +-
.../sockets/primitives/BooleanTextSocket.java | 2 +-
.../primitives/ByteObjectTextSocket.java | 2 +-
.../sockets/primitives/ByteTextSocket.java | 2 +-
.../sockets/primitives/CharTextSocket.java | 2 +-
.../primitives/CharacterObjectTextSocket.java | 2 +-
.../primitives/DoubleObjectTextSocket.java | 2 +-
.../sockets/primitives/DoubleTextSocket.java | 2 +-
.../primitives/FloatObjectTextSocket.java | 2 +-
.../sockets/primitives/FloatTextSocket.java | 2 +-
.../primitives/IntParamTextSocket.java | 2 +-
.../sockets/primitives/IntTextSocket.java | 2 +-
.../IntegerObjectParamTextSocket.java | 2 +-
.../primitives/IntegerObjectTextSocket.java | 2 +-
.../primitives/LongObjectTextSocket.java | 2 +-
.../sockets/primitives/LongTextSocket.java | 2 +-
.../primitives/ShortObjectTextSocket.java | 2 +-
.../sockets/primitives/ShortTextSocket.java | 2 +-
.../sockets/streaming/InputStreamSocket.java | 2 +-
.../sockets/streaming/ReaderParamSocket.java | 2 +-
.../sockets/streaming/ReaderSocket.java | 2 +-
.../StringReturnReaderParamSocket.java | 2 +-
.../test/resources/jetty-logging.properties | 0
.../resources/jetty-websocket-httpclient.xml | 0
.../src/test/resources/keystore.p12 | Bin
.../src/test/resources/quotes-ben.txt | 0
.../src/test/resources/quotes-twain.txt | 0
.../simple/jetty-websocket-httpclient.xml | 0
.../src/test/webapp/index.html | 0
.../jetty-ee9-websocket-jetty-api}/pom.xml | 10 +-
.../src/main/java/module-info.java | 22 +
.../jetty/ee9/websocket/api/BatchMode.java | 2 +-
.../jetty/ee9/websocket/api/CloseStatus.java | 2 +-
.../ee9/websocket/api/ExtensionConfig.java | 2 +-
.../jetty/ee9/websocket/api/Frame.java | 2 +-
.../ee9/websocket/api/RemoteEndpoint.java | 2 +-
.../jetty/ee9/websocket/api/Session.java | 4 +-
.../jetty/ee9/websocket/api/StatusCode.java | 2 +-
.../jetty/ee9/websocket/api/SuspendToken.java | 2 +-
.../ee9}/websocket/api/UpgradeRequest.java | 2 +-
.../ee9/websocket/api/UpgradeResponse.java | 2 +-
.../ee9/websocket/api/WebSocketAdapter.java | 2 +-
.../ee9/websocket/api/WebSocketBehavior.java | 2 +-
.../api/WebSocketConnectionListener.java | 2 +-
.../ee9/websocket/api/WebSocketContainer.java | 2 +-
.../websocket/api/WebSocketFrameListener.java | 2 +-
.../ee9/websocket/api/WebSocketListener.java | 2 +-
.../api/WebSocketPartialListener.java | 2 +-
.../api/WebSocketPingPongListener.java | 2 +-
.../ee9/websocket/api/WebSocketPolicy.java | 2 +-
.../api/WebSocketSessionListener.java | 2 +-
.../ee9/websocket/api/WriteCallback.java | 2 +-
.../api/annotations/OnWebSocketClose.java | 4 +-
.../api/annotations/OnWebSocketConnect.java | 4 +-
.../api/annotations/OnWebSocketError.java | 4 +-
.../api/annotations/OnWebSocketFrame.java | 6 +-
.../api/annotations/OnWebSocketMessage.java | 6 +-
.../websocket/api/annotations/WebSocket.java | 6 +-
.../api/annotations/package-info.java | 2 +-
.../api/exceptions/BadPayloadException.java | 4 +-
.../api/exceptions/CloseException.java | 2 +-
.../exceptions/InvalidWebSocketException.java | 8 +-
.../exceptions/MessageTooLargeException.java | 4 +-
.../exceptions/PolicyViolationException.java | 4 +-
.../api/exceptions/ProtocolException.java | 4 +-
.../api/exceptions/UpgradeException.java | 2 +-
.../api/exceptions/WebSocketException.java | 2 +-
.../exceptions/WebSocketTimeoutException.java | 2 +-
.../api/exceptions/package-info.java | 2 +-
.../ee9}/websocket/api/package-info.java | 2 +-
.../jetty/ee9}/websocket/api/util/WSURI.java | 2 +-
.../api/util/WebSocketConstants.java | 2 +-
.../ee9}/websocket/api/util/package-info.java | 2 +-
.../jetty-ee9-websocket-jetty-client}/pom.xml | 24 +-
.../src/main/java/module-info.java | 10 +-
.../client/ClientUpgradeRequest.java | 8 +-
.../client/JettyUpgradeListener.java | 2 +-
.../ee9/websocket/client/WebSocketClient.java | 22 +-
.../JettyWebSocketClientConfiguration.java | 26 +-
.../DelegatedJettyClientUpgradeRequest.java | 6 +-
.../DelegatedJettyClientUpgradeResponse.java | 6 +-
.../impl/JettyClientUpgradeRequest.java | 8 +-
.../ee9}/websocket/client/package-info.java | 2 +-
.../org.eclipse.jetty.webapp.Configuration | 1 +
.../src/test/java/examples/ClientDemo.java | 8 +-
.../test/java/examples/SimpleEchoClient.java | 4 +-
.../test/java/examples/SimpleEchoSocket.java | 12 +-
.../websocket/client/HttpClientInitTest.java | 2 +-
.../client/WebSocketClientBadUriTest.java | 8 +-
.../client/WebSocketClientInitTest.java | 2 +-
.../test/resources/jetty-logging.properties | 16 +
.../jetty-ee9-websocket-jetty-common}/pom.xml | 18 +-
.../src/main/java/module-info.java | 10 +-
.../common/ExtensionConfigParser.java | 4 +-
.../common/JettyExtensionConfig.java | 4 +-
.../websocket/common/JettyWebSocketFrame.java | 4 +-
.../common/JettyWebSocketFrameHandler.java | 26 +-
.../JettyWebSocketFrameHandlerFactory.java | 46 +-
.../JettyWebSocketFrameHandlerMetadata.java | 6 +-
.../common/JettyWebSocketRemoteEndpoint.java | 12 +-
.../ee9}/websocket/common/SessionTracker.java | 8 +-
.../websocket/common/WebSocketSession.java | 18 +-
.../ee9}/websocket/common/package-info.java | 2 +-
.../ee9}/websocket/common/DummyContainer.java | 8 +-
.../jetty/ee9/websocket/common/EndPoints.java | 28 +-
.../ee9/websocket/common/EventQueue.java | 2 +-
.../JettyWebSocketFrameHandlerTest.java | 12 +-
.../common/LocalEndpointMetadataTest.java | 8 +-
.../common/MessageInputStreamTest.java | 2 +-
.../common/MessageOutputStreamTest.java | 2 +-
.../common/OutgoingMessageCapture.java | 2 +-
.../TestableLeakTrackingBufferPool.java | 2 +-
.../endpoints/adapters/AdapterEchoSocket.java | 4 +-
.../adapters/AnnotatedEchoSocket.java | 8 +-
.../adapters/ListenerEchoSocket.java | 6 +-
.../common/invoke/InvokerUtilsTest.java | 2 +-
.../common/invoke/NameParamIdentifier.java | 2 +-
.../test/resources/jetty-logging.properties | 0
.../jetty-ee9-websocket-jetty-server}/pom.xml | 32 +-
.../src/main/java/module-info.java | 20 +-
.../server/JettyServerUpgradeRequest.java | 4 +-
.../server/JettyServerUpgradeResponse.java | 8 +-
.../server/JettyWebSocketCreator.java | 2 +-
.../server/JettyWebSocketServerContainer.java | 28 +-
.../server/JettyWebSocketServlet.java | 10 +-
.../server/JettyWebSocketServletFactory.java | 6 +-
.../config/JettyWebSocketConfiguration.java | 20 +-
...yWebSocketServletContainerInitializer.java | 6 +-
.../DelegatedServerUpgradeRequest.java | 8 +-
.../DelegatedServerUpgradeResponse.java | 8 +-
.../JettyServerFrameHandlerFactory.java | 8 +-
...akarta.servlet.ServletContainerInitializer | 0
.../org.eclipse.jetty.webapp.Configuration | 0
.../server/browser/BrowserDebugTool.java | 22 +-
.../server/browser/BrowserSocket.java | 16 +-
.../resources/browser-debug-tool/index.html | 0
.../resources/browser-debug-tool/main.css | 0
.../resources/browser-debug-tool/websocket.js | 0
.../fuzzingclient.json | 18 +
.../fuzzingserver.json | 10 +
.../jetty-ee9-websocket-jetty-tests}/pom.xml | 24 +-
.../tests/AnnoMaxMessageEndpoint.java | 8 +-
.../tests/AnnotatedPartialListenerTest.java | 20 +-
.../websocket/tests/CloseInOnOpenTest.java | 16 +-
.../tests/CloseTrackingEndpoint.java | 8 +-
.../tests/ConcurrentConnectTest.java | 22 +-
.../tests/ConnectMessageEndpoint.java | 8 +-
.../websocket/tests/ConnectionHeaderTest.java | 12 +-
.../ee9/websocket/tests/EchoCreator.java | 8 +-
.../ee9}/websocket/tests/EchoSocket.java | 4 +-
.../ee9/websocket/tests/ErrorCloseTest.java | 16 +-
.../ee9/websocket/tests}/EventSocket.java | 16 +-
.../tests/GetAuthHeaderEndpoint.java | 8 +-
.../websocket/tests/GracefulCloseTest.java | 12 +-
.../tests/JettyClientClassLoaderTest.java | 24 +-
.../ee9/websocket/tests/JettyOnCloseTest.java | 14 +-
.../JettyWebSocketExtensionConfigTest.java | 16 +-
.../tests/JettyWebSocketFilterTest.java | 22 +-
.../tests/JettyWebSocketNegotiationTest.java | 20 +-
.../tests/JettyWebSocketRestartTest.java | 16 +-
.../JettyWebSocketServletAttributeTest.java | 10 +-
.../tests/JettyWebSocketServletTest.java | 14 +-
.../websocket/tests/JettyWebSocketWebApp.java | 9 +-
.../ee9/websocket/tests/LargeDeflateTest.java | 14 +-
.../tests/MaxOutgoingFramesTest.java | 16 +-
.../ee9/websocket/tests/ParamsEndpoint.java | 8 +-
.../tests/PermessageDeflateBufferTest.java | 16 +-
.../ProgrammaticWebSocketUpgradeTest.java | 16 +-
.../websocket/tests/SimpleStatusServlet.java | 2 +-
.../websocket/tests/SingleOnMessageTest.java | 24 +-
.../websocket/tests/SuspendResumeTest.java | 20 +-
.../tests/UpgradeRequestResponseTest.java | 16 +-
.../ee9/websocket/tests/WebAppTester.java | 28 +-
.../tests/WebSocketOverHTTP2Test.java | 28 +-
.../tests/WebSocketServletExamplesTest.java | 30 +-
.../websocket/tests/WebSocketStatsTest.java | 10 +-
.../websocket/tests/WebSocketStopTest.java | 20 +-
.../tests/autobahn}/JettyAutobahnClient.java | 87 +-
.../tests/autobahn}/JettyAutobahnServer.java | 44 +-
.../tests/autobahn}/JettyAutobahnSocket.java | 7 +-
.../tests/client/BadNetworkTest.java | 24 +-
.../tests/client/ClientCloseTest.java | 32 +-
.../tests/client/ClientConfigTest.java | 26 +-
.../tests/client/ClientConnectTest.java | 26 +-
.../client/ClientOpenSessionTracker.java | 8 +-
.../tests/client/ClientSessionsTest.java | 30 +-
.../tests/client/ClientTimeoutTest.java | 20 +-
.../tests/client/ClientWriteThread.java | 10 +-
.../tests/client/ConnectFutureTest.java | 30 +-
.../tests/client/InvalidUpgradeServlet.java | 2 +-
.../tests/client/SlowClientTest.java | 24 +-
.../tests/client/WebSocketClientTest.java | 30 +-
.../tests/examples/MyAdvancedEchoCreator.java | 8 +-
.../tests/examples/MyAdvancedEchoServlet.java | 6 +-
.../tests/examples/MyAuthedCreator.java | 8 +-
.../tests/examples/MyAuthedServlet.java | 6 +-
.../tests/examples/MyBinaryEchoSocket.java | 8 +-
.../tests/examples/MyEchoServlet.java | 6 +-
.../tests/examples/MyEchoSocket.java | 8 +-
.../tests/extensions/ExtensionConfigTest.java | 4 +-
.../listeners/AbstractAnnotatedListener.java | 10 +-
.../tests/listeners/AbstractListener.java | 6 +-
.../tests/listeners/BinaryListeners.java | 12 +-
.../tests/listeners/TextListeners.java | 12 +-
.../listeners/WebSocketListenerTest.java | 18 +-
.../websocket/tests/proxy/WebSocketProxy.java | 18 +-
.../tests/proxy/WebSocketProxyTest.java | 30 +-
.../tests/server/AbstractCloseEndpoint.java | 6 +-
.../tests/server/CloseInOnCloseEndpoint.java | 4 +-
.../CloseInOnCloseEndpointNewThread.java | 4 +-
.../tests/server/ContainerEndpoint.java | 10 +-
.../tests/server/FastCloseEndpoint.java | 6 +-
.../tests/server/FastFailEndpoint.java | 4 +-
.../tests/server/FrameAnnotationTest.java | 44 +-
.../tests/server/FrameListenerTest.java | 30 +-
.../tests/server/PartialListenerTest.java | 34 +-
.../tests/server/ServerCloseCreator.java | 14 +-
.../tests/server/ServerCloseTest.java | 26 +-
.../tests/server/ServerConfigTest.java | 30 +-
.../tests/server/SlowServerEndpoint.java | 8 +-
.../tests/server/SlowServerTest.java | 20 +-
.../tests/util/FutureWriteCallback.java | 4 +-
.../ee9/websocket/tests/util/WSURITest.java | 4 +-
.../test/resources/jetty-logging.properties | 0
.../src/test/resources/keystore.p12 | Bin
.../jetty-ee9-websocket-servlet}/pom.xml | 14 +-
.../src/main/java/module-info.java | 6 +-
.../servlet/WebSocketUpgradeFilter.java | 8 +-
jetty-ee9/jetty-ee9-websocket/pom.xml | 30 +
jetty-ee9/pom.xml | 418 +
.../fcgi/client/http/HttpChannelOverFCGI.java | 205 -
.../fcgi/server/HttpTransportOverFCGI.java | 151 -
.../jetty/fcgi/server/EmptyServerHandler.java | 31 -
.../session/TestHazelcastSessions.java | 183 -
jetty-home/pom.xml | 122 +-
jetty-home/src/main/resources/bin/jetty.sh | 6 +-
.../modules/demo.d/demo-realm.properties | 2 +-
.../modules/jolokia/jolokia-realm.properties | 31 -
.../TestEndpointMultiplePublishProblem.java | 160 -
.../jetty/http2/client/EmptyHttpServlet.java | 29 -
.../test/resources/jetty-logging.properties | 5 -
.../jetty/http2/client/http/AbstractTest.java | 81 -
.../http2/client/http/EmptyServerHandler.java | 36 -
.../http/PriorKnowledgeHTTP2OverTLSTest.java | 137 -
.../test/resources/jetty-logging.properties | 6 -
.../src/test/resources/keystore.p12 | Bin 2565 -> 0 bytes
.../http2/server/HttpChannelOverHTTP2.java | 788 -
.../http/internal/HttpChannelOverHTTP3.java | 108 -
.../internal/HttpTransportOverHTTP3.java | 513 -
.../infinispan/EmbeddedQueryManagerTest.java | 128 -
.../infinispan/RemoteQueryManagerTest.java | 203 -
.../src/test/resources/config.yaml | 4 -
.../test/resources/simplelogger.properties | 3 -
.../jetty-gcloud-session-manager/pom.xml | 6 +-
.../session/GCloudSessionDataStore.java | 10 +-
.../GCloudSessionDataStoreFactory.java | 8 +-
jetty-integrations/jetty-gcloud/pom.xml | 8 +-
jetty-integrations/jetty-hazelcast/pom.xml | 26 +-
.../src/main/java/module-info.java | 4 +-
.../session/HazelcastSessionDataStore.java | 10 +-
.../HazelcastSessionDataStoreFactory.java | 12 +-
.../session/SessionDataSerializer.java | 2 +-
.../infinispan-common/pom.xml | 6 +-
.../infinispan/InfinispanSessionData.java | 3 +-
.../InfinispanSessionDataStore.java | 6 +-
.../InfinispanSessionDataStoreFactory.java | 8 +-
.../InfinispanSessionLegacyConverter.java | 2 +-
.../session/infinispan/QueryManager.java | 2 +-
.../infinispan-embedded-query/pom.xml | 4 +-
.../src/main/assembly/config.xml | 0
.../infinispan/EmbeddedQueryManager.java | 2 +-
.../infinispan-embedded/pom.xml | 4 +-
.../src/main/assembly/config.xml | 0
.../infinispan-remote-query/pom.xml | 4 +-
.../src/main/assembly/config.xml | 0
.../infinispan/RemoteQueryManager.java | 2 +-
.../infinispan-remote/pom.xml | 4 +-
.../src/main/assembly/config.xml | 0
jetty-integrations/jetty-infinispan/pom.xml | 7 +-
.../jetty-memcached-sessions/pom.xml | 29 +
.../src/main/java/module-info.java | 2 +-
.../session/MemcachedSessionDataMap.java | 6 +-
.../MemcachedSessionDataMapFactory.java | 4 +-
jetty-integrations/jetty-memcached/pom.xml | 6 +-
jetty-integrations/jetty-nosql/pom.xml | 16 +-
.../src/main/java/module-info.java | 4 +-
.../jetty/nosql/NoSqlSessionDataStore.java | 4 +-
.../nosql/mongodb/MongoSessionDataStore.java | 8 +-
.../mongodb/MongoSessionDataStoreFactory.java | 10 +-
.../jetty/nosql/mongodb/package-info.java | 0
.../org/eclipse/jetty/nosql/package-info.java | 0
jetty-integrations/pom.xml | 22 +
.../invoker.properties | 1 -
.../src/it/exclude-javax-annotation/pom.xml | 104 -
.../exclude-javax-annotation/postbuild.groovy | 24 -
.../main/java/org/github/unb/TestServlet.java | 82 -
.../src/config/jetty.xml | 40 -
.../jetty-memcached-sessions/pom.xml | 83 -
.../session/TestMemcachedSessions.java | 153 -
jetty-p2/pom.xml | 4 +-
.../org.eclipse.jetty.webapp.Configuration | 2 -
.../config/modules/rewrite/rewrite-msie.xml | 10 -
.../jetty/rewrite/handler/MsieRule.java | 111 -
.../jetty/rewrite/handler/MsieSslRule.java | 90 -
.../jetty/rewrite/handler/RedirectUtil.java | 63 -
.../jetty/rewrite/handler/ValidUrlRule.java | 113 -
.../rewrite/handler/AbstractRuleTestCase.java | 112 -
.../jetty/rewrite/handler/MsieRuleTest.java | 272 -
.../rewrite/handler/MsieSslRuleTest.java | 249 -
.../rewrite/handler/ValidUrlRuleTest.java | 121 -
.../security/SessionAuthenticationTest.java | 88 -
.../jetty/server/HttpChannelOverHttp.java | 737 -
.../jetty/server/RequestLogCollection.java | 43 -
.../server/ServerConnectionStatistics.java | 32 -
.../server/handler/RequestLogHandler.java | 59 -
.../gzip/GzipHttpInputInterceptor.java | 98 -
.../jetty/server/session/SessionHandler.java | 1718 -
.../eclipse/jetty/server/AsyncStressTest.java | 349 -
.../server/CharEncodingContextHandler.java | 44 -
.../org/eclipse/jetty/server/StressTest.java | 481 -
.../server/session/SessionCookieTest.java | 164 -
.../server/session/SessionHandlerTest.java | 97 -
.../jetty/servlet/DefaultHandlerTest.java | 99 -
.../eclipse/jetty/servlets/ConcatServlet.java | 144 -
.../servlets/DataRateLimitedServlet.java | 309 -
.../org/eclipse/jetty/servlets/PutFilter.java | 367 -
.../eclipse/jetty/servlets/WelcomeFilter.java | 76 -
.../jetty/servlets/ConcatServletTest.java | 204 -
.../servlets/DataRateLimitedServletTest.java | 121 -
.../eclipse/jetty/servlets/PutFilterTest.java | 285 -
.../jetty/servlets/WelcomeFilterTest.java | 144 -
.../jetty-unixsocket-client/pom.xml | 48 -
.../src/main/java/module-info.java | 25 -
.../HttpClientTransportOverUnixSockets.java | 164 -
.../jetty/unixsocket/UnixSocketClient.java | 80 -
.../jetty/unixsocket/UnixSocketTest.java | 146 -
.../test/resources/jetty-logging.properties | 3 -
.../jetty-unixsocket-common/pom.xml | 47 -
.../src/main/java/module-info.java | 23 -
.../unixsocket/common/UnixSocketEndPoint.java | 55 -
.../jetty/unixsocket/common/JnrTest.java | 149 -
.../jetty-unixsocket-server/pom.xml | 89 -
.../src/main/assembly/config.xml | 28 -
.../etc/jetty-unixsocket-forwarded.xml | 18 -
.../etc/jetty-unixsocket-http.xml | 13 -
.../etc/jetty-unixsocket-http2c.xml | 15 -
.../etc/jetty-unixsocket-proxy-protocol.xml | 10 -
.../etc/jetty-unixsocket-secure.xml | 12 -
.../config-template/etc/jetty-unixsocket.xml | 21 -
.../modules/unixsocket-forwarded.mod | 33 -
.../modules/unixsocket-http.mod | 25 -
.../modules/unixsocket-http2c.mod | 31 -
.../modules/unixsocket-prefix.mod | 30 -
.../modules/unixsocket-proxy-protocol.mod | 25 -
.../modules/unixsocket-secure.mod | 27 -
.../modules/unixsocket-suffix.mod | 20 -
.../src/main/java/module-info.java | 25 -
.../server/UnixSocketConnector.java | 406 -
.../unixsocket/UnixSocketProxyServer.java | 83 -
.../jetty/unixsocket/UnixSocketServer.java | 83 -
.../test/resources/jetty-logging.properties | 3 -
jetty-webapp/src/main/java/module-info.java | 39 -
.../org.eclipse.jetty.webapp.Configuration | 12 -
.../internal/UpgradeHttpServletRequest.java | 659 -
.../internal/UpgradeHttpServletResponse.java | 368 -
.../test/resources/jetty-logging.properties | 15 -
.../src/main/java/module-info.java | 22 -
.../org.eclipse.jetty.webapp.Configuration | 1 -
.../jetty/websocket/tests/EventSocket.java | 101 -
pom.xml | 726 +-
tests/jetty-jmh/pom.xml | 4 +-
tests/pom.xml | 25 +-
tests/test-distribution/pom.xml | 37 +-
.../jetty/tests/distribution/BadAppTests.java | 2 +-
.../tests/distribution/DistributionTests.java | 59 +-
.../distribution/openid/OpenIdProvider.java | 6 +-
.../badapp_throwonunavailable_false.xml | 2 +-
.../badapp/badapp_throwonunavailable_true.xml | 2 +-
.../src/test/resources/realm.properties | 2 +-
.../resources/stats-webapp/WEB-INF/web.xml | 2 +-
tests/test-jpms/pom.xml | 6 +-
.../test-jpms-websocket-core/pom.xml | 2 +-
tests/test-sessions/pom.xml | 17 +-
.../test-sessions/test-file-sessions/pom.xml | 10 +-
.../session/ClusteredOrphanedSessionTest.java | 18 +-
.../test-gcloud-sessions/pom.xml | 10 +-
.../session/ClusteredOrphanedSessionTest.java | 4 +-
.../ClusteredSessionScavengingTest.java | 4 +-
.../session/GCloudSessionDataStoreTest.java | 6 +-
.../session/GCloudSessionTestSupport.java | 6 +-
.../session/InvalidationSessionTest.java | 4 +-
.../test-hazelcast-sessions/pom.xml | 10 +-
.../session/ClusteredOrphanedSessionTest.java | 4 +-
.../ClusteredSessionScavengingTest.java | 4 +-
...lcastClusteredInvalidationSessionTest.java | 4 +-
.../HazelcastSessionDataStoreTest.java | 16 +-
.../session/HazelcastTestHelper.java | 4 +-
.../client/ClientOrphanedSessionTest.java | 4 +-
.../client/ClientSessionScavengingTest.java | 4 +-
.../client/HazelcastSessionDataStoreTest.java | 16 +-
.../test-infinispan-sessions/pom.xml | 10 +-
.../session/ClusteredOrphanedSessionTest.java | 2 +-
...steredSerializedSessionScavengingTest.java | 4 +-
.../ClusteredSessionScavengingTest.java | 2 +-
.../InfinispanFileSessionDataStoreTest.java | 2 +-
.../InfinispanSessionDataStoreTest.java | 4 +-
.../session/InfinispanTestSupport.java | 2 +-
.../{server => }/session/LoggingUtil.java | 2 +-
...ializedInfinispanSessionDataStoreTest.java | 4 +-
...emoteClusteredInvalidationSessionTest.java | 8 +-
.../RemoteClusteredSessionScavengingTest.java | 8 +-
.../RemoteInfinispanSessionDataStoreTest.java | 20 +-
.../remote/RemoteInfinispanTestSupport.java | 4 +-
.../test-sessions/test-jdbc-sessions/pom.xml | 8 +-
.../ClusteredInvalidationSessionTest.java | 2 +-
.../session/ClusteredOrphanedSessionTest.java | 2 +-
.../ClusteredSessionMigrationTest.java | 10 +-
.../ClusteredSessionScavengingTest.java | 2 +-
.../session/JDBCSessionDataStoreTest.java | 2 +-
.../{server => }/session/JdbcTestHelper.java | 2 +-
.../ReloadedSessionMissingClassTest.java | 8 +-
.../session/SessionTableSchemaTest.java | 2 +-
.../session/WebAppObjectInSessionTest.java | 2 +-
.../test-memcached-sessions/pom.xml | 10 +-
.../sessions/CachingSessionDataStoreTest.java | 20 +-
.../sessions/MemcachedTestHelper.java | 14 +-
.../test-mongodb-sessions/pom.xml | 10 +-
.../nosql/mongodb/AttributeNameTest.java | 12 +-
.../ClusteredInvalidateSessionTest.java | 4 +-
.../mongodb/ClusteredOrphanedSessionTest.java | 4 +-
.../ClusteredSessionScavengingTest.java | 4 +-
.../mongodb/MongoSessionDataStoreTest.java | 14 +-
.../jetty/nosql/mongodb/MongoTestHelper.java | 2 +-
.../src/test/resources/realm.properties | 2 +-
.../test-sessions-common/pom.xml | 10 +-
.../TestHttpChannelCompleteListener.java | 40 -
...tHttpSessionListenerWithWebappClasses.java | 54 -
.../server/session/TestSessionHandler.java | 33 -
...tractClusteredInvalidationSessionTest.java | 29 +-
.../AbstractClusteredOrphanedSessionTest.java | 8 +-
...bstractClusteredSessionScavengingTest.java | 16 +-
.../AbstractSessionTestBase.java} | 4 +-
.../AbstractWebAppObjectInSessionTest.java | 21 +-
.../jetty/{server => }/session/Foo.java | 2 +-
.../session/FooInvocationHandler.java | 2 +-
.../SessionTestSupport.java} | 10 +-
.../jetty/{server => }/session/TestFoo.java | 2 +-
.../session/TestHttpSessionListener.java | 2 +-
.../session/TestSessionDataStore.java | 2 +-
.../session/TestSessionDataStoreFactory.java | 6 +-
.../jetty/session/TestSessionHandler.java | 94 +
.../session/WebAppObjectInSessionServlet.java | 2 +-
.../session/DefaultSessionCacheTest.java | 498 -
.../server/session/DirtyAttributeTest.java | 247 -
.../server/session/ImmortalSessionTest.java | 147 -
.../server/session/SaveOptimizeTest.java | 607 -
.../session/SessionEvictionFailureTest.java | 224 -
.../server/session/SessionListenerTest.java | 467 -
.../jetty/{server => }/session/AsyncTest.java | 62 +-
.../ClientCrossContextSessionTest.java | 10 +-
.../{server => }/session/ConcurrencyTest.java | 4 +-
.../{server => }/session/CreationTest.java | 91 +-
.../session/DeleteUnloadableSessionTest.java | 23 +-
.../session/DuplicateCookieTest.java | 64 +-
.../{server => }/session/IdleSessionTest.java | 20 +-
.../ModifyMaxInactiveIntervalTest.java | 44 +-
.../NonClusteredSessionScavengingTest.java | 55 +-
.../session/RedirectSessionTest.java | 8 +-
.../session/ReentrantRequestSessionTest.java | 18 +-
.../session/RemoveSessionTest.java | 12 +-
.../session/RequestDispatchedSessionTest.java | 6 +-
.../session/RequestScopedSessionSaveTest.java | 8 +-
.../SameContextForwardedSessionTest.java | 20 +-
.../SessionInvalidateCreateScavengeTest.java | 10 +-
.../session/SessionInvalidationTest.java | 10 +-
.../session/SessionRenewTest.java | 38 +-
tests/test-webapps/pom.xml | 34 +-
.../test-cdi-common-webapp/pom.xml | 4 +-
tests/test-webapps/test-felix-webapp/pom.xml | 4 +-
tests/test-webapps/test-openid-webapp/pom.xml | 10 +-
.../test-webapps/test-owb-cdi-webapp/pom.xml | 6 +-
...akarta.servlet.ServletContainerInitializer | 2 +-
.../src/main/webapp/WEB-INF/jetty-env.xml | 2 +-
.../src/main/webapp/WEB-INF/jetty-web-owb.xml | 2 +-
.../test-simple-session-webapp/pom.xml | 4 +-
.../test-webapps/test-webapp-rfc2616/pom.xml | 12 +-
.../test-webapps/test-weld-cdi-webapp/pom.xml | 4 +-
.../src/main/webapp/WEB-INF/jetty-env.xml | 2 +-
tests/test-websocket-autobahn/pom.xml | 143 -
.../jetty/websocket/tests/AutobahnClient.java | 19 -
.../jetty/websocket/tests/AutobahnServer.java | 21 -
.../jetty/websocket/tests/AutobahnTests.java | 160 -
.../tests/core/TestMessageHandler.java | 82 -
.../tests/core/TestWebSocketNegotiator.java | 47 -
.../websocket/tests/jakarta/EchoSocket.java | 39 -
.../websocket/tests/jakarta/EventSocket.java | 96 -
.../tests/jakarta/HostConfigurator.java | 30 -
.../websocket/tests/jetty/EchoSocket.java | 37 -
.../test/resources/simplelogger.properties | 4 -
3483 files changed, 288353 insertions(+), 63353 deletions(-)
delete mode 100644 SECURITY.md
delete mode 100644 apache-jsp/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer
delete mode 100644 apache-jsp/src/main/resources/META-INF/services/org.apache.juli.logging.Log
rename {build-resources => build/build-resources}/jetty-codestyle-eclipse-ide.xml (100%)
rename {build-resources => build/build-resources}/jetty-codestyle-intellij.xml (100%)
rename {build-resources => build/build-resources}/pom.xml (96%)
rename {build-resources => build/build-resources}/src/main/resources/jetty-checkstyle.xml (100%)
rename {jetty-unixsocket => build}/pom.xml (53%)
rename {scripts => build/scripts}/clirr-gen-master-index.output-foot.html (100%)
rename {scripts => build/scripts}/clirr-gen-master-index.output-head.html (100%)
rename {scripts => build/scripts}/clirr-gen-master-index.output-html.xslt (100%)
rename {scripts => build/scripts}/clirr-gen-master-index.sh (100%)
rename {scripts => build/scripts}/git-log-csv.sh (100%)
rename {scripts => build/scripts}/looptest.sh (100%)
rename {scripts => build/scripts}/query-git-stats.sh (100%)
rename {scripts => build/scripts}/release-jetty.sh (100%)
delete mode 100644 demos/demo-async-rest/pom.xml
delete mode 100644 demos/demo-jetty-webapp/src/test/resources/jetty-logging.properties
delete mode 100644 demos/demo-mock-resources/src/main/resources/META-INF/javaxmail.providers
delete mode 100644 demos/demo-spec/demo-container-initializer/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer
delete mode 100644 jetty-annotations/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration
delete mode 100644 jetty-client/src/main/java/org/eclipse/jetty/client/AsyncContentProvider.java
delete mode 100644 jetty-client/src/main/java/org/eclipse/jetty/client/api/ContentProvider.java
delete mode 100644 jetty-client/src/main/java/org/eclipse/jetty/client/internal/RequestContentAdapter.java
delete mode 100644 jetty-client/src/main/java/org/eclipse/jetty/client/util/ByteBufferContentProvider.java
delete mode 100644 jetty-client/src/main/java/org/eclipse/jetty/client/util/BytesContentProvider.java
delete mode 100644 jetty-client/src/main/java/org/eclipse/jetty/client/util/DeferredContentProvider.java
delete mode 100644 jetty-client/src/main/java/org/eclipse/jetty/client/util/FormContentProvider.java
delete mode 100644 jetty-client/src/main/java/org/eclipse/jetty/client/util/InputStreamContentProvider.java
delete mode 100644 jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java
delete mode 100644 jetty-client/src/main/java/org/eclipse/jetty/client/util/OutputStreamContentProvider.java
delete mode 100644 jetty-client/src/main/java/org/eclipse/jetty/client/util/PathContentProvider.java
delete mode 100644 jetty-client/src/main/java/org/eclipse/jetty/client/util/StringContentProvider.java
delete mode 100644 jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesServerTest.java
rename {jetty-alpn => jetty-core/jetty-alpn}/jetty-alpn-client/src/main/java/module-info.java (100%)
rename {jetty-alpn => jetty-core/jetty-alpn}/jetty-alpn-conscrypt-client/src/main/java/module-info.java (100%)
rename {jetty-alpn => jetty-core/jetty-alpn}/jetty-alpn-conscrypt-client/src/main/resources/META-INF/services/org.eclipse.jetty.io.ssl.ALPNProcessor$Client (100%)
rename {jetty-alpn => jetty-core/jetty-alpn}/jetty-alpn-conscrypt-client/src/test/resources/jetty-logging.properties (100%)
rename {jetty-alpn => jetty-core/jetty-alpn}/jetty-alpn-conscrypt-server/src/main/java/module-info.java (100%)
rename {jetty-alpn => jetty-core/jetty-alpn}/jetty-alpn-conscrypt-server/src/main/resources/META-INF/services/org.eclipse.jetty.io.ssl.ALPNProcessor$Server (100%)
rename {jetty-alpn => jetty-core/jetty-alpn}/jetty-alpn-conscrypt-server/src/test/resources/jetty-logging.properties (100%)
rename {jetty-alpn => jetty-core/jetty-alpn}/jetty-alpn-conscrypt-server/src/test/resources/keystore.p12 (100%)
rename {jetty-alpn => jetty-core/jetty-alpn}/jetty-alpn-java-client/src/main/java/module-info.java (100%)
rename {jetty-alpn => jetty-core/jetty-alpn}/jetty-alpn-java-client/src/main/resources/META-INF/services/org.eclipse.jetty.io.ssl.ALPNProcessor$Client (100%)
rename {jetty-alpn => jetty-core/jetty-alpn}/jetty-alpn-java-client/src/test/resources/jetty-logging.properties (100%)
rename {jetty-alpn => jetty-core/jetty-alpn}/jetty-alpn-java-server/src/main/java/module-info.java (100%)
rename {jetty-alpn => jetty-core/jetty-alpn}/jetty-alpn-java-server/src/main/resources/META-INF/services/org.eclipse.jetty.io.ssl.ALPNProcessor$Server (100%)
rename {jetty-alpn => jetty-core/jetty-alpn}/jetty-alpn-java-server/src/test/resources/jetty-logging.properties (100%)
rename {jetty-alpn => jetty-core/jetty-alpn}/jetty-alpn-java-server/src/test/resources/keystore.p12 (100%)
rename {jetty-alpn => jetty-core/jetty-alpn}/jetty-alpn-server/src/main/java/module-info.java (100%)
rename jetty-core/{jetty-bom => jetty-bom/pom.xml} (54%)
rename {jetty-client => jetty-core/jetty-client}/src/main/java/module-info.java (100%)
rename {jetty-client => jetty-core/jetty-client}/src/main/java/org/eclipse/jetty/client/api/package-info.java (100%)
rename {jetty-client => jetty-core/jetty-client}/src/main/java/org/eclipse/jetty/client/package-info.java (100%)
rename {jetty-client => jetty-core/jetty-client}/src/main/java/org/eclipse/jetty/client/util/package-info.java (100%)
rename {jetty-deploy => jetty-core/jetty-deploy}/src/main/java/module-info.java (95%)
rename {jetty-deploy => jetty-core/jetty-deploy}/src/main/java/org/eclipse/jetty/deploy/bindings/package-info.java (100%)
rename {jetty-deploy => jetty-core/jetty-deploy}/src/main/java/org/eclipse/jetty/deploy/graph/package-info.java (100%)
rename {jetty-deploy => jetty-core/jetty-deploy}/src/main/java/org/eclipse/jetty/deploy/jmx/package-info.java (100%)
rename {jetty-deploy => jetty-core/jetty-deploy}/src/main/java/org/eclipse/jetty/deploy/package-info.java (100%)
rename {jetty-deploy => jetty-core/jetty-deploy}/src/main/java/org/eclipse/jetty/deploy/providers/package-info.java (100%)
rename {jetty-deploy => jetty-core/jetty-deploy}/src/main/java/org/eclipse/jetty/deploy/util/package-info.java (100%)
rename {jetty-fcgi => jetty-core/jetty-fcgi}/fcgi-client/src/main/java/module-info.java (83%)
rename {jetty-fcgi => jetty-core/jetty-fcgi}/fcgi-client/src/test/resources/jetty-logging.properties (100%)
rename {jetty-fcgi => jetty-core/jetty-fcgi}/fcgi-server/src/main/java/module-info.java (79%)
create mode 100644 jetty-core/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/HttpStreamOverFCGI.java
rename {jetty-fcgi => jetty-core/jetty-fcgi}/fcgi-server/src/test/resources/jetty-logging.properties (100%)
rename {jetty-http-spi => jetty-core/jetty-http-spi}/src/main/java/module-info.java (100%)
rename {tests => jetty-core}/jetty-http-tools/pom.xml (78%)
rename {tests => jetty-core}/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderKey.java (100%)
rename {tests => jetty-core}/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderValue.java (100%)
rename {tests => jetty-core}/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsHeaderValue.java (100%)
rename {tests => jetty-core}/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchers.java (100%)
rename {tests => jetty-core}/jetty-http-tools/src/test/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchersTest.java (100%)
rename {jetty-http => jetty-core/jetty-http}/src/main/java/module-info.java (89%)
create mode 100644 jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/CachingContentFactory.java
create mode 100644 jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCache.java
create mode 100644 jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/Http10FieldPreEncoder.java
create mode 100644 jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/Http11FieldPreEncoder.java
rename {jetty-http => jetty-core/jetty-http}/src/main/java/org/eclipse/jetty/http/package-info.java (100%)
rename {jetty-http2 => jetty-core/jetty-http2}/http2-client/src/main/java/module-info.java (100%)
rename {jetty-http2 => jetty-core/jetty-http2}/http2-common/src/main/java/module-info.java (63%)
rename {jetty-http2 => jetty-core/jetty-http2}/http2-common/src/test/resources/jetty-logging.properties (100%)
rename {jetty-http2 => jetty-core/jetty-http2}/http2-hpack/src/main/java/module-info.java (94%)
rename {jetty-http2 => jetty-core/jetty-http2}/http2-hpack/src/test/resources/jetty-logging.properties (100%)
rename {jetty-http2 => jetty-core/jetty-http2}/http2-http-client-transport/src/main/java/module-info.java (100%)
rename {jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http => jetty-core/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/internal}/HttpChannelOverHTTP2.java (97%)
rename {jetty-http2 => jetty-core/jetty-http2}/http2-server/src/main/java/module-info.java (100%)
create mode 100644 jetty-core/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/internal/HttpChannelOverHTTP2.java
create mode 100644 jetty-core/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/internal/HttpStreamOverHTTP2.java
create mode 100644 jetty-core/jetty-http2/jetty-http2-tests/pom.xml
rename {jetty-http2/http2-server => jetty-core/jetty-http2/jetty-http2-tests}/src/test/resources/jetty-logging.properties (73%)
rename {jetty-http3 => jetty-core/jetty-http3}/http3-client/src/main/java/module-info.java (100%)
rename {jetty-http3 => jetty-core/jetty-http3}/http3-common/src/main/java/module-info.java (100%)
rename {jetty-http3 => jetty-core/jetty-http3}/http3-http-client-transport/src/main/java/module-info.java (100%)
rename {jetty-http3 => jetty-core/jetty-http3}/http3-qpack/src/main/java/module-info.java (100%)
rename {jetty-http3 => jetty-core/jetty-http3}/http3-qpack/src/test/resources/jetty-logging.properties (100%)
rename {jetty-http3 => jetty-core/jetty-http3}/http3-server/src/main/java/module-info.java (100%)
create mode 100644 jetty-core/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/HttpStreamOverHTTP3.java
rename {jetty-http3 => jetty-core/jetty-http3}/http3-tests/src/test/resources/jetty-logging.properties (81%)
rename {jetty-io => jetty-core/jetty-io}/src/main/java/module-info.java (100%)
rename {jetty-io => jetty-core/jetty-io}/src/main/java/org/eclipse/jetty/io/package-info.java (100%)
rename {jetty-io => jetty-core/jetty-io}/src/main/java/org/eclipse/jetty/io/ssl/package-info.java (100%)
rename {jetty-jmx => jetty-core/jetty-jmx}/src/main/java/module-info.java (100%)
rename {jetty-jmx => jetty-core/jetty-jmx}/src/main/java/org/eclipse/jetty/jmx/package-info.java (100%)
rename {jetty-jndi => jetty-core/jetty-jndi}/src/main/java/module-info.java (92%)
rename {jetty-jndi => jetty-core/jetty-jndi}/src/main/java/org/eclipse/jetty/jndi/factories/package-info.java (100%)
rename {jetty-jndi => jetty-core/jetty-jndi}/src/main/java/org/eclipse/jetty/jndi/java/package-info.java (100%)
rename {jetty-jndi => jetty-core/jetty-jndi}/src/main/java/org/eclipse/jetty/jndi/local/package-info.java (100%)
rename {jetty-jndi => jetty-core/jetty-jndi}/src/main/java/org/eclipse/jetty/jndi/package-info.java (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-client/src/main/java/module-info.java (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-client/src/test/resources/jetty-logging.properties (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-client/src/test/resources/keystore.p12 (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-common/src/main/java/module-info.java (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-common/src/main/java/org/eclipse/jetty/quic/common/package-info.java (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-quiche/quic-quiche-common/pom.xml (92%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-quiche/quic-quiche-common/src/main/java/module-info.java (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-quiche/quic-quiche-foreign-incubator/pom.xml (95%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-quiche/quic-quiche-foreign-incubator/src/main/java/module-info.java (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-quiche/quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/sockaddr.java (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-quiche/quic-quiche-foreign-incubator/src/main/resources/META-INF/services/org.eclipse.jetty.quic.quiche.QuicheBinding (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-quiche/quic-quiche-foreign-incubator/src/test/java/org/eclipse/jetty/quic/quiche/foreign/incubator/LowLevelQuicheTest.java (98%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-quiche/quic-quiche-foreign-incubator/src/test/resources/jetty-logging.properties (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-quiche/quic-quiche-foreign-incubator/src/test/resources/keystore.p12 (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-quiche/quic-quiche-jna/pom.xml (94%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-quiche/quic-quiche-jna/src/main/java/module-info.java (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-quiche/quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/sockaddr.java (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-quiche/quic-quiche-jna/src/main/resources/META-INF/services/org.eclipse.jetty.quic.quiche.QuicheBinding (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-quiche/quic-quiche-jna/src/test/java/org/eclipse/jetty/quic/quiche/jna/LowLevelQuicheTest.java (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-quiche/quic-quiche-jna/src/test/resources/jetty-logging.properties (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-quiche/quic-quiche-jna/src/test/resources/keystore.p12 (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-server/src/main/java/module-info.java (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-server/src/test/resources/jetty-logging.properties (100%)
rename {jetty-quic => jetty-core/jetty-quic}/quic-server/src/test/resources/keystore.p12 (100%)
rename {jetty-rewrite => jetty-core/jetty-rewrite}/src/main/config/etc/jetty-rewrite.xml (100%)
rename {jetty-rewrite => jetty-core/jetty-rewrite}/src/main/java/module-info.java (95%)
create mode 100644 jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/InvalidURIRule.java
rename {jetty-rewrite => jetty-core/jetty-rewrite}/src/main/java/org/eclipse/jetty/rewrite/handler/package-info.java (100%)
create mode 100644 jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/AbstractRuleTest.java
create mode 100644 jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/InvalidURIRuleTest.java
create mode 100644 jetty-core/jetty-rewrite/src/test/resources/jetty-logging.properties
rename {jetty-rewrite => jetty-core/jetty-rewrite}/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml (99%)
rename {jetty-server => jetty-core/jetty-server}/src/main/config/etc/sessions/file/session-store.xml (100%)
rename {jetty-server => jetty-core/jetty-server}/src/main/config/etc/sessions/jdbc/session-store.xml (100%)
create mode 100644 jetty-core/jetty-server/src/main/config/modules/test-keystore/test-keystore.p12
rename {jetty-server => jetty-core/jetty-server}/src/main/java/module-info.java (82%)
create mode 100644 jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Components.java
create mode 100644 jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionMetaData.java
create mode 100644 jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Content.java
create mode 100644 jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/ContentProcessor.java
create mode 100644 jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Context.java
create mode 100644 jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/FutureFormFields.java
create mode 100644 jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/HttpStream.java
create mode 100644 jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextRequest.java
create mode 100644 jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextResponse.java
create mode 100644 jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DelayedHandler.java
create mode 100644 jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorProcessor.java
create mode 100644 jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ProxiedRequestHandler.java
create mode 100644 jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipRequest.java
rename jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHttpOutputInterceptor.java => jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipResponse.java (59%)
rename jetty-client/src/main/java/org/eclipse/jetty/client/util/AbstractTypedContentProvider.java => jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/HeaderWrappingRequest.java (56%)
rename {jetty-server => jetty-core/jetty-server}/src/main/java/org/eclipse/jetty/server/handler/gzip/package-info.java (100%)
create mode 100644 jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/jmx/AbstractHandlerMBean.java
rename {jetty-server => jetty-core/jetty-server}/src/main/java/org/eclipse/jetty/server/handler/jmx/package-info.java (100%)
rename {jetty-server => jetty-core/jetty-server}/src/main/java/org/eclipse/jetty/server/handler/package-info.java (100%)
create mode 100644 jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/internal/ResponseHttpFields.java
create mode 100644 jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/jmx/AbstractHandlerMBean.java
rename {jetty-server => jetty-core/jetty-server}/src/main/java/org/eclipse/jetty/server/jmx/package-info.java (93%)
rename {jetty-server => jetty-core/jetty-server}/src/main/java/org/eclipse/jetty/server/package-info.java (100%)
create mode 100644 jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/FixJPMS.java
create mode 100644 jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ContentTest.java
create mode 100644 jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/CustomRequestLogTest.java
create mode 100644 jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorProcessorTest.java
create mode 100644 jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/HttpChannelTest.java
create mode 100644 jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/MockConnectionMetaData.java
create mode 100644 jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/MockHttpStream.java
create mode 100644 jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/DelayedHandlerTest.java
create mode 100644 jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/EchoHandler.java
create mode 100644 jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/HelloHandler.java
rename {jetty-servlet/src/test/java/org/eclipse/jetty/servlet => jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/gzip}/GzipHandlerTest.java (69%)
create mode 100644 jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/jmh/HandlerBenchmark.java
create mode 100644 jetty-core/jetty-session/pom.xml
create mode 100644 jetty-core/jetty-session/src/main/java/module-info.java
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/AbstractSessionCache.java (92%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/AbstractSessionCacheFactory.java (88%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/AbstractSessionDataStore.java (99%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/AbstractSessionDataStoreFactory.java (97%)
create mode 100644 jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/AbstractSessionManager.java
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/CachingSessionDataStore.java (99%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/CachingSessionDataStoreFactory.java (89%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/DatabaseAdaptor.java (99%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/DefaultSessionCache.java (92%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/DefaultSessionCacheFactory.java (83%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/DefaultSessionIdManager.java (84%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/FileSessionDataStore.java (99%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/FileSessionDataStoreFactory.java (93%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/HouseKeeper.java (93%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/JDBCSessionDataStore.java (99%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/JDBCSessionDataStoreFactory.java (92%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/NullSessionCache.java (85%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/NullSessionCacheFactory.java (87%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/NullSessionDataStore.java (98%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/NullSessionDataStoreFactory.java (85%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/Session.java (63%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/SessionCache.java (91%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/SessionCacheFactory.java (86%)
create mode 100644 jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SessionConfig.java
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/SessionContext.java (70%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/SessionData.java (99%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/SessionDataMap.java (97%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/SessionDataMapFactory.java (94%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/SessionDataStore.java (98%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/SessionDataStoreFactory.java (86%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session}/SessionIdManager.java (81%)
create mode 100644 jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SessionInactivityTimer.java
create mode 100644 jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SessionManager.java
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/UnreadableSessionDataException.java (97%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/UnwriteableSessionDataException.java (96%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/main/java/org/eclipse/jetty}/session/package-info.java (93%)
rename {tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/test/java/org/eclipse/jetty}/session/AbstractSessionCacheTest.java (65%)
rename {tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/test/java/org/eclipse/jetty}/session/AbstractSessionDataStoreTest.java (60%)
create mode 100644 jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/AbstractSessionManagerTest.java
create mode 100644 jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/DefaultSessionCacheTest.java
create mode 100644 jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/DefaultSessionIdManagerTest.java
create mode 100644 jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/DirtyAttributeTest.java
rename {tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/test/java/org/eclipse/jetty}/session/FileSessionDataStoreTest.java (98%)
rename tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/TestFileSessions.java => jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/FileSessionsTest.java (85%)
rename {tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/test/java/org/eclipse/jetty}/session/FileTestHelper.java (99%)
rename {jetty-server/src/test/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/test/java/org/eclipse/jetty}/session/HouseKeeperTest.java (95%)
rename {tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server => jetty-core/jetty-session/src/test/java/org/eclipse/jetty}/session/NullSessionCacheTest.java (65%)
create mode 100644 jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/SessionListenerTest.java
create mode 100644 jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/SimpleSessionHandler.java
create mode 100644 jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/SimpleSessionHandlerTest.java
create mode 100644 jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/TestableRequest.java
create mode 100644 jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/TestableSessionDataStore.java
create mode 100644 jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/TestableSessionManager.java
rename {tests/test-sessions/test-sessions-common/src/main => jetty-core/jetty-session/src/test}/resources/Foo.clazz (100%)
rename {tests/test-sessions/test-sessions-common/src/main => jetty-core/jetty-session/src/test}/resources/Foo.java (100%)
rename {tests/test-sessions/test-sessions-common/src/main => jetty-core/jetty-session/src/test}/resources/Proxyable.clazz (100%)
rename {tests/test-sessions/test-sessions-common/src/main => jetty-core/jetty-session/src/test}/resources/Proxyable.java (100%)
rename {tests/test-sessions/test-sessions-common/src/main => jetty-core/jetty-session/src/test}/resources/ProxyableFactory.clazz (100%)
rename {tests/test-sessions/test-sessions-common/src/main => jetty-core/jetty-session/src/test}/resources/ProxyableFactory.java (100%)
rename {tests/test-sessions/test-sessions-common/src/main => jetty-core/jetty-session/src/test}/resources/ProxyableInvocationHandler.clazz (100%)
rename {tests/test-sessions/test-sessions-common/src/main => jetty-core/jetty-session/src/test}/resources/ProxyableInvocationHandler.java (100%)
rename {jetty-slf4j-impl => jetty-core/jetty-slf4j-impl}/src/main/java/module-info.java (100%)
create mode 100644 jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Environment.java
rename {jetty-start => jetty-core/jetty-start}/src/main/java/org/eclipse/jetty/start/package-info.java (100%)
create mode 100644 jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/EnvironmentsTest.java
rename {jetty-start => jetty-core/jetty-start}/src/test/resources/dist-home/modules/base.mod (100%)
rename {jetty-start => jetty-core/jetty-start}/src/test/resources/dist-home/start.ini (100%)
rename {jetty-start => jetty-core/jetty-start}/src/test/resources/empty.home/start.ini (100%)
rename {jetty-start => jetty-core/jetty-start}/src/test/resources/extra-jetty-dirs/logging/start.ini (100%)
rename {jetty-start => jetty-core/jetty-start}/src/test/resources/hb.1/base/start.d/jmx.ini (100%)
rename {jetty-start => jetty-core/jetty-start}/src/test/resources/hb.1/base/start.d/logging.ini (100%)
rename {jetty-start => jetty-core/jetty-start}/src/test/resources/hb.1/base/start.ini (100%)
rename {jetty-start => jetty-core/jetty-start}/src/test/resources/hb.1/home/start.d/jmx.ini (100%)
rename {jetty-start => jetty-core/jetty-start}/src/test/resources/hb.1/home/start.d/logging.ini (100%)
rename {jetty-start => jetty-core/jetty-start}/src/test/resources/hb.1/home/start.ini (100%)
rename {jetty-start => jetty-core/jetty-start}/src/test/resources/jetty home with spaces/lib/example of a library with spaces.jar (100%)
rename {jetty-start => jetty-core/jetty-start}/src/test/resources/jetty home with spaces/modules/base.mod (100%)
rename {jetty-start => jetty-core/jetty-start}/src/test/resources/jetty home with spaces/start.ini (100%)
rename {jetty-start => jetty-core/jetty-start}/src/test/resources/usecases/minimal-start-ini/start.ini (100%)
rename {jetty-unixdomain-server => jetty-core/jetty-unixdomain-server}/src/main/java/module-info.java (100%)
rename {jetty-util-ajax => jetty-core/jetty-util-ajax}/src/main/java/module-info.java (100%)
rename {jetty-util-ajax => jetty-core/jetty-util-ajax}/src/main/java/org/eclipse/jetty/util/ajax/package-info.java (100%)
rename {jetty-util => jetty-core/jetty-util}/src/main/java/module-info.java (100%)
create mode 100644 jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Blocking.java
create mode 100644 jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/CharsetStringBuilder.java
create mode 100644 jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/IteratingCallback_State.puml
rename {jetty-util => jetty-core/jetty-util}/src/main/java/org/eclipse/jetty/util/annotation/package-info.java (100%)
create mode 100644 jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/Environment.java
rename {jetty-util => jetty-core/jetty-util}/src/main/java/org/eclipse/jetty/util/component/package-info.java (100%)
rename {jetty-util => jetty-core/jetty-util}/src/main/java/org/eclipse/jetty/util/package-info.java (100%)
rename {jetty-util => jetty-core/jetty-util}/src/main/java/org/eclipse/jetty/util/preventers/package-info.java (100%)
create mode 100644 jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/PathCollators.java
rename {jetty-util => jetty-core/jetty-util}/src/main/java/org/eclipse/jetty/util/resource/package-info.java (100%)
rename {jetty-util => jetty-core/jetty-util}/src/main/java/org/eclipse/jetty/util/security/package-info.java (100%)
rename {jetty-util => jetty-core/jetty-util}/src/main/java/org/eclipse/jetty/util/ssl/package-info.java (100%)
rename {jetty-util => jetty-core/jetty-util}/src/main/java/org/eclipse/jetty/util/statistic/package-info.java (100%)
create mode 100644 jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedInvoker.java
rename {jetty-util => jetty-core/jetty-util}/src/main/java/org/eclipse/jetty/util/thread/package-info.java (100%)
create mode 100644 jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/AttributesTest.java
create mode 100644 jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/BlockingTest.java
create mode 100644 jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/CharsetStringBuilderTest.java
create mode 100644 jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/FieldsTest.java
create mode 100644 jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/component/LifeCycleListenerNestedTest.java
create mode 100644 jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SerializedInvokerTest.java
rename {jetty-util => jetty-core/jetty-util}/src/test/resources/TestData/test/alphabet (100%)
rename {jetty-util => jetty-core/jetty-util}/src/test/resources/TestData/test/numbers (100%)
rename {jetty-util => jetty-core/jetty-util}/src/test/resources/TestData/test/subdir/alphabet (100%)
rename {jetty-util => jetty-core/jetty-util}/src/test/resources/TestData/test/subdir/numbers (100%)
rename {jetty-util => jetty-core/jetty-util}/src/test/resources/TestData/test/subdir/subsubdir/alphabet (100%)
rename {jetty-util => jetty-core/jetty-util}/src/test/resources/TestData/test/subdir/subsubdir/numbers (100%)
rename {jetty-util => jetty-core/jetty-util}/src/test/resources/org/eclipse/jetty/util/resource/four/four (100%)
rename {jetty-util => jetty-core/jetty-util}/src/test/resources/org/eclipse/jetty/util/resource/one/1.txt (100%)
rename {jetty-util => jetty-core/jetty-util}/src/test/resources/org/eclipse/jetty/util/resource/one/dir/1.txt (100%)
rename {jetty-util => jetty-core/jetty-util}/src/test/resources/org/eclipse/jetty/util/resource/resource.txt (100%)
rename {jetty-util => jetty-core/jetty-util}/src/test/resources/org/eclipse/jetty/util/resource/three/2.txt (100%)
rename {jetty-util => jetty-core/jetty-util}/src/test/resources/org/eclipse/jetty/util/resource/three/3.txt (100%)
rename {jetty-util => jetty-core/jetty-util}/src/test/resources/org/eclipse/jetty/util/resource/three/dir/3.txt (100%)
rename {jetty-util => jetty-core/jetty-util}/src/test/resources/org/eclipse/jetty/util/resource/two/1.txt (100%)
rename {jetty-util => jetty-core/jetty-util}/src/test/resources/org/eclipse/jetty/util/resource/two/2.txt (100%)
rename {jetty-util => jetty-core/jetty-util}/src/test/resources/org/eclipse/jetty/util/resource/two/dir/2.txt (100%)
rename {jetty-util => jetty-core/jetty-util}/src/test/resources/resource.txt (100%)
rename {jetty-websocket => jetty-core/jetty-websocket}/websocket-core-client/src/main/java/module-info.java (100%)
rename {jetty-websocket => jetty-core/jetty-websocket}/websocket-core-common/src/main/java/module-info.java (56%)
rename {jetty-websocket => jetty-core/jetty-websocket}/websocket-core-server/src/main/java/module-info.java (100%)
create mode 100644 jetty-core/jetty-websocket/websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HttpFieldsWrapper.java
create mode 100644 jetty-core/jetty-websocket/websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/WebSocketHttpFieldsWrapper.java
rename {tests/test-websocket-autobahn => jetty-core/jetty-websocket/websocket-core-tests}/fuzzingclient.json (100%)
rename {tests/test-websocket-autobahn => jetty-core/jetty-websocket/websocket-core-tests}/fuzzingserver.json (100%)
create mode 100644 jetty-core/jetty-websocket/websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/WebSocketEchoTest.java
rename {tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/core => jetty-core/jetty-websocket/websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/autobahn}/AutobahnFrameHandler.java (94%)
rename tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/AutobahnUtils.java => jetty-core/jetty-websocket/websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/autobahn/AutobahnTests.java (68%)
rename {tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/core => jetty-core/jetty-websocket/websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/autobahn}/CoreAutobahnClient.java (83%)
rename {tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/core => jetty-core/jetty-websocket/websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/autobahn}/CoreAutobahnServer.java (75%)
rename {jetty-xml => jetty-core/jetty-xml}/src/main/java/module-info.java (100%)
rename {jetty-xml => jetty-core/jetty-xml}/src/main/java/org/eclipse/jetty/xml/package-info.java (100%)
create mode 100644 jetty-core/pom.xml
delete mode 100644 jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/DebugListenerBinding.java
delete mode 100644 jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBinding.java
delete mode 100644 jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/jmx/WebAppProviderMBean.java
delete mode 100644 jetty-deploy/src/test/java/org/eclipse/jetty/deploy/BadAppDeployTest.java
delete mode 100644 jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentTempDirTest.java
delete mode 100644 jetty-deploy/src/test/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBindingTest.java
delete mode 100644 jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/WebAppProviderTest.java
rename {jetty-annotations => jetty-ee9/jetty-ee9-annotations}/pom.xml (85%)
rename {jetty-annotations => jetty-ee9/jetty-ee9-annotations}/src/main/java/module-info.java (68%)
rename {jetty-annotations/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9}/annotations/package-info.java (93%)
create mode 100644 jetty-ee9/jetty-ee9-annotations/src/main/resources/META-INF/services/org.eclipse.jetty.ee9.webapp.Configuration
rename {jetty-ant => jetty-ee9/jetty-ee9-ant}/pom.xml (76%)
rename {jetty-ant/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9}/ant/package-info.java (94%)
rename {jetty-ant/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9}/ant/types/package-info.java (93%)
rename {jetty-ant/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9}/ant/utils/package-info.java (93%)
rename {jetty-ant => jetty-ee9/jetty-ee9-ant}/src/test/resources/foo/index.html (100%)
rename {jetty-ant => jetty-ee9/jetty-ee9-ant}/src/test/resources/foo/jsp/index.html (100%)
rename {apache-jsp => jetty-ee9/jetty-ee9-apache-jsp}/pom.xml (78%)
rename {apache-jsp => jetty-ee9/jetty-ee9-apache-jsp}/src/main/config/modules/apache-jsp.mod (100%)
rename {apache-jsp => jetty-ee9/jetty-ee9-apache-jsp}/src/main/java/module-info.java (77%)
rename {apache-jsp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-apache-jsp/src/main/java/org/eclipse/jetty/ee9}/apache/jsp/JettyJasperInitializer.java (98%)
rename {apache-jsp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-apache-jsp/src/main/java/org/eclipse/jetty/ee9}/apache/jsp/JettyTldPreScanned.java (98%)
rename {apache-jsp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-apache-jsp/src/main/java/org/eclipse/jetty/ee9}/apache/jsp/JuliLog.java (99%)
rename {apache-jsp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-apache-jsp/src/main/java/org/eclipse/jetty/ee9}/jsp/JettyJspServlet.java (99%)
create mode 100644 jetty-ee9/jetty-ee9-apache-jsp/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer
create mode 100644 jetty-ee9/jetty-ee9-apache-jsp/src/main/resources/META-INF/services/org.apache.juli.logging.Log
rename {apache-jsp/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-apache-jsp/src/test/java/org/eclipse/jetty/ee9}/jsp/TestJettyJspServlet.java (96%)
rename {apache-jsp/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-apache-jsp/src/test/java/org/eclipse/jetty/ee9}/jsp/TestJettyTldPreScanned.java (93%)
rename {apache-jsp/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-apache-jsp/src/test/java/org/eclipse/jetty/ee9}/jsp/TestJspFileNameToClass.java (95%)
rename {apache-jsp => jetty-ee9/jetty-ee9-apache-jsp}/src/test/resources/META-INF/foo-taglib.tld (100%)
rename {apache-jsp => jetty-ee9/jetty-ee9-apache-jsp}/src/test/resources/base/dir/empty.txt (100%)
rename {apache-jsp => jetty-ee9/jetty-ee9-apache-jsp}/src/test/resources/base/foo.jsp (100%)
rename {apache-jsp => jetty-ee9/jetty-ee9-apache-jsp}/src/test/resources/taglib.jar (100%)
create mode 100644 jetty-ee9/jetty-ee9-bom/pom.xml
rename {jetty-cdi => jetty-ee9/jetty-ee9-cdi}/pom.xml (83%)
rename {jetty-cdi => jetty-ee9/jetty-ee9-cdi}/src/main/java/module-info.java (76%)
rename {demos/demo-async-rest/demo-async-rest-jar => jetty-ee9/jetty-ee9-demos/demo-ee9-async-rest/demo-ee9-async-rest-jar}/pom.xml (78%)
rename {demos/demo-async-rest/demo-async-rest-jar/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-async-rest/demo-ee9-async-rest-jar/src/main/java/org/eclipse/jetty/ee9}/demos/AbstractRestServlet.java (99%)
rename {demos/demo-async-rest/demo-async-rest-jar/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-async-rest/demo-ee9-async-rest-jar/src/main/java/org/eclipse/jetty/ee9}/demos/AsyncRestServlet.java (99%)
rename {demos/demo-async-rest/demo-async-rest-jar/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-async-rest/demo-ee9-async-rest-jar/src/main/java/org/eclipse/jetty/ee9}/demos/SerialRestServlet.java (98%)
rename {demos/demo-async-rest/demo-async-rest-jar => jetty-ee9/jetty-ee9-demos/demo-ee9-async-rest/demo-ee9-async-rest-jar}/src/main/resources/META-INF/resources/asyncrest.html (100%)
rename {demos/demo-async-rest/demo-async-rest-jar => jetty-ee9/jetty-ee9-demos/demo-ee9-async-rest/demo-ee9-async-rest-jar}/src/main/resources/META-INF/resources/asyncrest/green.png (100%)
rename {demos/demo-async-rest/demo-async-rest-jar => jetty-ee9/jetty-ee9-demos/demo-ee9-async-rest/demo-ee9-async-rest-jar}/src/main/resources/META-INF/resources/asyncrest/red.png (100%)
rename {demos/demo-async-rest/demo-async-rest-jar => jetty-ee9/jetty-ee9-demos/demo-ee9-async-rest/demo-ee9-async-rest-jar}/src/main/resources/META-INF/web-fragment.xml (100%)
rename {demos/demo-async-rest/demo-async-rest-server => jetty-ee9/jetty-ee9-demos/demo-ee9-async-rest/demo-ee9-async-rest-server}/pom.xml (59%)
rename {demos/demo-async-rest/demo-async-rest-server/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-async-rest/demo-ee9-async-rest-server/src/main/java/org/eclipse/jetty/ee9}/demos/AsyncRestServer.java (95%)
rename {demos/demo-async-rest/demo-async-rest-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-async-rest/demo-ee9-async-rest-webapp}/pom.xml (69%)
rename {demos/demo-async-rest/demo-async-rest-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-async-rest/demo-ee9-async-rest-webapp}/src/main/config/modules/demo-async-rest.mod (100%)
rename {demos/demo-async-rest/demo-async-rest-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-async-rest/demo-ee9-async-rest-webapp}/src/main/webapp/META-INF/MANIFEST.MF (100%)
rename {demos/demo-async-rest/demo-async-rest-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-async-rest/demo-ee9-async-rest-webapp}/src/main/webapp/WEB-INF/jetty-web.xml (82%)
rename {demos/demo-async-rest/demo-async-rest-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-async-rest/demo-ee9-async-rest-webapp}/src/main/webapp/WEB-INF/web.xml (100%)
rename {demos/demo-async-rest/demo-async-rest-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-async-rest/demo-ee9-async-rest-webapp}/src/main/webapp/demo.css (100%)
rename {demos/demo-async-rest/demo-async-rest-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-async-rest/demo-ee9-async-rest-webapp}/src/main/webapp/index.html (100%)
rename {demos/demo-async-rest/demo-async-rest-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-async-rest/demo-ee9-async-rest-webapp}/src/main/webapp/small_powered_by.gif (100%)
create mode 100644 jetty-ee9/jetty-ee9-demos/demo-ee9-async-rest/pom.xml
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/pom.xml (67%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/prodDb.properties (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/prodDb.script (100%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/AsyncEchoServlet.java (99%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/DumpServlet.java (98%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/ExampleServer.java (94%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/ExampleServerXml.java (97%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/ExampleUtil.java (98%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/FastFileServer.java (98%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/FileServer.java (96%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/FileServerXml.java (98%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/HelloHandler.java (98%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/HelloServlet.java (97%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/HelloSessionServlet.java (98%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/HelloWorld.java (98%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/Http2Server.java (95%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/JarServer.java (90%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/JettyDemos.java (99%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/LikeJettyXml.java (95%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/ManyConnectors.java (99%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/ManyContexts.java (98%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/ManyHandlers.java (99%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/ManyServletContexts.java (92%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/MinimalServlets.java (96%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/OneConnector.java (97%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/OneContext.java (97%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/OneHandler.java (96%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/OneServletContext.java (94%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/OneServletContextJmxStats.java (92%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/OneServletContextWithSession.java (88%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/OneWebApp.java (94%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/OneWebAppWithJsp.java (95%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/ProxyServer.java (87%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/RewriteServer.java (95%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/SecuredHelloHandler.java (93%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/ServerWithAnnotations.java (81%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/ServerWithJMX.java (97%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/ServerWithJNDI.java (84%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/SimplestServer.java (97%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/SplitFileServer.java (99%)
rename {demos/embedded/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/main/java/org/eclipse/jetty/ee9}/demos/WebSocketServer.java (78%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/other/content.jar (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/demo/demo-realm.properties (89%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/demo/webdefault.xml (97%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/push.html (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile00.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile01.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile02.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile03.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile04.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile05.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile06.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile07.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile08.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile09.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile10.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile11.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile12.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile13.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile14.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile15.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile16.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile17.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile18.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile19.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile20.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile21.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile22.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile23.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile24.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile25.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile26.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile27.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile28.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile29.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile30.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile31.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile32.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile33.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile34.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile35.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile36.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile37.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile38.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile39.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile40.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile41.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile42.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile43.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile44.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile45.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile46.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile47.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile48.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/pushed/tile49.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/readme.txt (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile00.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile01.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile02.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile03.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile04.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile05.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile06.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile07.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile08.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile09.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile10.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile11.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile12.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile13.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile14.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile15.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile16.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile17.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile18.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile19.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile20.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile21.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile22.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile23.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile24.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile25.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile26.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile27.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile28.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile29.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile30.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile31.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile32.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile33.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile34.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile35.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile36.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile37.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile38.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile39.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile40.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile41.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile42.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile43.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile44.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile45.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile46.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile47.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile48.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/docroot/tiles/tile49.jpg (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/etc/keystore.p12 (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/etc/realm.properties (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/exampleserver.xml (93%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/fileserver.xml (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/java-util-logging.properties (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/jetty-logging.properties (90%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/main/resources/logback-access.xml (100%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/AbstractEmbeddedTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/ExampleServerTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/ExampleServerXmlTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/FastFileServerTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/FileServerTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/FileServerXmlTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/JarServerTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/LikeJettyXmlTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/ManyConnectorsTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/ManyContextsTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/ManyHandlersTest.java (99%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/ManyServletContextsTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/MinimalServletsTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/OneConnectorTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/OneContextTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/OneHandlerTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/OneServletContextJmxStatsTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/OneServletContextTest.java (99%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/OneServletContextWithSessionTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/OneWebAppTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/OneWebAppWithJspTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/ProxyServerTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/RewriteServerTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/SecuredHelloHandlerTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/ServerUtil.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/ServerWithAnnotationsTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/ServerWithJMXTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/ServerWithJNDITest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/SimplestServerTest.java (97%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/SplitFileServerTest.java (98%)
rename {demos/embedded/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/java/org/eclipse/jetty/ee9}/demos/WebSocketServerTest.java (85%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/test/resources/dir0/test0.txt (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/test/resources/dir1/test1.txt (100%)
rename {demos/embedded => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded}/src/test/resources/jetty-logging.properties (89%)
rename {demos/demo-spec/demo-spec-webapp/src/etc => jetty-ee9/jetty-ee9-demos/demo-ee9-embedded/src/test/resources}/realm.properties (100%)
rename {demos/demo-jaas-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jaas-webapp}/pom.xml (86%)
rename {demos/demo-jaas-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jaas-webapp}/src/main/config/modules/demo-jaas.mod (100%)
rename {demos/demo-jaas-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jaas-webapp}/src/main/config/modules/demo.d/demo-jaas.xml (92%)
rename {demos/demo-jaas-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jaas-webapp}/src/main/config/modules/demo.d/demo-login.conf (100%)
rename {demos/demo-jaas-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jaas-webapp}/src/main/config/modules/demo.d/demo-login.properties (100%)
rename {demos/demo-jaas-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jaas-webapp}/src/main/webapp/WEB-INF/jetty-web.xml (82%)
rename {demos/demo-jaas-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jaas-webapp}/src/main/webapp/WEB-INF/web.xml (100%)
rename {demos/demo-jaas-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jaas-webapp}/src/main/webapp/auth.html (100%)
rename {demos/demo-jaas-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jaas-webapp}/src/main/webapp/authfail.html (100%)
rename {demos/demo-jaas-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jaas-webapp}/src/main/webapp/demo.css (100%)
rename {demos/demo-jaas-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jaas-webapp}/src/main/webapp/index.html (100%)
rename {demos/demo-jaas-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jaas-webapp}/src/main/webapp/login.html (100%)
rename {demos/demo-jaas-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jaas-webapp}/src/main/webapp/logout.jsp (100%)
rename {demos/demo-jaas-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jaas-webapp}/src/main/webapp/small_powered_by.gif (100%)
rename {demos/demo-jaas-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jaas-webapp}/src/main/webapp/stylesheet.css (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/jetty-chat.jmx (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/pom.xml (88%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/assembly/embedded-jetty-web-for-webbundle.xml (98%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/assembly/web-bundle.xml (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/config/modules/demo-jetty.mod (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/config/modules/demo-moved-context.mod (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/config/modules/demo-rewrite.mod (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/config/modules/demo.d/demo-jetty-override-web.xml (93%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/config/modules/demo.d/demo-jetty.xml (95%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/config/modules/demo.d/demo-moved-context.xml (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/config/modules/demo.d/demo-rewrite-rules.xml (100%)
rename {demos/demo-jetty-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/main/java/org/example}/AddListServletRequestListener.java (98%)
rename {demos/demo-jetty-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/main/java/org/example}/ChatServlet.java (99%)
rename {demos/demo-jetty-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/main/java/org/example}/CookieDump.java (99%)
rename {demos/demo-jetty-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/main/java/org/example}/DispatchServlet.java (99%)
rename {demos/demo-jetty-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/main/java/org/example}/Dump.java (99%)
rename {demos/demo-jetty-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/main/java/org/example}/HelloWorld.java (98%)
rename {demos/demo-jetty-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/main/java/org/example}/JakartaWebSocketChat.java (99%)
rename {demos/demo-jetty-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/main/java/org/example}/LoginServlet.java (99%)
rename {demos/demo-jetty-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/main/java/org/example}/RegTest.java (99%)
rename {demos/demo-jetty-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/main/java/org/example}/RewriteServlet.java (99%)
rename {demos/demo-jetty-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/main/java/org/example}/SecureModeServlet.java (99%)
rename {demos/demo-jetty-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/main/java/org/example}/SessionDump.java (99%)
rename {demos/demo-jetty-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/main/java/org/example}/TestFilter.java (99%)
rename {demos/demo-jetty-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/main/java/org/example}/TestListener.java (99%)
rename {demos/demo-jetty-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/main/java/org/example}/TestServlet.java (98%)
rename {demos/demo-jetty-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/main/java/org/example}/WebSocketChatServlet.java (79%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/WEB-INF/jetty-web.xml (81%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/WEB-INF/web.xml (88%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/auth.html (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/auth/file.txt (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/auth/relax.txt (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/auth2/index.html (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/cgi-bin/hello.sh (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/chat/index.html (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/d.txt (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/da.txt (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/da.txt.gz (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/dat.txt (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/data.txt (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/data.txt.gz (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/demo.css (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/error404.html (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/favicon.ico (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/index.html (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/jakarta.websocket/index.html (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/logon.html (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/logonError.html (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/remote.html (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/rewrite/index.html (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/rewrite/info.html (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/small_powered_by.gif (100%)
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/main/webapp/ws/index.html (100%)
rename {demos/demo-jetty-webapp/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/test/java/org/eclipse/jetty/ee9}/ChatServletTest.java (95%)
rename {demos/demo-jetty-webapp/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/test/java/org/eclipse/jetty/ee9}/DispatchServletTest.java (91%)
rename {demos/demo-jetty-webapp/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/test/java/org/eclipse/jetty/ee9}/TestServer.java (95%)
create mode 100644 jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp/src/test/resources/jetty-logging.properties
rename {demos/demo-jetty-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jetty-webapp}/src/test/resources/test-realm.properties (89%)
rename {demos/demo-jndi-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jndi-webapp}/pom.xml (84%)
rename {demos/demo-jndi-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jndi-webapp}/src/main/config/modules/demo-jndi.mod (100%)
rename {demos/demo-jndi-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jndi-webapp}/src/main/config/modules/demo.d/demo-jndi.xml (93%)
rename {demos/demo-jndi-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jndi-webapp/src/main/java/org/example}/JNDITest.java (99%)
rename {demos/demo-jndi-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jndi-webapp}/src/main/templates/env-definitions.xml (94%)
rename {demos/demo-jndi-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jndi-webapp}/src/main/templates/jetty-test-jndi-header.xml (84%)
rename {demos/demo-jndi-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jndi-webapp}/src/main/templates/plugin-context-header.xml (78%)
rename {demos/demo-jndi-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jndi-webapp}/src/main/webapp/WEB-INF/jetty-env.xml (94%)
rename {demos/demo-jndi-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jndi-webapp}/src/main/webapp/WEB-INF/jetty-web.xml (82%)
rename {demos/demo-jndi-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jndi-webapp}/src/main/webapp/WEB-INF/web.xml (79%)
rename {demos/demo-jndi-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jndi-webapp}/src/main/webapp/demo.css (100%)
rename {demos/demo-jndi-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jndi-webapp}/src/main/webapp/index.html (100%)
rename {demos/demo-jndi-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jndi-webapp}/src/main/webapp/small_powered_by.gif (100%)
rename {demos/demo-jndi-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jndi-webapp}/src/main/webapp/stylesheet.css (100%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/pom.xml (91%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/src/main/assembly/web-bundle.xml (100%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/src/main/config/modules/demo-jsp.mod (100%)
rename {demos/demo-jsp-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp/src/main/java/org/example}/Counter.java (97%)
rename {demos/demo-jsp-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp/src/main/java/org/example}/Date2Tag.java (98%)
rename {demos/demo-jsp-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp/src/main/java/org/example}/DateTag.java (99%)
rename {demos/demo-jsp-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp/src/main/java/org/example}/TagListener.java (99%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/src/main/webapp/WEB-INF/acme-taglib.tld (86%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/src/main/webapp/WEB-INF/acme-taglib2.tld (95%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/src/main/webapp/WEB-INF/jetty-web.xml (82%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/src/main/webapp/WEB-INF/tags/panel.tag (100%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/src/main/webapp/WEB-INF/web.xml (100%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/src/main/webapp/bean1.jsp (78%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/src/main/webapp/bean2.jsp (78%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/src/main/webapp/demo.css (100%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/src/main/webapp/dump.jsp (100%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/src/main/webapp/expr.jsp (100%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/src/main/webapp/foo/foo.jsp (100%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/src/main/webapp/index.jsp (100%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/src/main/webapp/jstl.jsp (100%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/src/main/webapp/small_powered_by.gif (100%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/src/main/webapp/tag.jsp (100%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/src/main/webapp/tag2.jsp (100%)
rename {demos/demo-jsp-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-jsp-webapp}/src/main/webapp/tagfile.jsp (100%)
rename {demos/demo-mock-resources => jetty-ee9/jetty-ee9-demos/demo-ee9-mock-resources}/pom.xml (81%)
rename {demos/demo-mock-resources => jetty-ee9/jetty-ee9-demos/demo-ee9-mock-resources}/src/main/config/modules/demo-mock-resources.mod (100%)
rename {demos/demo-mock-resources/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-mock-resources/src/main/java/org/example}/MockDataSource.java (98%)
rename {demos/demo-mock-resources/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-mock-resources/src/main/java/org/example}/MockTransport.java (98%)
rename {demos/demo-mock-resources/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-mock-resources/src/main/java/org/example}/MockUserTransaction.java (98%)
create mode 100644 jetty-ee9/jetty-ee9-demos/demo-ee9-mock-resources/src/main/resources/META-INF/javaxmail.providers
rename {demos/demo-proxy-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-proxy-webapp}/pom.xml (82%)
rename {demos/demo-proxy-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-proxy-webapp}/src/main/config/modules/demo-proxy.mod (100%)
rename {demos/demo-proxy-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-proxy-webapp}/src/main/webapp/META-INF/MANIFEST.MF (100%)
rename {demos/demo-proxy-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-proxy-webapp}/src/main/webapp/WEB-INF/jetty-web.xml (84%)
rename {demos/demo-proxy-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-proxy-webapp}/src/main/webapp/WEB-INF/web.xml (100%)
rename {demos/demo-proxy-webapp/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-demos/demo-ee9-proxy-webapp/src/test/java/org/eclipse/jetty/ee9}/demos/ProxyWebAppTest.java (97%)
rename {demos/demo-proxy-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-proxy-webapp}/src/test/resources/jetty-logging.properties (100%)
rename {demos/demo-simple-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-simple-webapp}/pom.xml (65%)
rename {demos/demo-simple-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-simple-webapp}/src/main/config/modules/demo-simple.mod (100%)
rename {demos/demo-simple-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-simple-webapp}/src/main/webapp/WEB-INF/web.xml (100%)
rename {demos/demo-simple-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-simple-webapp}/src/main/webapp/index.html (100%)
rename {demos/demo-simple-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-simple-webapp}/src/main/webapp/jetty.icon (100%)
rename {demos/demo-simple-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-simple-webapp}/src/main/webapp/jetty.png (100%)
rename {demos/demo-simple-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-simple-webapp}/src/main/webapp/jetty.webp (100%)
rename {demos/demo-spec/demo-container-initializer => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-container-initializer}/pom.xml (70%)
rename {demos/demo-spec/demo-container-initializer/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-container-initializer/src/main/java/org/example}/initializer/Foo.java (96%)
rename {demos/demo-spec/demo-container-initializer/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-container-initializer/src/main/java/org/example}/initializer/FooInitializer.java (74%)
create mode 100644 jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-container-initializer/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer
rename {demos/demo-spec/demo-spec-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp}/pom.xml (88%)
rename {demos/embedded/src/test/resources => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp/src/etc}/realm.properties (89%)
rename {demos/demo-spec/demo-spec-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp}/src/main/assembly/web-bundle.xml (100%)
rename {demos/demo-spec/demo-spec-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp}/src/main/config/modules/demo-spec.mod (100%)
rename {demos/demo-spec/demo-spec-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp}/src/main/config/modules/demo.d/demo-spec.xml (82%)
rename {demos/demo-spec/demo-spec-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp/src/main/java/org/example}/test/AnnotatedListener.java (90%)
rename {demos/demo-spec/demo-spec-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp/src/main/java/org/example}/test/AnnotationTest.java (87%)
rename {demos/demo-spec/demo-spec-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp/src/main/java/org/example}/test/AsyncListenerServlet.java (99%)
rename {demos/demo-spec/demo-spec-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp/src/main/java/org/example}/test/Bar.java (91%)
rename {demos/demo-spec/demo-spec-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp/src/main/java/org/example}/test/ClassLoaderServlet.java (99%)
rename {demos/demo-spec/demo-spec-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp/src/main/java/org/example}/test/MultiPartTest.java (99%)
rename {demos/demo-spec/demo-spec-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp/src/main/java/org/example}/test/RoleAnnotationTest.java (99%)
rename {demos/demo-spec/demo-spec-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp/src/main/java/org/example}/test/SecuredServlet.java (98%)
rename {demos/demo-spec/demo-spec-webapp/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp/src/main/java/org/example}/test/TestListener.java (82%)
rename {demos/demo-spec/demo-spec-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp}/src/main/templates/annotations-context-header.xml (87%)
rename {demos/demo-spec/demo-spec-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp}/src/main/templates/env-definitions.xml (89%)
rename {demos/demo-spec/demo-spec-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp}/src/main/templates/plugin-context-header.xml (80%)
rename {demos/demo-spec/demo-spec-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp}/src/main/webapp/WEB-INF/jetty-env.xml (85%)
rename {demos/demo-spec/demo-spec-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp}/src/main/webapp/WEB-INF/jetty-web.xml (89%)
rename {demos/demo-spec/demo-spec-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp}/src/main/webapp/WEB-INF/web.xml (90%)
rename {demos/demo-spec/demo-spec-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp}/src/main/webapp/authfail.html (100%)
rename {demos/demo-spec/demo-spec-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp}/src/main/webapp/demo.css (100%)
rename {demos/demo-spec/demo-spec-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp}/src/main/webapp/dynamic.jsp (100%)
rename {demos/demo-spec/demo-spec-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp}/src/main/webapp/index.html (100%)
rename {demos/demo-spec/demo-spec-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp}/src/main/webapp/login.html (100%)
rename {demos/demo-spec/demo-spec-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp}/src/main/webapp/logout.jsp (100%)
rename {demos/demo-spec/demo-spec-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp}/src/main/webapp/small_powered_by.gif (100%)
rename {demos/demo-spec/demo-spec-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp}/src/main/webapp/stylesheet.css (100%)
rename {demos/demo-spec/demo-spec-webapp => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-spec-webapp}/src/test/jetty-plugin-env.xml (84%)
rename {demos/demo-spec/demo-web-fragment => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-web-fragment}/pom.xml (72%)
rename {demos/demo-spec/demo-web-fragment/src/main/java/com/acme => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-web-fragment/src/main/java/org/example}/fragment/FragmentServlet.java (98%)
rename {demos/demo-spec/demo-web-fragment => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-web-fragment}/src/main/resources/META-INF/resources/fragmentA/index.html (100%)
rename {demos/demo-spec/demo-web-fragment => jetty-ee9/jetty-ee9-demos/demo-ee9-spec/demo-ee9-web-fragment}/src/main/resources/META-INF/web-fragment.xml (86%)
rename {demos/demo-spec => jetty-ee9/jetty-ee9-demos/demo-ee9-spec}/pom.xml (50%)
rename {demos/demo-template => jetty-ee9/jetty-ee9-demos/demo-ee9-template}/pom.xml (76%)
rename {demos/demo-template => jetty-ee9/jetty-ee9-demos/demo-ee9-template}/src/main/resources/demo.css (100%)
rename {demos/demo-template => jetty-ee9/jetty-ee9-demos/demo-ee9-template}/src/main/resources/index.html (100%)
rename {demos/demo-template => jetty-ee9/jetty-ee9-demos/demo-ee9-template}/src/main/resources/small_powered_by.gif (100%)
rename {demos => jetty-ee9/jetty-ee9-demos}/pom.xml (50%)
create mode 100644 jetty-ee9/jetty-ee9-fcgi-server-proxy/pom.xml
create mode 100644 jetty-ee9/jetty-ee9-fcgi-server-proxy/src/main/java/module-info.java
rename {jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-fcgi-server-proxy/src/main/java/org/eclipse/jetty/ee9}/fcgi/server/proxy/FastCGIProxyServlet.java (97%)
rename {jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-fcgi-server-proxy/src/main/java/org/eclipse/jetty/ee9}/fcgi/server/proxy/TryFilesFilter.java (99%)
rename {jetty-fcgi/fcgi-server => jetty-ee9/jetty-ee9-fcgi-server-proxy}/src/test/java/org/eclipse/jetty/fcgi/server/proxy/DrupalHTTP2FastCGIProxyServer.java (93%)
rename {jetty-fcgi/fcgi-server => jetty-ee9/jetty-ee9-fcgi-server-proxy}/src/test/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServletTest.java (98%)
rename {jetty-fcgi/fcgi-server => jetty-ee9/jetty-ee9-fcgi-server-proxy}/src/test/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilterTest.java (94%)
rename {jetty-fcgi/fcgi-server => jetty-ee9/jetty-ee9-fcgi-server-proxy}/src/test/java/org/eclipse/jetty/fcgi/server/proxy/WordPressHTTP2FastCGIProxyServer.java (91%)
rename {glassfish-jstl => jetty-ee9/jetty-ee9-glassfish-jstl}/pom.xml (69%)
rename {glassfish-jstl => jetty-ee9/jetty-ee9-glassfish-jstl}/src/main/config/modules/glassfish-jstl.mod (100%)
rename {glassfish-jstl => jetty-ee9/jetty-ee9-glassfish-jstl}/src/main/resources/readme.txt (100%)
rename {glassfish-jstl/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-glassfish-jstl/src/test/java/org/eclipse/jetty/ee9}/jstl/JspConfig.java (93%)
rename {glassfish-jstl/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-glassfish-jstl/src/test/java/org/eclipse/jetty/ee9}/jstl/JspIncludeTest.java (95%)
rename {glassfish-jstl/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-glassfish-jstl/src/test/java/org/eclipse/jetty/ee9}/jstl/JstlTest.java (97%)
rename {glassfish-jstl => jetty-ee9/jetty-ee9-glassfish-jstl}/src/test/resources/jetty-logging.properties (100%)
rename {glassfish-jstl => jetty-ee9/jetty-ee9-glassfish-jstl}/src/test/taglibjar/META-INF/etag.tld (100%)
rename {glassfish-jstl => jetty-ee9/jetty-ee9-glassfish-jstl}/src/test/taglibjar/META-INF/tags/errorhandler.tag (100%)
rename {glassfish-jstl => jetty-ee9/jetty-ee9-glassfish-jstl}/src/test/webapp/WEB-INF/web.xml (100%)
rename {glassfish-jstl => jetty-ee9/jetty-ee9-glassfish-jstl}/src/test/webapp/catch-basic.jsp (100%)
rename {glassfish-jstl => jetty-ee9/jetty-ee9-glassfish-jstl}/src/test/webapp/catch-taglib.jsp (100%)
rename {glassfish-jstl => jetty-ee9/jetty-ee9-glassfish-jstl}/src/test/webapp/included.jsp (100%)
rename {glassfish-jstl => jetty-ee9/jetty-ee9-glassfish-jstl}/src/test/webapp/ref.jsp (100%)
rename {glassfish-jstl => jetty-ee9/jetty-ee9-glassfish-jstl}/src/test/webapp/top.jsp (100%)
rename {glassfish-jstl => jetty-ee9/jetty-ee9-glassfish-jstl}/src/test/webapp/urls.jsp (100%)
rename {jetty-jaas => jetty-ee9/jetty-ee9-jaas}/pom.xml (94%)
rename {jetty-jaas => jetty-ee9/jetty-ee9-jaas}/src/main/java/module-info.java (76%)
rename {jetty-jaas/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9}/jaas/callback/package-info.java (93%)
rename {jetty-jaas/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9}/jaas/package-info.java (94%)
rename {jetty-jaas/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9}/jaas/spi/package-info.java (94%)
rename {jetty-jaspi => jetty-ee9/jetty-ee9-jaspi}/pom.xml (87%)
rename {jetty-jaspi => jetty-ee9/jetty-ee9-jaspi}/src/main/java/module-info.java (59%)
rename {jetty-jaspi/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9}/security/jaspi/SimpleAuthConfig.java (97%)
rename {jetty-jaspi/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9}/security/jaspi/callback/package-info.java (91%)
rename {jetty-jaspi/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9}/security/jaspi/modules/package-info.java (92%)
rename {jetty-jaspi/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9}/security/jaspi/package-info.java (93%)
rename {jetty-jaspi/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9}/security/jaspi/provider/SimpleAuthConfig.java (97%)
rename {jetty-jspc-maven-plugin => jetty-ee9/jetty-ee9-jspc-maven-plugin}/pom.xml (56%)
rename {jetty-jspc-maven-plugin => jetty-ee9/jetty-ee9-jspc-maven-plugin}/src/it/package-root/invoker.properties (100%)
rename {jetty-jspc-maven-plugin => jetty-ee9/jetty-ee9-jspc-maven-plugin}/src/it/package-root/pom.xml (96%)
rename {jetty-jspc-maven-plugin => jetty-ee9/jetty-ee9-jspc-maven-plugin}/src/it/package-root/postbuild.groovy (100%)
rename {jetty-jspc-maven-plugin => jetty-ee9/jetty-ee9-jspc-maven-plugin}/src/it/package-root/src/main/webapp/foo.jsp (100%)
rename {jetty-jspc-maven-plugin => jetty-ee9/jetty-ee9-jspc-maven-plugin}/src/it/simple-jsp-fail/invoker.properties (100%)
rename {jetty-jspc-maven-plugin => jetty-ee9/jetty-ee9-jspc-maven-plugin}/src/it/simple-jsp-fail/pom.xml (96%)
rename {jetty-jspc-maven-plugin => jetty-ee9/jetty-ee9-jspc-maven-plugin}/src/it/simple-jsp-fail/postbuild.groovy (100%)
rename {jetty-jspc-maven-plugin => jetty-ee9/jetty-ee9-jspc-maven-plugin}/src/it/simple-jsp-fail/src/main/jsp/foo.jsp (100%)
rename {jetty-jspc-maven-plugin => jetty-ee9/jetty-ee9-jspc-maven-plugin}/src/it/simple-jsp/invoker.properties (100%)
rename {jetty-jspc-maven-plugin => jetty-ee9/jetty-ee9-jspc-maven-plugin}/src/it/simple-jsp/pom.xml (96%)
rename {jetty-jspc-maven-plugin => jetty-ee9/jetty-ee9-jspc-maven-plugin}/src/it/simple-jsp/postbuild.groovy (100%)
rename {jetty-jspc-maven-plugin => jetty-ee9/jetty-ee9-jspc-maven-plugin}/src/it/simple-jsp/src/main/webapp/foo.jsp (100%)
rename {jetty-jspc-maven-plugin/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-jspc-maven-plugin/src/main/java/org/eclipse/jetty/ee9}/jspc/plugin/package-info.java (93%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/pom.xml (80%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/it-parent-pom/invoker.properties (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/it-parent-pom/pom.xml (99%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-cdi-start-forked/invoker.properties (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-cdi-start-forked/pom.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-cdi-start-forked/postbuild.groovy (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-cdi-start-forked/src/main/jetty/jetty.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-maven-plugin-provided-module-dep/api/pom.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-maven-plugin-provided-module-dep/invoker.properties (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-maven-plugin-provided-module-dep/pom.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-maven-plugin-provided-module-dep/postbuild.groovy (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-maven-plugin-provided-module-dep/web/pom.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-maven-plugin-provided-module-dep/web/src/config/jetty.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-run-mojo-jar-scan-it/MyLibrary/pom.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-run-mojo-jar-scan-it/MyWebApp/pom.xml (100%)
rename {jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp => jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyWebApp}/src/config/context.xml (76%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-run-mojo-jar-scan-it/MyWebApp/src/config/jetty.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-run-mojo-jar-scan-it/MyWebApp/src/main/webapp/index.html (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-run-mojo-jar-scan-it/invoker.properties (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-run-mojo-jar-scan-it/pom.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-run-mojo-jar-scan-it/postbuild.groovy (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-distro-mojo-it/invoker.properties (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-distro-mojo-it/jetty-simple-base/pom.xml (96%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_distro_mojo_it/HelloServlet.java (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_distro_mojo_it/PingServlet.java (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-distro-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-distro-mojo-it/jetty-simple-webapp/pom.xml (98%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-distro-mojo-it/jetty-simple-webapp/src/base/modules/testmod.mod (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-distro-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-distro-mojo-it/pom.xml (97%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-distro-mojo-it/postbuild.groovy (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-forked-mojo-it/invoker.properties (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-forked-mojo-it/jetty-simple-base/pom.xml (96%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/Counter.java (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/HelloServlet.java (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/PingServlet.java (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-forked-mojo-it/jetty-simple-webapp/pom.xml (98%)
rename {jetty-maven-plugin/src/it/exclude-javax-annotation => jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-webapp}/src/config/jetty.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-forked-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-forked-mojo-it/jetty-simple-webapp/src/main/webapp/jsp/bean1.jsp (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-forked-mojo-it/pom.xml (97%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-forked-mojo-it/postbuild.groovy (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-gwt-it/beer-client/pom.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-gwt-it/beer-server/pom.xml (100%)
rename {jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-webapp => jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-gwt-it/beer-server}/src/config/jetty.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-gwt-it/beer-server/src/main/jettyconf/context.xml (60%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-gwt-it/beer-server/src/main/webapp/WEB-INF/web.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-gwt-it/beer-server/src/main/webapp/index.html (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-gwt-it/beer-shared/pom.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-gwt-it/invoker.properties (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-gwt-it/pom.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-gwt-it/postbuild.groovy (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-it/invoker.properties (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-it/jetty-simple-base/pom.xml (96%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/Counter.java (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/HelloServlet.java (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/PingServlet.java (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-it/jetty-simple-webapp/pom.xml (98%)
rename {jetty-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyWebApp => jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp}/src/config/context.xml (76%)
rename {jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server => jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp}/src/config/jetty.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/main/webapp/jsp/bean1.jsp (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-it/pom.xml (97%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-it/postbuild.groovy (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-multi-module-single-war-it/common/pom.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-multi-module-single-war-it/invoker.properties (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-api/pom.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-impl/pom.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-multi-module-single-war-it/module/pom.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-multi-module-single-war-it/pom.xml (97%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-multi-module-single-war-it/postbuild.groovy (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-multi-module-single-war-it/webapp-war/pom.xml (100%)
rename {jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp => jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/webapp-war}/src/config/jetty.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-mojo-multi-module-single-war-it/webapp-war/src/main/webapp/WEB-INF/web.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-distro-mojo-it/invoker.properties (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/pom.xml (96%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/HelloServlet.java (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/PingServlet.java (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-distro-mojo-it/jetty-simple-webapp/pom.xml (98%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-distro-mojo-it/jetty-simple-webapp/src/base/modules/testmod.mod (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-distro-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-distro-mojo-it/pom.xml (97%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-distro-mojo-it/postbuild.groovy (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-forked-mojo-it/invoker.properties (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/pom.xml (96%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/HelloServlet.java (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/PingServlet.java (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-forked-mojo-it/jetty-simple-webapp/pom.xml (98%)
rename {jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/webapp-war => jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-webapp}/src/config/jetty.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-forked-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-forked-mojo-it/pom.xml (97%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-forked-mojo-it/postbuild.groovy (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-mojo-it/invoker.properties (100%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-mojo-it/pom.xml (98%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/it/jetty-start-war-mojo-it/postbuild.groovy (100%)
rename {jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-webapp => jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-war-mojo-it}/src/config/jetty.xml (100%)
rename {jetty-maven-plugin/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9}/maven/plugin/package-info.java (93%)
rename {jetty-maven-plugin => jetty-ee9/jetty-ee9-maven-plugin}/src/test/resources/root/index.html (100%)
create mode 100644 jetty-ee9/jetty-ee9-nested/pom.xml
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/assembly/site-component.xml
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/module-info.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/AbstractHandler.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/AbstractHandlerContainer.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/AllowSymLinkAliasChecker.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/AllowedResourceAliasChecker.java
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/AsyncAttributes.java (94%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/AsyncContentProducer.java (78%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/AsyncContextEvent.java (87%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/AsyncContextState.java (96%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server/handler => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/AsyncDelayHandler.java (98%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/Authentication.java (99%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/BlockingContentProducer.java (92%)
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/BufferedResponseHandler.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/CachedContentFactory.java
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/ContentProducer.java (77%)
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ContextHandler.java
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/Cookies.java (99%)
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/DebugHandler.java
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/DebugListener.java (96%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/Dispatcher.java (91%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/EncodingHttpWriter.java (97%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server/handler => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/ErrorHandler.java (94%)
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/FileBufferedResponseHandler.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Handler.java
rename {jetty-server/src/main/java/org/eclipse/jetty/server/handler => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/HandlerCollection.java (97%)
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HandlerContainer.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HandlerList.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HandlerWrapper.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HotSwapHandler.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HttpChannel.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HttpChannelListeners.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HttpChannelState.java
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/HttpChannelState_input.puml (100%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/HttpInput.java (63%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/HttpInputState.puml (100%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/HttpInput_async.puml (100%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/HttpInput_blocking.puml (100%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/HttpOutput.java (98%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/HttpWriter.java (98%)
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/IdleTimeoutHandler.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/InclusiveByteRange.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/InetAccessHandler.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/InetAccessSet.java
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/Iso88591HttpWriter.java (97%)
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ManagedAttributeListener.java
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/MultiPartFormInputStream.java (99%)
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/MultiPartParser.java
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/PushBuilderImpl.java (98%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/QuietServletException.java (97%)
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Request.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ResourceContentFactory.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ResourceHandler.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ResourceService.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Response.java
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/ResponseWriter.java (99%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/SameFileAliasChecker.java (91%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server/handler => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/ScopedHandler.java (81%)
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/SecuredRedirectHandler.java
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/ServletAttributes.java (83%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/ServletPathMapping.java (95%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/ServletRequestHttpWrapper.java (99%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/ServletResponseHttpWrapper.java (98%)
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/SessionHandler.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ShutdownHandler.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/StatisticsHandler.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/SymlinkAllowedResourceAliasChecker.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ThreadLimitHandler.java
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/UserIdentity.java (97%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/Utf8HttpWriter.java (99%)
rename {jetty-server/src/main/java/org/eclipse/jetty/server/handler => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/jmx/AbstractHandlerMBean.java (85%)
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/jmx/ContextHandlerMBean.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/jmx/package-info.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/package-info.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/resource/ByteBufferRangeWriter.java
rename {jetty-server/src/main/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested}/resource/HttpContentRangeWriter.java (53%)
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/resource/InputStreamRangeWriter.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/resource/RangeWriter.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/resource/SeekableByteChannelRangeWriter.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/resources/jetty-dir.css
create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/resources/org/eclipse/nested/favicon.ico
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/AbstractHttpTest.java
rename {jetty-server/src/test/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested}/AsyncCompletionTest.java (92%)
rename {jetty-server/src/test/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested}/AsyncContentProducerTest.java (58%)
rename {jetty-server/src/test/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested}/AsyncRequestReadTest.java (88%)
rename {jetty-server/src/test/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested}/BlockingContentProducerTest.java (64%)
rename {jetty-server/src/test/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested}/BlockingTest.java (97%)
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/ContextHandlerTest.java
rename {jetty-server/src/test/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested}/CookiesTest.java (99%)
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/DumpHandler.java
rename {jetty-server/src/test/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested}/ErrorHandlerTest.java (98%)
rename {jetty-server/src/test/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested}/HttpManyWaysToAsyncCommitTest.java (97%)
rename {jetty-server/src/test/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested}/HttpManyWaysToCommitTest.java (96%)
rename {jetty-server/src/test/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested}/HttpOutputTest.java (98%)
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/HttpServerTestFixture.java
rename {jetty-server/src/test/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested}/HttpWriterTest.java (95%)
rename {jetty-server/src/test/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested}/LocalAsyncContextTest.java (94%)
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/MockConnectionMetaData.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/MockConnector.java
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/RequestTest.java
rename {jetty-server/src/test/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested}/ResponseTest.java (85%)
rename {jetty-server/src/test/java/org/eclipse/jetty/server/handler => jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested}/ScopedHandlerTest.java (92%)
rename {jetty-server/src/test/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested}/ServerConnectorAsyncContextTest.java (89%)
rename {jetty-server/src/test/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested}/ServletRequestWrapperTest.java (73%)
rename {jetty-server/src/test/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested}/ServletWriterTest.java (85%)
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/SessionHandlerTest.java
rename {jetty-server/src/test/java/org/eclipse/jetty/server => jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested}/SuspendHandler.java (98%)
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/example.jar
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/fakeRequests.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/jetty-logging.properties
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/keystore.p12
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/keystore_sni.p12
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/keystore_sni_key_types.p12
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/keystore_sni_nowild.p12
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-company-urlencoded-apache-httpcomp.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-company-urlencoded-apache-httpcomp.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-complex-apache-httpcomp.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-complex-apache-httpcomp.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-complex-jetty-client.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-complex-jetty-client.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-duplicate-names-apache-httpcomp.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-duplicate-names-apache-httpcomp.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-duplicate-names-jetty-client.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-duplicate-names-jetty-client.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-encoding-mess-apache-httpcomp.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-encoding-mess-apache-httpcomp.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-encoding-mess-jetty-client.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-encoding-mess-jetty-client.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-alt-chrome.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-alt-chrome.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-alt-edge.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-alt-edge.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-alt-firefox.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-alt-firefox.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-alt-msie.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-alt-msie.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-alt-safari.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-alt-safari.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-android-chrome.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-android-chrome.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-android-firefox.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-android-firefox.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-chrome.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-chrome.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-edge.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-edge.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-firefox.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-firefox.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-ios-safari.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-ios-safari.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-msie.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-msie.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-safari.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form-fileupload-safari.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form1-android-chrome.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form1-android-chrome.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form1-android-firefox.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form1-android-firefox.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form1-chrome.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form1-chrome.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form1-edge.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form1-edge.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form1-firefox.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form1-firefox.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form1-ios-safari.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form1-ios-safari.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form1-msie.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form1-msie.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form1-osx-safari.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-form1-osx-safari.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-nested-apache-httpcomp.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-nested-apache-httpcomp.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-nested-binary-apache-httpcomp.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-nested-binary-apache-httpcomp.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-nested-jetty-client.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-nested-jetty-client.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-number-only-apache-httpcomp.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-number-only-apache-httpcomp.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-number-only-jetty-client.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-number-only-jetty-client.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-number-only2-apache-httpcomp.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-number-only2-apache-httpcomp.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-apache-httpcomp.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-apache-httpcomp.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-charset-form-android-chrome.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-charset-form-android-chrome.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-charset-form-android-firefox.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-charset-form-android-firefox.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-charset-form-chrome.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-charset-form-chrome.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-charset-form-edge.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-charset-form-edge.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-charset-form-firefox.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-charset-form-firefox.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-charset-form-ios-safari.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-charset-form-ios-safari.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-charset-form-msie.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-charset-form-msie.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-charset-form-safari.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-charset-form-safari.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-form-android-chrome.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-form-android-chrome.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-form-android-firefox.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-form-android-firefox.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-form-chrome.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-form-chrome.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-form-edge.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-form-edge.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-form-firefox.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-form-firefox.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-form-ios-safari.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-form-ios-safari.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-form-msie.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-form-msie.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-form-safari.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-form-safari.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-jetty-client.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-sjis-jetty-client.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-strange-quoting-apache-httpcomp.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-strange-quoting-apache-httpcomp.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-text-files-apache-httpcomp.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-text-files-apache-httpcomp.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-text-files-jetty-client.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-text-files-jetty-client.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-unicode-names-apache-httpcomp.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-unicode-names-apache-httpcomp.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-unicode-names-jetty-client.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-unicode-names-jetty-client.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-whitespace-only-jetty-client.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-whitespace-only-jetty-client.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-zalgo-text-plain-apache-httpcomp.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/browser-capture-zalgo-text-plain-apache-httpcomp.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/multipart-base64-long.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/multipart-base64-long.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/multipart-base64.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/multipart-base64.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/multipart-uppercase.expected.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/multipart/multipart-uppercase.raw
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/reload_keystore_1.p12
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/reload_keystore_2.p12
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/simple/big.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/simple/directory/content.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/simple/directory/welcome.txt
create mode 100644 jetty-ee9/jetty-ee9-nested/src/test/resources/simple/simple.txt
rename {jetty-openid => jetty-ee9/jetty-ee9-openid}/pom.xml (84%)
rename {jetty-openid => jetty-ee9/jetty-ee9-openid}/src/main/java/module-info.java (78%)
create mode 100644 jetty-ee9/jetty-ee9-openid/src/main/resources/META-INF/services/org.eclipse.jetty.ee9.security.Authenticator$Factory
rename {jetty-osgi/jetty-osgi-alpn => jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-alpn}/pom.xml (81%)
rename {jetty-osgi/jetty-osgi-boot-jsp => jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot-jsp}/pom.xml (91%)
rename {jetty-osgi/jetty-osgi-boot-warurl => jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot-warurl}/pom.xml (72%)
rename {jetty-osgi/jetty-osgi-boot => jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot}/jettyhome/contexts/README (100%)
rename {jetty-osgi/jetty-osgi-boot => jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot}/jettyhome/etc/README (100%)
rename {jetty-osgi/jetty-osgi-boot => jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot}/jettyhome/etc/jetty-deploy.xml (100%)
rename {jetty-osgi/jetty-osgi-boot => jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot}/jettyhome/etc/jetty-http.xml (100%)
rename {jetty-osgi/jetty-osgi-boot => jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot}/jettyhome/etc/jetty.xml (85%)
rename {jetty-osgi/jetty-osgi-boot => jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot}/jettyhome/lib/ext/README (100%)
rename {jetty-osgi/jetty-osgi-boot => jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot}/jettyhome/logs/README (100%)
rename {jetty-osgi/jetty-osgi-boot => jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot}/jettyhome/resources/README (100%)
rename {jetty-osgi/jetty-osgi-boot => jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot}/jettyhome/webapps/README (100%)
rename {jetty-osgi/jetty-osgi-boot => jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot}/pom.xml (84%)
rename {jetty-osgi/jetty-osgi-httpservice => jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-httpservice}/pom.xml (82%)
rename {jetty-osgi => jetty-ee9/jetty-ee9-osgi}/pom.xml (74%)
rename {jetty-osgi/test-jetty-osgi-context => jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-context}/pom.xml (87%)
rename {jetty-osgi/test-jetty-osgi-context => jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-context}/src/main/java/com/acme/osgi/Activator.java (100%)
rename {jetty-osgi/test-jetty-osgi-context => jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-context}/src/main/resources/static/index.html (100%)
rename {jetty-osgi/test-jetty-osgi-fragment => jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-fragment}/pom.xml (88%)
rename {jetty-osgi/test-jetty-osgi-server => jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-server}/pom.xml (89%)
rename {jetty-osgi/test-jetty-osgi-server => jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-server}/src/main/java/com/acme/osgi/Activator.java (85%)
rename {jetty-osgi/test-jetty-osgi-server => jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-server}/src/main/resources/index.html (100%)
rename {jetty-osgi/test-jetty-osgi-webapp-resources => jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp-resources}/pom.xml (93%)
rename {jetty-osgi/test-jetty-osgi-webapp => jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp}/pom.xml (85%)
rename {jetty-osgi/test-jetty-osgi-webapp => jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp}/src/main/java/com/acme/osgi/Activator.java (96%)
rename {jetty-osgi/test-jetty-osgi-webapp => jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp}/src/main/resources/index.html (100%)
rename {jetty-osgi/test-jetty-osgi-webapp => jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp}/src/main/resources/webappA/index.html (100%)
rename {jetty-osgi/test-jetty-osgi-webapp => jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp}/src/main/resources/webappB/index.html (100%)
rename {jetty-osgi/test-jetty-osgi => jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi}/pom.xml (86%)
rename {jetty-osgi/test-jetty-osgi => jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi}/src/test/config/etc/jetty-deploy.xml (100%)
rename {jetty-osgi/test-jetty-osgi => jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi}/src/test/config/etc/jetty-http.xml (96%)
rename {jetty-osgi/test-jetty-osgi => jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi}/src/test/config/etc/jetty.xml (82%)
rename {jetty-osgi/test-jetty-osgi => jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi}/src/test/resources/module-info.java (100%)
rename {jetty-plus => jetty-ee9/jetty-ee9-plus}/pom.xml (85%)
rename {jetty-plus => jetty-ee9/jetty-ee9-plus}/src/main/java/module-info.java (63%)
rename {jetty-plus/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9}/plus/annotation/package-info.java (93%)
rename {jetty-plus/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9}/plus/jndi/package-info.java (93%)
rename {jetty-plus/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9}/plus/security/package-info.java (93%)
rename {jetty-plus/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9}/plus/webapp/package-info.java (93%)
create mode 100644 jetty-ee9/jetty-ee9-plus/src/main/resources/META-INF/services/org.eclipse.jetty.ee9.webapp.Configuration
rename {jetty-proxy => jetty-ee9/jetty-ee9-proxy}/pom.xml (86%)
rename {jetty-proxy => jetty-ee9/jetty-ee9-proxy}/src/main/java/module-info.java (85%)
rename {jetty-proxy/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-proxy/src/main/java/org/eclipse/jetty/ee9}/proxy/package-info.java (94%)
rename {jetty-proxy => jetty-ee9/jetty-ee9-proxy}/src/test/resources/client_auth/client_keystore.p12 (100%)
rename {jetty-proxy => jetty-ee9/jetty-ee9-proxy}/src/test/resources/client_auth/proxy_keystore.p12 (100%)
rename {jetty-proxy => jetty-ee9/jetty-ee9-proxy}/src/test/resources/client_auth/server_keystore.p12 (100%)
rename {jetty-proxy => jetty-ee9/jetty-ee9-proxy}/src/test/resources/client_keystore.p12 (100%)
rename {jetty-proxy => jetty-ee9/jetty-ee9-proxy}/src/test/resources/proxy_keystore.p12 (100%)
rename {jetty-proxy => jetty-ee9/jetty-ee9-proxy}/src/test/resources/server_keystore.p12 (100%)
rename {jetty-quickstart => jetty-ee9/jetty-ee9-quickstart}/pom.xml (74%)
rename {jetty-quickstart => jetty-ee9/jetty-ee9-quickstart}/src/main/java/module-info.java (81%)
rename {jetty-runner => jetty-ee9/jetty-ee9-runner}/pom.xml (85%)
rename {jetty-runner => jetty-ee9/jetty-ee9-runner}/src/it/demo-simple-webapp-runner-with-path/invoker.properties (100%)
rename {jetty-runner => jetty-ee9/jetty-ee9-runner}/src/it/demo-simple-webapp-runner-with-path/pom.xml (97%)
rename {jetty-runner => jetty-ee9/jetty-ee9-runner}/src/it/demo-simple-webapp-runner/invoker.properties (100%)
rename {jetty-runner => jetty-ee9/jetty-ee9-runner}/src/it/demo-simple-webapp-runner/pom.xml (97%)
rename {jetty-runner => jetty-ee9/jetty-ee9-runner}/src/it/test-jar-manifest/invoker.properties (100%)
rename {jetty-runner => jetty-ee9/jetty-ee9-runner}/src/it/test-jar-manifest/pom.xml (100%)
rename {jetty-runner/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-runner/src/main/java/org/eclipse/jetty/ee9}/runner/package-info.java (94%)
rename {jetty-security => jetty-ee9/jetty-ee9-security}/pom.xml (86%)
rename {jetty-security => jetty-ee9/jetty-ee9-security}/src/main/java/module-info.java (74%)
rename {jetty-security/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9}/security/authentication/package-info.java (91%)
rename {jetty-security/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9}/security/package-info.java (94%)
rename {jetty-security => jetty-ee9/jetty-ee9-security}/src/test/resources/docroot/all/index.txt (100%)
rename {jetty-security => jetty-ee9/jetty-ee9-security}/src/test/resources/docroot/forbid/index.txt (100%)
rename {jetty-servlet => jetty-ee9/jetty-ee9-servlet}/pom.xml (81%)
rename {jetty-servlet => jetty-ee9/jetty-ee9-servlet}/src/main/java/module-info.java (76%)
rename {jetty-servlet/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9}/servlet/jmx/package-info.java (93%)
rename {jetty-servlet/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9}/servlet/listener/package-info.java (92%)
rename {jetty-servlet/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9}/servlet/package-info.java (94%)
rename {jetty-servlet => jetty-ee9/jetty-ee9-servlet}/src/test/resources/contextResources/content.txt (100%)
rename {jetty-servlet => jetty-ee9/jetty-ee9-servlet}/src/test/resources/dispatchResourceTest/content.txt (100%)
rename {jetty-servlets => jetty-ee9/jetty-ee9-servlets}/pom.xml (75%)
rename {jetty-servlets => jetty-ee9/jetty-ee9-servlets}/src/main/java/module-info.java (86%)
rename {jetty-servlets/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-servlets/src/main/java/org/eclipse/jetty/ee9}/servlets/package-info.java (94%)
create mode 100644 jetty-ee9/jetty-ee9-tests/pom.xml
rename {tests/test-webapps => jetty-ee9/jetty-ee9-tests}/test-bad-websocket-webapp/pom.xml (75%)
rename {tests/test-webapps/test-bad-websocket-webapp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-bad-websocket-webapp/src/main/java/org/eclipse/jetty/ee9}/tests/webapp/websocket/bad/BadOnCloseServerEndpoint.java (96%)
rename {tests/test-webapps/test-bad-websocket-webapp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-bad-websocket-webapp/src/main/java/org/eclipse/jetty/ee9}/tests/webapp/websocket/bad/BadOnOpenServerEndpoint.java (95%)
rename {tests/test-webapps/test-bad-websocket-webapp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-bad-websocket-webapp/src/main/java/org/eclipse/jetty/ee9}/tests/webapp/websocket/bad/StringSequence.java (95%)
rename {tests/test-webapps => jetty-ee9/jetty-ee9-tests}/test-bad-websocket-webapp/src/main/webapp/WEB-INF/web.xml (100%)
rename {tests/test-webapps => jetty-ee9/jetty-ee9-tests}/test-bad-websocket-webapp/src/main/webapp/index.jsp (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-cdi/pom.xml (76%)
rename {tests/test-cdi/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-cdi/src/test/java/org/eclipse/jetty/ee9}/cdi/tests/EmbeddedWeldTest.java (93%)
rename {tests/test-cdi/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-cdi/src/test/java/org/eclipse/jetty/ee9}/cdi/tests/FriendlyGreetings.java (96%)
rename {tests/test-cdi/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-cdi/src/test/java/org/eclipse/jetty/ee9}/cdi/tests/Greetings.java (93%)
rename {tests/test-cdi/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-cdi/src/test/java/org/eclipse/jetty/ee9}/cdi/tests/GreetingsServlet.java (97%)
rename {tests/test-cdi/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-cdi/src/test/java/org/eclipse/jetty/ee9}/cdi/tests/MyContextListener.java (96%)
rename {tests/test-cdi/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-cdi/src/test/java/org/eclipse/jetty/ee9}/cdi/tests/MyFilter.java (97%)
rename {tests/test-cdi/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-cdi/src/test/java/org/eclipse/jetty/ee9}/cdi/tests/websocket/JavaxWebSocketCdiTest.java (95%)
rename {tests/test-cdi/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-cdi/src/test/java/org/eclipse/jetty/ee9}/cdi/tests/websocket/JettyWebSocketCdiTest.java (84%)
rename {tests/test-cdi/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-cdi/src/test/java/org/eclipse/jetty/ee9}/cdi/tests/websocket/LogFactory.java (94%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-cdi/src/test/resources/META-INF/beans.xml (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-cdi/src/test/resources/jetty-logging.properties (70%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-cdi/src/test/weldtest/.donotdelete (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-http-client-transport/pom.xml (92%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/AbstractTest.java (96%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/AsyncIOServletTest.java (99%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/AsyncRequestContentTest.java (99%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/BlockedIOTest.java (99%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/ConnectionStatisticsTest.java (96%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/EmptyServerHandler.java (96%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/HttpChannelAssociationTest.java (97%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/HttpClientConnectTimeoutTest.java (99%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/HttpClientContinueTest.java (99%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/HttpClientDemandTest.java (99%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/HttpClientIdleTimeoutTest.java (98%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/HttpClientLoadTest.java (99%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/HttpClientStreamTest.java (99%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/HttpClientTest.java (99%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/HttpClientTimeoutTest.java (99%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/HttpClientTransportDynamicTest.java (99%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/HttpTrailersTest.java (99%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/ProxyWithDynamicTransportTest.java (98%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/RequestReaderTest.java (98%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/RoundRobinConnectionPoolTest.java (99%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/ServerTimeoutsTest.java (98%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/Transport.java (95%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/TransportProvider.java (97%)
rename {tests/test-http-client-transport/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-http-client-transport/src/test/java/org/eclipse/jetty/ee9}/http/client/TransportScenario.java (99%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-http-client-transport/src/test/resources/jetty-logging.properties (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-http-client-transport/src/test/resources/keystore.p12 (100%)
rename {tests/test-webapps => jetty-ee9/jetty-ee9-tests}/test-http2-webapp/pom.xml (86%)
rename {tests/test-webapps => jetty-ee9/jetty-ee9-tests}/test-http2-webapp/src/main/java/org/eclipse/jetty/test/webapp/HTTP1Servlet.java (100%)
rename {tests/test-webapps => jetty-ee9/jetty-ee9-tests}/test-http2-webapp/src/main/java/org/eclipse/jetty/test/webapp/HTTP2Servlet.java (100%)
rename {tests/test-webapps => jetty-ee9/jetty-ee9-tests}/test-http2-webapp/src/main/webapp/WEB-INF/web.xml (70%)
rename {tests/test-webapps => jetty-ee9/jetty-ee9-tests}/test-http2-webapp/src/test/java/org/eclipse/jetty/test/webapp/HTTP2FromWebAppIT.java (98%)
rename {tests/test-webapps => jetty-ee9/jetty-ee9-tests}/test-http2-webapp/src/test/resources/jetty-logging.properties (100%)
rename {tests/test-webapps => jetty-ee9/jetty-ee9-tests}/test-http2-webapp/src/test/resources/keystore.p12 (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/pom.xml (83%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/AliasCheckerSymlinkTest.java (97%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/AllowedResourceAliasCheckerTest.java (97%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/AnnotatedAsyncListenerTest.java (87%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/CustomRequestLogTest.java (98%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/DefaultHandlerTest.java (95%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/DeploymentErrorInitializer.java (97%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/DeploymentErrorTest.java (96%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/DigestPostTest.java (96%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/FailedSelectorTest.java (98%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/GzipWithSendErrorTest.java (98%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/HttpInputIntegrationTest.java (98%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/HttpInputInterceptorTest.java (99%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/KeyStoreScannerTest.java (99%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/RecoverFailedSelectorTest.java (99%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/jsp/FakeJspServlet.java (97%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/jsp/JspAndDefaultWithAliasesTest.java (95%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/jsp/JspAndDefaultWithoutAliasesTest.java (96%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/rfcs/RFC2616BaseTest.java (99%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/rfcs/RFC2616NIOHttpTest.java (86%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/rfcs/RFC2616NIOHttpsTest.java (86%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/support/EchoHandler.java (97%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/support/StringUtil.java (99%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/support/XmlBasedJettyServer.java (99%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/support/rawhttp/HttpRequestTesterTest.java (97%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/support/rawhttp/HttpResponseTesterTest.java (99%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/support/rawhttp/HttpSocket.java (93%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/support/rawhttp/HttpSocketImpl.java (94%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/support/rawhttp/HttpTesting.java (99%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/support/rawhttp/HttpsSocketImpl.java (97%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/websocket/JakartaSimpleEchoSocket.java (97%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/websocket/JakartaWebSocketTest.java (94%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/websocket/JettySimpleEchoSocket.java (82%)
rename {tests/test-integration/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-integration/src/test/java/org/eclipse/jetty/ee9}/test/websocket/JettyWebSocketTest.java (88%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/DefaultHandler.xml (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/NIOHttp.xml (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/NIOHttps.xml (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/RFC2616Base.xml (98%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/RFC2616_Filters.xml (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/RFC2616_Redirects.xml (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/add-jetty-test-webapp.xml (91%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/badKeystore (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/basic-server.xml (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/deploy.xml (94%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/docroots/default/R1.txt (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/docroots/default/R2.txt (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/docroots/default/R3.txt (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/docroots/default/alpha.txt (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/docroots/default/index.html (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/docroots/default/quotes.txt (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/docroots/deployerror/badapp-unavailable-false.xml (90%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/docroots/deployerror/badapp.xml (89%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/docroots/deployerror/badapp/WEB-INF/classes/META-INF/services/jakarta.servlet.ServletContainerInitializer (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/docroots/deployerror/badapp/WEB-INF/web.xml (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/docroots/jsp/dump.jsp (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/docroots/virtualhost/R1.txt (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/docroots/virtualhost/R2.txt (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/docroots/virtualhost/R3.txt (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/docroots/virtualhost/index.html (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/file (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/jetty-logging.properties (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/keystore.p12 (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/logback.xml (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/login-service.xml (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/message.txt (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/newKeystore (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/oldKeystore (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/realm.properties (89%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/sibling/file (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/ssl.xml (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/webapp-contexts/RFC2616/rfc2616-webapp.xml (92%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/webdefault.xml (97%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/webroot/WEB-INF/web.xml (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/webroot/documents/file (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/webroot/file (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/webroot/index.html (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-integration/src/test/resources/zeros.gz.gz (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-jmx/jmx-webapp-it/pom.xml (86%)
rename {tests/test-jmx/jmx-webapp-it/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-jmx/jmx-webapp-it/src/test/java/org/eclipse/jetty/ee9}/test/jmx/JmxIT.java (97%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-jmx/jmx-webapp/pom.xml (89%)
rename {tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/ee9}/test/jmx/CommonComponent.java (97%)
rename {tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/ee9}/test/jmx/Echoer.java (96%)
rename {tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/ee9}/test/jmx/MyContainerInitializer.java (97%)
rename {tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/ee9}/test/jmx/PingServlet.java (97%)
rename {tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/ee9}/test/jmx/Pinger.java (95%)
rename {tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/ee9}/test/jmx/jmx/EchoerMBean.java (95%)
rename {tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/ee9}/test/jmx/jmx/PingerMBean.java (93%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-jmx/jmx-webapp/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-jmx/jmx-webapp/src/main/webapp/WEB-INF/web.xml (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-jmx/jmx-webapp/src/main/webapp/index.html (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-jmx/pom.xml (67%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-jndi/pom.xml (85%)
rename {tests/test-jndi/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-jndi/src/test/java/org/eclipse/jetty/ee9}/jndi/factories/TestMailSessionReference.java (96%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-loginservice/pom.xml (80%)
rename {tests/test-loginservice/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-loginservice/src/test/java/org/eclipse/jetty/ee9/loginservice}/DataSourceLoginServiceTest.java (96%)
rename {tests/test-loginservice/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-loginservice/src/test/java/org/eclipse/jetty/ee9/loginservice}/DatabaseLoginServiceTestServer.java (94%)
rename {tests/test-loginservice/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-loginservice/src/test/java/org/eclipse/jetty/ee9/loginservice}/JdbcLoginServiceTest.java (98%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-loginservice/src/test/resources/createdb.sql (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-loginservice/src/test/resources/droptables.sql (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-loginservice/src/test/resources/jdbcrealm.properties (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-loginservice/src/test/resources/jetty-logging.properties (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-quickstart/pom.xml (77%)
rename {tests/test-quickstart/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-quickstart/src/test/java/org/eclipse/jetty/ee9}/quickstart/AttributeNormalizerTest.java (99%)
rename {tests/test-quickstart/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-quickstart/src/test/java/org/eclipse/jetty/ee9}/quickstart/AttributeNormalizerToCanonicalUriTest.java (98%)
rename {tests/test-quickstart/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-quickstart/src/test/java/org/eclipse/jetty/ee9}/quickstart/EnvUtils.java (98%)
rename {tests/test-quickstart/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-quickstart/src/test/java/org/eclipse/jetty/ee9}/quickstart/PreconfigureJNDIWar.java (97%)
rename {tests/test-quickstart/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-quickstart/src/test/java/org/eclipse/jetty/ee9}/quickstart/PreconfigureSpecWar.java (98%)
rename {tests/test-quickstart/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-quickstart/src/test/java/org/eclipse/jetty/ee9}/quickstart/PreconfigureStandardTestWar.java (97%)
rename {tests/test-quickstart/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-quickstart/src/test/java/org/eclipse/jetty/ee9}/quickstart/QuickStartJNDIWar.java (95%)
rename {tests/test-quickstart/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-quickstart/src/test/java/org/eclipse/jetty/ee9}/quickstart/QuickStartSpecWar.java (95%)
rename {tests/test-quickstart/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-quickstart/src/test/java/org/eclipse/jetty/ee9}/quickstart/QuickStartStandardTestWar.java (95%)
rename {tests/test-quickstart/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-quickstart/src/test/java/org/eclipse/jetty/ee9}/quickstart/QuickStartTest.java (95%)
rename {tests/test-quickstart/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-quickstart/src/test/java/org/eclipse/jetty/ee9}/quickstart/Quickstart.java (89%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-quickstart/src/test/resources/jetty-logging.properties (100%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-quickstart/src/test/resources/realm.properties (89%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-quickstart/src/test/resources/test-jndi.xml (95%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-quickstart/src/test/resources/test-spec.xml (93%)
rename {tests => jetty-ee9/jetty-ee9-tests}/test-quickstart/src/test/resources/test.xml (96%)
rename {tests/test-webapps => jetty-ee9/jetty-ee9-tests}/test-websocket-client-provided-webapp/pom.xml (77%)
rename {tests/test-webapps/test-websocket-client-provided-webapp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-websocket-client-provided-webapp/src/main/java/org/eclipse/jetty/ee9}/tests/webapp/websocket/EchoEndpoint.java (93%)
rename {tests/test-webapps/test-websocket-client-provided-webapp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-websocket-client-provided-webapp/src/main/java/org/eclipse/jetty/ee9}/tests/webapp/websocket/WebSocketClientServlet.java (88%)
rename {tests/test-webapps => jetty-ee9/jetty-ee9-tests}/test-websocket-client-provided-webapp/src/main/resources/jetty-websocket-httpclient.xml (100%)
rename {tests/test-webapps => jetty-ee9/jetty-ee9-tests}/test-websocket-client-provided-webapp/src/main/webapp/WEB-INF/web.xml (100%)
rename {tests/test-webapps => jetty-ee9/jetty-ee9-tests}/test-websocket-client-webapp/pom.xml (76%)
rename {tests/test-webapps/test-websocket-client-webapp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-websocket-client-webapp/src/main/java/org/eclipse/jetty/ee9}/tests/webapp/websocket/EchoEndpoint.java (93%)
rename {tests/test-webapps/test-websocket-client-webapp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-websocket-client-webapp/src/main/java/org/eclipse/jetty/ee9}/tests/webapp/websocket/WebSocketClientServlet.java (88%)
rename {tests/test-webapps => jetty-ee9/jetty-ee9-tests}/test-websocket-client-webapp/src/main/webapp/WEB-INF/web.xml (100%)
rename {tests/test-webapps => jetty-ee9/jetty-ee9-tests}/test-websocket-webapp/pom.xml (78%)
rename {tests/test-webapps/test-websocket-webapp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-websocket-webapp/src/main/java/org/eclipse/jetty/ee9}/tests/webapp/websocket/EchoEndpoint.java (95%)
rename {tests/test-webapps/test-websocket-webapp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-websocket-webapp/src/main/java/org/eclipse/jetty/ee9}/tests/webapp/websocket/StringSequence.java (95%)
rename {tests/test-webapps/test-websocket-webapp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-tests/test-websocket-webapp/src/main/java/org/eclipse/jetty/ee9}/tests/webapp/websocket/StringSequenceDecoder.java (95%)
rename {tests/test-webapps => jetty-ee9/jetty-ee9-tests}/test-websocket-webapp/src/main/webapp/WEB-INF/web.xml (100%)
rename {tests/test-webapps => jetty-ee9/jetty-ee9-tests}/test-websocket-webapp/src/main/webapp/index.jsp (100%)
rename {jetty-webapp => jetty-ee9/jetty-ee9-webapp}/pom.xml (79%)
create mode 100644 jetty-ee9/jetty-ee9-webapp/src/main/java/module-info.java
rename {jetty-webapp/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9}/webapp/package-info.java (94%)
create mode 100644 jetty-ee9/jetty-ee9-webapp/src/main/resources/META-INF/services/org.eclipse.jetty.ee9.webapp.Configuration
rename {jetty-webapp => jetty-ee9/jetty-ee9-webapp}/src/test/resources/org/acme/resource.txt (100%)
rename {jetty-webapp => jetty-ee9/jetty-ee9-webapp}/src/test/webapp/WEB-INF/classes/org/acme/resource.txt (100%)
rename {jetty-webapp => jetty-ee9/jetty-ee9-webapp}/src/test/webapp/WEB-INF/test.xml (100%)
rename {jetty-webapp => jetty-ee9/jetty-ee9-webapp}/src/test/webapp/test.xml (100%)
rename {jetty-websocket/websocket-jakarta-client => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-client}/pom.xml (88%)
rename {jetty-websocket/websocket-jakarta-client => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-client}/src/main/java/module-info.java (68%)
rename {jetty-websocket/websocket-jakarta-client => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-client}/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer (100%)
rename {jetty-websocket/websocket-jakarta-client => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-client}/src/test/resources/jetty-logging.properties (100%)
rename {jetty-websocket/websocket-jakarta-client => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-client}/src/test/resources/jetty-websocket-httpclient.xml (100%)
rename {jetty-websocket/websocket-jakarta-common => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common}/pom.xml (87%)
rename {jetty-websocket/websocket-jakarta-common => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common}/src/main/java/module-info.java (68%)
rename {jetty-websocket/websocket-jakarta-common/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9}/websocket/jakarta/common/SessionTracker.java (98%)
rename {jetty-websocket/websocket-jakarta-common/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9}/websocket/jakarta/common/UpgradeRequest.java (95%)
rename {jetty-websocket/websocket-jakarta-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/common/DummyContainer.java (98%)
rename {jetty-websocket/websocket-jakarta-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/common/JakartaWebSocketFrameHandlerOnMessageTextStreamTest.java (95%)
rename {jetty-websocket/websocket-jakarta-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/common/coders/tests/BadDualDecoder.java (97%)
rename {jetty-websocket/websocket-jakarta-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/common/coders/tests/BadDualEncoder.java (95%)
rename {jetty-websocket/websocket-jakarta-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/common/coders/tests/ExtDecoder.java (91%)
rename {jetty-websocket/websocket-jakarta-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/common/coders/tests/Fruit.java (90%)
rename {jetty-websocket/websocket-jakarta-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/common/coders/tests/FruitBinaryEncoder.java (96%)
rename {jetty-websocket/websocket-jakarta-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/common/coders/tests/FruitDecoder.java (96%)
rename {jetty-websocket/websocket-jakarta-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/common/coders/tests/FruitTextEncoder.java (93%)
rename {jetty-websocket/websocket-jakarta-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/common/endpoints/DummyEndpoint.java (92%)
rename {jetty-websocket/websocket-jakarta-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/common/handlers/BaseMessageHandler.java (92%)
rename {jetty-websocket/websocket-jakarta-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/common/handlers/ComboMessageHandler.java (94%)
rename {jetty-websocket/websocket-jakarta-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/common/handlers/ExtendedMessageHandler.java (93%)
rename {jetty-websocket/websocket-jakarta-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/common/handlers/LongMessageHandler.java (92%)
rename {jetty-websocket/websocket-jakarta-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/common/sockets/TrackingSocket.java (95%)
rename {jetty-websocket/websocket-jakarta-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/common/util/InvokerUtilsTest.java (99%)
rename {jetty-websocket/websocket-jakarta-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/common/util/NameParamIdentifier.java (96%)
rename {jetty-websocket/websocket-jakarta-common => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common}/src/test/resources/jetty-logging.properties (100%)
rename {jetty-websocket/websocket-jakarta-common => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common}/src/test/resources/quotes-ben.txt (100%)
rename {jetty-websocket/websocket-jakarta-common => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common}/src/test/resources/quotes-twain.txt (100%)
rename {jetty-websocket/websocket-jakarta-server => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server}/pom.xml (75%)
rename {jetty-websocket/websocket-jakarta-server => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server}/src/main/java/module-info.java (52%)
rename {jetty-websocket/websocket-jakarta-server => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server}/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer (100%)
rename {jetty-websocket/websocket-jakarta-server => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server}/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration (100%)
rename {jetty-websocket/websocket-jakarta-server => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server}/src/test/resources/jetty-logging.properties (100%)
rename {jetty-websocket/websocket-jakarta-server => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server}/src/test/resources/jsr-browser-debug-tool/index.html (100%)
rename {jetty-websocket/websocket-jakarta-server => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server}/src/test/resources/jsr-browser-debug-tool/main.css (100%)
rename {jetty-websocket/websocket-jakarta-server => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server}/src/test/resources/jsr-browser-debug-tool/websocket.js (100%)
create mode 100644 jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/fuzzingclient.json
create mode 100644 jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/fuzzingserver.json
rename {jetty-websocket/websocket-jakarta-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests}/pom.xml (84%)
rename {jetty-websocket/websocket-jakarta-tests/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/DummyEndpoint.java (93%)
rename {jetty-websocket/websocket-jakarta-tests/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/EchoSocket.java (95%)
rename {jetty-websocket/websocket-jakarta-tests/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/EventSocket.java (98%)
rename {jetty-websocket/websocket-jakarta-tests/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/WSURI.java (98%)
rename {jetty-websocket/websocket-jakarta-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests}/src/test/java/com/acme/websocket/BasicEchoEndpoint.java (100%)
rename {jetty-websocket/websocket-jakarta-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests}/src/test/java/com/acme/websocket/BasicEchoEndpointConfigContextListener.java (100%)
rename {jetty-websocket/websocket-jakarta-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests}/src/test/java/com/acme/websocket/IdleTimeoutContextListener.java (100%)
rename {jetty-websocket/websocket-jakarta-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests}/src/test/java/com/acme/websocket/IdleTimeoutOnOpenEndpoint.java (100%)
rename {jetty-websocket/websocket-jakarta-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests}/src/test/java/com/acme/websocket/IdleTimeoutOnOpenSocket.java (100%)
rename {jetty-websocket/websocket-jakarta-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests}/src/test/java/com/acme/websocket/LargeEchoContextListener.java (100%)
rename {jetty-websocket/websocket-jakarta-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests}/src/test/java/com/acme/websocket/LargeEchoDefaultSocket.java (100%)
rename {jetty-websocket/websocket-jakarta-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests}/src/test/java/com/acme/websocket/OnOpenIdleTimeoutEndpoint.java (100%)
rename {jetty-websocket/websocket-jakarta-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests}/src/test/java/com/acme/websocket/PongContextListener.java (100%)
rename {jetty-websocket/websocket-jakarta-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests}/src/test/java/com/acme/websocket/PongMessageEndpoint.java (100%)
rename {jetty-websocket/websocket-jakarta-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests}/src/test/java/com/acme/websocket/PongSocket.java (100%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/CloseInOnOpenTest.java (88%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/GracefulCloseTest.java (93%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/ProgrammaticWebSocketUpgradeTest.java (92%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/ServerConfigTest.java (95%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/UpgradeRequestResponseTest.java (91%)
rename {tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/jakarta => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/autobahn}/JakartaAutobahnClient.java (84%)
rename {tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/jakarta => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/autobahn}/JakartaAutobahnServer.java (70%)
rename {tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/jakarta => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/autobahn}/JakartaAutobahnSocket.java (94%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/client/ConfiguratorTest.java (95%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/coders/BadDualDecoder.java (98%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/coders/BadDualEncoder.java (95%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/coders/ExtDecoder.java (92%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/coders/Fruit.java (91%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/coders/FruitBinaryEncoder.java (96%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/coders/FruitDecoder.java (96%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/coders/FruitTextEncoder.java (94%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/coders/Quotes.java (94%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/coders/QuotesDecoder.java (97%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/coders/QuotesEncoder.java (95%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/coders/QuotesUtil.java (97%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/handlers/BaseMessageHandler.java (92%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/handlers/ComboMessageHandler.java (94%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/handlers/ExtendedMessageHandler.java (93%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/handlers/LongMessageHandler.java (92%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/quotes/Quotes.java (94%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/quotes/QuotesDecoder.java (96%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/quotes/QuotesEncoder.java (95%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/quotes/QuotesUtil.java (97%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/server/BasicEchoEndpointConfigContextListener.java (92%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/server/ConfiguratorTest.java (98%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/server/IdleTimeoutContextListener.java (91%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/server/JakartaWebSocketFrameHandlerOnMessageTextStreamTest.java (93%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/server/LargeEchoContextListener.java (95%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/server/PongContextListener.java (93%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/server/PongSocket.java (96%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/server/sockets/BasicEchoSocket.java (93%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/server/sockets/ByteBufferSocket.java (95%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/server/sockets/IdleTimeoutOnOpenEndpoint.java (94%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/server/sockets/IdleTimeoutOnOpenSocket.java (94%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/server/sockets/TrackingSocket.java (95%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/server/sockets/binary/ByteBufferSocket.java (94%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/server/sockets/echo/BasicEchoEndpoint.java (94%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/server/sockets/echo/BasicEchoSocket.java (92%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/server/sockets/echo/LargeEchoDefaultSocket.java (93%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/server/sockets/idletimeout/OnOpenIdleTimeoutEndpoint.java (93%)
rename {jetty-websocket/websocket-jakarta-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/jakarta/tests/server/sockets/pong/PongMessageEndpoint.java (95%)
rename {jetty-websocket/websocket-jakarta-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests}/src/test/resources/jetty-logging.properties (100%)
rename {jetty-websocket/websocket-jakarta-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests}/src/test/resources/jetty-websocket-httpclient.xml (100%)
rename {jetty-websocket/websocket-jakarta-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests}/src/test/resources/keystore.p12 (100%)
rename {jetty-websocket/websocket-jakarta-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests}/src/test/resources/quotes-ben.txt (100%)
rename {jetty-websocket/websocket-jakarta-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests}/src/test/resources/quotes-twain.txt (100%)
rename {jetty-websocket/websocket-jakarta-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests}/src/test/resources/simple/jetty-websocket-httpclient.xml (100%)
rename {jetty-websocket/websocket-jakarta-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests}/src/test/webapp/index.html (100%)
rename {jetty-websocket/websocket-jetty-api => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api}/pom.xml (60%)
create mode 100644 jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/module-info.java
rename {jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9}/websocket/api/UpgradeRequest.java (99%)
rename {jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9}/websocket/api/annotations/package-info.java (91%)
rename {jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9}/websocket/api/exceptions/package-info.java (91%)
rename {jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9}/websocket/api/package-info.java (93%)
rename {jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9}/websocket/api/util/WSURI.java (98%)
rename {jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9}/websocket/api/util/package-info.java (92%)
rename {jetty-websocket/websocket-jetty-client => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client}/pom.xml (73%)
rename {jetty-websocket/websocket-jetty-client => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client}/src/main/java/module-info.java (71%)
rename {jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client/src/main/java/org/eclipse/jetty/ee9}/websocket/client/package-info.java (92%)
create mode 100644 jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration
create mode 100644 jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client/src/test/resources/jetty-logging.properties
rename {jetty-websocket/websocket-jetty-common => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common}/pom.xml (76%)
rename {jetty-websocket/websocket-jetty-common => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common}/src/main/java/module-info.java (68%)
rename {jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee9}/websocket/common/SessionTracker.java (92%)
rename {jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee9}/websocket/common/package-info.java (95%)
rename {jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee9}/websocket/common/DummyContainer.java (90%)
rename {jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee9}/websocket/common/invoke/InvokerUtilsTest.java (99%)
rename {jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee9}/websocket/common/invoke/NameParamIdentifier.java (96%)
rename {jetty-websocket/websocket-jetty-common => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common}/src/test/resources/jetty-logging.properties (100%)
rename {jetty-websocket/websocket-jetty-server => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server}/pom.xml (67%)
rename {jetty-websocket/websocket-jetty-server => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server}/src/main/java/module-info.java (56%)
rename {jetty-websocket/websocket-jetty-server => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server}/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer (100%)
rename {jetty-websocket/websocket-jetty-server => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server}/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration (100%)
rename {jetty-websocket/websocket-jetty-server => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server}/src/test/resources/browser-debug-tool/index.html (100%)
rename {jetty-websocket/websocket-jetty-server => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server}/src/test/resources/browser-debug-tool/main.css (100%)
rename {jetty-websocket/websocket-jetty-server => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server}/src/test/resources/browser-debug-tool/websocket.js (100%)
create mode 100644 jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/fuzzingclient.json
create mode 100644 jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/fuzzingserver.json
rename {jetty-websocket/websocket-jetty-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests}/pom.xml (84%)
rename {jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/tests/CloseInOnOpenTest.java (84%)
rename {jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/tests/EchoSocket.java (90%)
rename {tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests}/EventSocket.java (85%)
rename {jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/tests/GracefulCloseTest.java (91%)
rename {jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/tests/ProgrammaticWebSocketUpgradeTest.java (87%)
rename {jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/tests/UpgradeRequestResponseTest.java (91%)
rename {tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/autobahn}/JettyAutobahnClient.java (74%)
rename {tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/autobahn}/JettyAutobahnServer.java (70%)
rename {tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/autobahn}/JettyAutobahnSocket.java (81%)
rename {jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9}/websocket/tests/server/ServerConfigTest.java (91%)
rename {jetty-websocket/websocket-jetty-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests}/src/test/resources/jetty-logging.properties (100%)
rename {jetty-websocket/websocket-jetty-tests => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests}/src/test/resources/keystore.p12 (100%)
rename {jetty-websocket/websocket-servlet => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-servlet}/pom.xml (75%)
rename {jetty-websocket/websocket-servlet => jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-servlet}/src/main/java/module-info.java (80%)
create mode 100644 jetty-ee9/jetty-ee9-websocket/pom.xml
create mode 100644 jetty-ee9/pom.xml
delete mode 100644 jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpChannelOverFCGI.java
delete mode 100644 jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpTransportOverFCGI.java
delete mode 100644 jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/EmptyServerHandler.java
delete mode 100644 jetty-hazelcast/src/test/java/org/eclipse/jetty/hazelcast/session/TestHazelcastSessions.java
delete mode 100644 jetty-home/src/main/resources/modules/jolokia/jolokia-realm.properties
delete mode 100644 jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestEndpointMultiplePublishProblem.java
delete mode 100644 jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/EmptyHttpServlet.java
delete mode 100644 jetty-http2/http2-client/src/test/resources/jetty-logging.properties
delete mode 100644 jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/AbstractTest.java
delete mode 100644 jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/EmptyServerHandler.java
delete mode 100644 jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/PriorKnowledgeHTTP2OverTLSTest.java
delete mode 100644 jetty-http2/http2-http-client-transport/src/test/resources/jetty-logging.properties
delete mode 100644 jetty-http2/http2-http-client-transport/src/test/resources/keystore.p12
delete mode 100644 jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java
delete mode 100644 jetty-http3/http3-http-client-transport/src/main/java/org/eclipse/jetty/http3/client/http/internal/HttpChannelOverHTTP3.java
delete mode 100644 jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/HttpTransportOverHTTP3.java
delete mode 100644 jetty-infinispan/infinispan-embedded-query/src/test/java/org/eclipse/jetty/server/session/infinispan/EmbeddedQueryManagerTest.java
delete mode 100644 jetty-infinispan/infinispan-remote-query/src/test/java/org/eclipse/jetty/server/session/infinispan/RemoteQueryManagerTest.java
delete mode 100644 jetty-infinispan/infinispan-remote-query/src/test/resources/config.yaml
delete mode 100644 jetty-infinispan/infinispan-remote-query/src/test/resources/simplelogger.properties
rename {jetty-gcloud => jetty-integrations/jetty-gcloud}/jetty-gcloud-session-manager/pom.xml (97%)
rename {jetty-hazelcast => jetty-integrations/jetty-hazelcast}/src/main/java/module-info.java (93%)
rename {jetty-infinispan => jetty-integrations/jetty-infinispan}/infinispan-common/pom.xml (94%)
rename {jetty-infinispan => jetty-integrations/jetty-infinispan}/infinispan-embedded-query/pom.xml (97%)
rename {jetty-infinispan => jetty-integrations/jetty-infinispan}/infinispan-embedded-query/src/main/assembly/config.xml (100%)
rename {jetty-infinispan => jetty-integrations/jetty-infinispan}/infinispan-embedded/pom.xml (97%)
rename {jetty-infinispan => jetty-integrations/jetty-infinispan}/infinispan-embedded/src/main/assembly/config.xml (100%)
rename {jetty-infinispan => jetty-integrations/jetty-infinispan}/infinispan-remote-query/pom.xml (98%)
rename {jetty-infinispan => jetty-integrations/jetty-infinispan}/infinispan-remote-query/src/main/assembly/config.xml (100%)
rename {jetty-infinispan => jetty-integrations/jetty-infinispan}/infinispan-remote/pom.xml (97%)
rename {jetty-infinispan => jetty-integrations/jetty-infinispan}/infinispan-remote/src/main/assembly/config.xml (100%)
create mode 100644 jetty-integrations/jetty-memcached/jetty-memcached-sessions/pom.xml
rename {jetty-memcached => jetty-integrations/jetty-memcached}/jetty-memcached-sessions/src/main/java/module-info.java (93%)
rename {jetty-nosql => jetty-integrations/jetty-nosql}/src/main/java/module-info.java (93%)
rename {jetty-nosql => jetty-integrations/jetty-nosql}/src/main/java/org/eclipse/jetty/nosql/mongodb/package-info.java (100%)
rename {jetty-nosql => jetty-integrations/jetty-nosql}/src/main/java/org/eclipse/jetty/nosql/package-info.java (100%)
create mode 100644 jetty-integrations/pom.xml
delete mode 100644 jetty-maven-plugin/src/it/exclude-javax-annotation/invoker.properties
delete mode 100644 jetty-maven-plugin/src/it/exclude-javax-annotation/pom.xml
delete mode 100644 jetty-maven-plugin/src/it/exclude-javax-annotation/postbuild.groovy
delete mode 100644 jetty-maven-plugin/src/it/exclude-javax-annotation/src/main/java/org/github/unb/TestServlet.java
delete mode 100644 jetty-maven-plugin/src/it/jetty-start-war-mojo-it/src/config/jetty.xml
delete mode 100644 jetty-memcached/jetty-memcached-sessions/pom.xml
delete mode 100644 jetty-memcached/jetty-memcached-sessions/src/test/java/org/eclipse/jetty/memcached/session/TestMemcachedSessions.java
delete mode 100644 jetty-plus/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration
delete mode 100644 jetty-rewrite/src/main/config/modules/rewrite/rewrite-msie.xml
delete mode 100644 jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/MsieRule.java
delete mode 100644 jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/MsieSslRule.java
delete mode 100644 jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RedirectUtil.java
delete mode 100644 jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ValidUrlRule.java
delete mode 100644 jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/AbstractRuleTestCase.java
delete mode 100644 jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/MsieRuleTest.java
delete mode 100644 jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/MsieSslRuleTest.java
delete mode 100644 jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ValidUrlRuleTest.java
delete mode 100644 jetty-security/src/test/java/org/eclipse/jetty/security/SessionAuthenticationTest.java
delete mode 100644 jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java
delete mode 100644 jetty-server/src/main/java/org/eclipse/jetty/server/RequestLogCollection.java
delete mode 100644 jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnectionStatistics.java
delete mode 100644 jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java
delete mode 100644 jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHttpInputInterceptor.java
delete mode 100644 jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java
delete mode 100644 jetty-server/src/test/java/org/eclipse/jetty/server/AsyncStressTest.java
delete mode 100644 jetty-server/src/test/java/org/eclipse/jetty/server/CharEncodingContextHandler.java
delete mode 100644 jetty-server/src/test/java/org/eclipse/jetty/server/StressTest.java
delete mode 100644 jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionCookieTest.java
delete mode 100644 jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionHandlerTest.java
delete mode 100644 jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultHandlerTest.java
delete mode 100644 jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ConcatServlet.java
delete mode 100644 jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DataRateLimitedServlet.java
delete mode 100644 jetty-servlets/src/main/java/org/eclipse/jetty/servlets/PutFilter.java
delete mode 100644 jetty-servlets/src/main/java/org/eclipse/jetty/servlets/WelcomeFilter.java
delete mode 100644 jetty-servlets/src/test/java/org/eclipse/jetty/servlets/ConcatServletTest.java
delete mode 100644 jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DataRateLimitedServletTest.java
delete mode 100644 jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PutFilterTest.java
delete mode 100644 jetty-servlets/src/test/java/org/eclipse/jetty/servlets/WelcomeFilterTest.java
delete mode 100644 jetty-unixsocket/jetty-unixsocket-client/pom.xml
delete mode 100644 jetty-unixsocket/jetty-unixsocket-client/src/main/java/module-info.java
delete mode 100644 jetty-unixsocket/jetty-unixsocket-client/src/main/java/org/eclipse/jetty/unixsocket/client/HttpClientTransportOverUnixSockets.java
delete mode 100644 jetty-unixsocket/jetty-unixsocket-client/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketClient.java
delete mode 100644 jetty-unixsocket/jetty-unixsocket-client/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketTest.java
delete mode 100644 jetty-unixsocket/jetty-unixsocket-client/src/test/resources/jetty-logging.properties
delete mode 100644 jetty-unixsocket/jetty-unixsocket-common/pom.xml
delete mode 100644 jetty-unixsocket/jetty-unixsocket-common/src/main/java/module-info.java
delete mode 100644 jetty-unixsocket/jetty-unixsocket-common/src/main/java/org/eclipse/jetty/unixsocket/common/UnixSocketEndPoint.java
delete mode 100644 jetty-unixsocket/jetty-unixsocket-common/src/test/java/org/eclipse/jetty/unixsocket/common/JnrTest.java
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/pom.xml
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/src/main/assembly/config.xml
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/src/main/config-template/etc/jetty-unixsocket-forwarded.xml
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/src/main/config-template/etc/jetty-unixsocket-http.xml
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/src/main/config-template/etc/jetty-unixsocket-http2c.xml
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/src/main/config-template/etc/jetty-unixsocket-proxy-protocol.xml
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/src/main/config-template/etc/jetty-unixsocket-secure.xml
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/src/main/config-template/etc/jetty-unixsocket.xml
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/src/main/config-template/modules/unixsocket-forwarded.mod
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/src/main/config-template/modules/unixsocket-http.mod
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/src/main/config-template/modules/unixsocket-http2c.mod
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/src/main/config-template/modules/unixsocket-prefix.mod
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/src/main/config-template/modules/unixsocket-proxy-protocol.mod
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/src/main/config-template/modules/unixsocket-secure.mod
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/src/main/config-template/modules/unixsocket-suffix.mod
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/src/main/java/module-info.java
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/src/main/java/org/eclipse/jetty/unixsocket/server/UnixSocketConnector.java
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketProxyServer.java
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketServer.java
delete mode 100644 jetty-unixsocket/jetty-unixsocket-server/src/test/resources/jetty-logging.properties
delete mode 100644 jetty-webapp/src/main/java/module-info.java
delete mode 100644 jetty-webapp/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration
delete mode 100644 jetty-websocket/websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/UpgradeHttpServletRequest.java
delete mode 100644 jetty-websocket/websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/UpgradeHttpServletResponse.java
delete mode 100644 jetty-websocket/websocket-core-tests/src/test/resources/jetty-logging.properties
delete mode 100644 jetty-websocket/websocket-jetty-api/src/main/java/module-info.java
delete mode 100644 jetty-websocket/websocket-jetty-client/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration
delete mode 100644 jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/EventSocket.java
rename tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/{server => }/session/ClusteredOrphanedSessionTest.java (68%)
rename tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/{server => }/session/ClusteredOrphanedSessionTest.java (97%)
rename tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/{server => }/session/ClusteredSerializedSessionScavengingTest.java (93%)
rename tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/{server => }/session/ClusteredSessionScavengingTest.java (97%)
rename tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/{server => }/session/InfinispanFileSessionDataStoreTest.java (97%)
rename tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/{server => }/session/InfinispanSessionDataStoreTest.java (98%)
rename tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/{server => }/session/InfinispanTestSupport.java (99%)
rename tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/{server => }/session/LoggingUtil.java (96%)
rename tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/{server => }/session/SerializedInfinispanSessionDataStoreTest.java (98%)
rename tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/{server => }/session/remote/RemoteClusteredInvalidationSessionTest.java (87%)
rename tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/{server => }/session/remote/RemoteClusteredSessionScavengingTest.java (87%)
rename tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/{server => }/session/remote/RemoteInfinispanSessionDataStoreTest.java (91%)
rename tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/{server => }/session/remote/RemoteInfinispanTestSupport.java (98%)
rename tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/{server => }/session/ClusteredInvalidationSessionTest.java (96%)
rename tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/{server => }/session/ClusteredOrphanedSessionTest.java (96%)
rename tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/{server => }/session/ClusteredSessionMigrationTest.java (93%)
rename tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/{server => }/session/ClusteredSessionScavengingTest.java (96%)
rename tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/{server => }/session/JDBCSessionDataStoreTest.java (98%)
rename tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/{server => }/session/JdbcTestHelper.java (99%)
rename tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/{server => }/session/ReloadedSessionMissingClassTest.java (94%)
rename tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/{server => }/session/SessionTableSchemaTest.java (99%)
rename tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/{server => }/session/WebAppObjectInSessionTest.java (97%)
delete mode 100644 tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestHttpChannelCompleteListener.java
delete mode 100644 tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestHttpSessionListenerWithWebappClasses.java
delete mode 100644 tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestSessionHandler.java
rename tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/{server => }/session/AbstractClusteredInvalidationSessionTest.java (83%)
rename tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/{server => }/session/AbstractClusteredOrphanedSessionTest.java (95%)
rename tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/{server => }/session/AbstractClusteredSessionScavengingTest.java (93%)
rename tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/{server/session/AbstractTestBase.java => session/AbstractSessionTestBase.java} (89%)
rename tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/{server => }/session/AbstractWebAppObjectInSessionTest.java (88%)
rename tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/{server => }/session/Foo.java (94%)
rename tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/{server => }/session/FooInvocationHandler.java (96%)
rename tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/{server/session/TestServer.java => session/SessionTestSupport.java} (93%)
rename tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/{server => }/session/TestFoo.java (96%)
rename tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/{server => }/session/TestHttpSessionListener.java (98%)
rename tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/{server => }/session/TestSessionDataStore.java (98%)
rename tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/{server => }/session/TestSessionDataStoreFactory.java (79%)
create mode 100644 tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/session/TestSessionHandler.java
rename tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/{server => }/session/WebAppObjectInSessionServlet.java (98%)
delete mode 100644 tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DefaultSessionCacheTest.java
delete mode 100644 tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DirtyAttributeTest.java
delete mode 100644 tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/ImmortalSessionTest.java
delete mode 100644 tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SaveOptimizeTest.java
delete mode 100644 tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionEvictionFailureTest.java
delete mode 100644 tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionListenerTest.java
rename tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/{server => }/session/AsyncTest.java (82%)
rename tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/{server => }/session/ClientCrossContextSessionTest.java (93%)
rename tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/{server => }/session/ConcurrencyTest.java (98%)
rename tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/{server => }/session/CreationTest.java (82%)
rename tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/{server => }/session/DeleteUnloadableSessionTest.java (87%)
rename tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/{server => }/session/DuplicateCookieTest.java (84%)
rename tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/{server => }/session/IdleSessionTest.java (94%)
rename tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/{server => }/session/ModifyMaxInactiveIntervalTest.java (92%)
rename tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/{server => }/session/NonClusteredSessionScavengingTest.java (82%)
rename tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/{server => }/session/RedirectSessionTest.java (94%)
rename tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/{server => }/session/ReentrantRequestSessionTest.java (88%)
rename tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/{server => }/session/RemoveSessionTest.java (94%)
rename tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/{server => }/session/RequestDispatchedSessionTest.java (96%)
rename tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/{server => }/session/RequestScopedSessionSaveTest.java (96%)
rename tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/{server => }/session/SameContextForwardedSessionTest.java (88%)
rename tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/{server => }/session/SessionInvalidateCreateScavengeTest.java (96%)
rename tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/{server => }/session/SessionInvalidationTest.java (96%)
rename tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/{server => }/session/SessionRenewTest.java (87%)
delete mode 100644 tests/test-websocket-autobahn/pom.xml
delete mode 100644 tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/AutobahnClient.java
delete mode 100644 tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/AutobahnServer.java
delete mode 100644 tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/AutobahnTests.java
delete mode 100644 tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/core/TestMessageHandler.java
delete mode 100644 tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/core/TestWebSocketNegotiator.java
delete mode 100644 tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/jakarta/EchoSocket.java
delete mode 100644 tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/jakarta/EventSocket.java
delete mode 100644 tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/jakarta/HostConfigurator.java
delete mode 100644 tests/test-websocket-autobahn/src/test/java/org/eclipse/jetty/websocket/tests/jetty/EchoSocket.java
delete mode 100644 tests/test-websocket-autobahn/src/test/resources/simplelogger.properties
diff --git a/Jenkinsfile b/Jenkinsfile
index a07d6021278..71fefe0221a 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -1,86 +1,118 @@
#!groovy
pipeline {
- agent any
+ agent {
+ node { label 'linux' }
+ }
// save some io during the build
options { durabilityHint('PERFORMANCE_OPTIMIZED') }
stages {
- stage("Parallel Stage") {
- parallel {
- stage("Build / Test - JDK17") {
- agent { node { label 'linux' } }
+ stage("Checkout Jetty") {
+ steps {
+ container('jetty-build') {
+ dir("${env.WORKSPACE}/buildy") {
+ checkout scm
+ }
+ }
+ }
+ }
+ stage("Build & Test - JDK17") {
+ stages {
+ stage("Setup") {
steps {
container('jetty-build') {
- timeout( time: 180, unit: 'MINUTES' ) {
- mavenBuild( "jdk17", "clean install -Perrorprone", "maven3")
- // Collect up the jacoco execution results (only on main build)
- jacoco inclusionPattern: '**/org/eclipse/jetty/**/*.class',
- exclusionPattern: '' +
- // build tools
- '**/org/eclipse/jetty/ant/**' + ',**/org/eclipse/jetty/maven/**' +
- ',**/org/eclipse/jetty/jspc/**' +
- // example code / documentation
- ',**/org/eclipse/jetty/embedded/**' + ',**/org/eclipse/jetty/asyncrest/**' +
- ',**/org/eclipse/jetty/demo/**' +
- // special environments / late integrations
- ',**/org/eclipse/jetty/gcloud/**' + ',**/org/eclipse/jetty/infinispan/**' +
- ',**/org/eclipse/jetty/osgi/**' +
- ',**/org/eclipse/jetty/http/spi/**' +
- // test classes
- ',**/org/eclipse/jetty/tests/**' + ',**/org/eclipse/jetty/test/**',
- execPattern: '**/target/jacoco.exec',
- classPattern: '**/target/classes',
- sourcePattern: '**/src/main/java'
- recordIssues id: "jdk17", name: "Static Analysis jdk17", aggregatingResults: true, enabledForFailure: true, tools: [mavenConsole(), java(), checkStyle(), errorProne(), spotBugs()]
+ timeout(time: 120, unit: 'MINUTES') {
+ dir("${env.WORKSPACE}/buildy") {
+ echo "Install org.eclipse.jetty:build-resources"
+ mavenBuild("jdk17", "clean install -f build", "maven3")
+ echo "Install org.eclipse.jetty:jetty-project"
+ mavenBuild("jdk17", "-N clean install", "maven3")
+ }
}
}
}
}
-
- stage("Build / Test - JDK11") {
- agent { node { label 'linux' } }
+ stage("Module : /jetty-core/") {
steps {
- container( 'jetty-build' ) {
- timeout( time: 180, unit: 'MINUTES' ) {
- mavenBuild( "jdk11", "clean install -Dspotbugs.skip=true -Djacoco.skip=true", "maven3")
- recordIssues id: "jdk11", name: "Static Analysis jdk11", aggregatingResults: true, enabledForFailure: true, tools: [mavenConsole(), java(), checkStyle()]
+ container('jetty-build') {
+ timeout(time: 120, unit: 'MINUTES') {
+ dir("${env.WORKSPACE}/buildy") {
+ mavenBuild("jdk17", "clean install -f jetty-core", "maven3")
+ }
}
}
}
}
-
+ stage("Module : /jetty-ee9/") {
+ steps {
+ container('jetty-build') {
+ timeout(time: 120, unit: 'MINUTES') {
+ dir("${env.WORKSPACE}/buildy") {
+ mavenBuild("jdk17", "clean install -f jetty-ee9", "maven3")
+ }
+ }
+ }
+ }
+ }
+ stage("Module : /jetty-ee10/") {
+ steps {
+ container('jetty-build') {
+ timeout(time: 120, unit: 'MINUTES') {
+ dir("${env.WORKSPACE}/buildy") {
+ mavenBuild("jdk17", "clean install -f jetty-ee10", "maven3")
+ }
+ }
+ }
+ }
+ }
+ /*stage("Module : /jetty-integrations/") {
+ steps {
+ container('jetty-build') {
+ timeout(time: 120, unit: 'MINUTES') {
+ dir("${env.WORKSPACE}/buildy") {
+ mavenBuild("jdk17", "clean install -f jetty-integrations", "maven3")
+ }
+ }
+ }
+ }
+ }*/
+ /*stage("Module : /jetty-home/") {
+ steps {
+ container('jetty-build') {
+ timeout(time: 120, unit: 'MINUTES') {
+ dir("${env.WORKSPACE}/buildy") {
+ mavenBuild("jdk17", "clean install -f jetty-home", "maven3")
+ }
+ }
+ }
+ }
+ }*/
+ /*
+ stage("Module : /tests/") {
+ steps {
+ container('jetty-build') {
+ timeout(time: 120, unit: 'MINUTES') {
+ dir("${env.WORKSPACE}/buildy") {
+ mavenBuild("jdk17", "clean install -f tests", "maven3")
+ }
+ }
+ }
+ }
+ }*/
+ /*stage("Module : /documentation/") {
+ steps {
+ container('jetty-build') {
+ timeout(time: 120, unit: 'MINUTES') {
+ dir("${env.WORKSPACE}/buildy") {
+ mavenBuild("jdk17", "clean install -f documentation", "maven3")
+ }
+ }
+ }
+ }
+ }*/
}
}
}
- post {
- failure {
- slackNotif()
- }
- unstable {
- slackNotif()
- }
- fixed {
- slackNotif()
- }
- }
-}
-
-def slackNotif() {
- script {
- try {
- if ( env.BRANCH_NAME == 'jetty-10.0.x' || env.BRANCH_NAME == 'jetty-11.0.x') {
- //BUILD_USER = currentBuild.rawBuild.getCause(Cause.UserIdCause).getUserId()
- // by ${BUILD_USER}
- COLOR_MAP = ['SUCCESS': 'good', 'FAILURE': 'danger', 'UNSTABLE': 'danger', 'ABORTED': 'danger']
- slackSend channel: '#jenkins',
- color: COLOR_MAP[currentBuild.currentResult],
- message: "*${currentBuild.currentResult}:* Job ${env.JOB_NAME} build ${env.BUILD_NUMBER} - ${env.BUILD_URL}"
- }
- } catch (Exception e) {
- e.printStackTrace()
- echo "skip failure slack notification: " + e.getMessage()
- }
- }
}
/**
@@ -93,14 +125,13 @@ def slackNotif() {
* @return the Jenkinsfile step representing a maven build
*/
def mavenBuild(jdk, cmdline, mvnName) {
- script {
try {
withEnv(["JAVA_HOME=${ tool "$jdk" }",
"PATH+MAVEN=${ tool "$jdk" }/bin:${tool "$mvnName"}/bin",
"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 -V -B -e -Djetty.testtracker.log=true $cmdline"
+ sh "mvn --no-transfer-progress -s $GLOBAL_MVN_SETTINGS -Pci --show-version --batch-mode --errors -Djetty.testtracker.log=true -Dmaven.test.failure.ignore=true $cmdline"
}
}
}
@@ -108,7 +139,6 @@ def mavenBuild(jdk, cmdline, mvnName) {
{
junit testResults: '**/target/surefire-reports/*.xml,**/target/invoker-reports/TEST*.xml', allowEmptyResults: true
}
- }
}
// vim: et:ts=2:sw=2:ft=groovy
diff --git a/Jenkinsfile-autobahn b/Jenkinsfile-autobahn
index eee85b9bbbe..0e92efd217d 100644
--- a/Jenkinsfile-autobahn
+++ b/Jenkinsfile-autobahn
@@ -10,17 +10,8 @@ pipeline {
// save some io during the build
durabilityHint( 'PERFORMANCE_OPTIMIZED' )
}
- parameters {
- string( defaultValue: 'jetty-10.0.x', description: 'GIT branch name to build (jetty-10.0.x/jetty-11.0.x/etc.)',
- name: 'JETTY_BRANCH' )
- }
stages {
- stage("Checkout Jetty Branch") {
- steps {
- git url: 'https://github.com/eclipse/jetty.project/', branch: '${JETTY_BRANCH}'
- }
- }
stage( "Build / Test - JDK11" ) {
agent {
node { label 'linux' }
@@ -28,14 +19,8 @@ pipeline {
steps {
container( 'jetty-build' ) {
timeout( time: 120, unit: 'MINUTES' ) {
- mavenBuild( "jdk11", "-T3 clean install -Djacoco.skip=true -pl :test-websocket-autobahn -am -Pautobahn -Dtest=AutobahnTests", "maven3" ) //
+ mavenBuild( "jdk11", "-T3 clean install -Djacoco.skip=true -Pautobahn", "maven3", true ) //
junit testResults: '**/target/surefire-reports/*.xml,**/target/invoker-reports/TEST*.xml,**/target/autobahntestsuite-reports/*.xml'
- publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, keepAll: true, reportDir: "${env.WORKSPACE}/tests/test-websocket-autobahn/target/reports/core/servers", reportFiles: 'index.html', reportName: 'Autobahn Report Core Server', reportTitles: ''])
- publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, keepAll: true, reportDir: "${env.WORKSPACE}/tests/test-websocket-autobahn/target/reports/core/clients", reportFiles: 'index.html', reportName: 'Autobahn Report Core Client', reportTitles: ''])
- publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, keepAll: true, reportDir: "${env.WORKSPACE}/tests/test-websocket-autobahn/target/reports/javax/servers", reportFiles: 'index.html', reportName: 'Autobahn Report Javax Server', reportTitles: ''])
- publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, keepAll: true, reportDir: "${env.WORKSPACE}/tests/test-websocket-autobahn/target/reports/javax/clients", reportFiles: 'index.html', reportName: 'Autobahn Report Javax Client', reportTitles: ''])
- publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, keepAll: true, reportDir: "${env.WORKSPACE}/tests/test-websocket-autobahn/target/reports/jetty/servers", reportFiles: 'index.html', reportName: 'Autobahn Report Jetty Server', reportTitles: ''])
- publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, keepAll: true, reportDir: "${env.WORKSPACE}/tests/test-websocket-autobahn/target/reports/jetty/clients", reportFiles: 'index.html', reportName: 'Autobahn Report Jetty Client', reportTitles: ''])
}
}
}
@@ -83,16 +68,19 @@ def slackNotif() {
* @paran mvnName maven installation to use
* @return the Jenkinsfile step representing a maven build
*/
-def mavenBuild(jdk, cmdline, mvnName) {
- script {
- withEnv(["JAVA_HOME=${ tool "$jdk" }",
- "PATH+MAVEN=${ tool "$jdk" }/bin:${tool "$mvnName"}/bin",
- "MAVEN_OPTS=-Xms2g -Xmx8g -Djava.awt.headless=true"]) {
- configFileProvider(
- [configFile(fileId: 'oss-settings.xml', variable: 'GLOBAL_MVN_SETTINGS')]) {
- sh "mvn -Denforcer.skip=true -Dlicense.skip=true -Dspotbugs.skip=true -Dcheckstyle.skip=true --no-transfer-progress -s $GLOBAL_MVN_SETTINGS -Dmaven.repo.local=.repository -Pci -V -B -e -Djetty.testtracker.log=true $cmdline"
- }
- }
+def mavenBuild(jdk, cmdline, mvnName, junitPublishDisabled) {
+ def localRepo = ".repository"
+ def mavenOpts = '-Xms1g -Xmx4g -Djava.awt.headless=true'
+
+ withMaven(
+ maven: mvnName,
+ jdk: "$jdk",
+ publisherStrategy: 'EXPLICIT',
+ options: [junitPublisher(disabled: junitPublishDisabled), mavenLinkerPublisher(disabled: false), pipelineGraphPublisher(disabled: false)],
+ mavenOpts: mavenOpts,
+ mavenLocalRepo: localRepo) {
+ // Some common Maven command line + provided command line
+ sh "mvn -Pci -V -B -e -fae -Dmaven.test.failure.ignore=true -Djetty.testtracker.log=true $cmdline"
}
}
diff --git a/SECURITY.md b/SECURITY.md
deleted file mode 100644
index 1af414ee5d5..00000000000
--- a/SECURITY.md
+++ /dev/null
@@ -1,47 +0,0 @@
-# Security Policy
-
-## Supported Versions
-
-All [stable versions](https://www.eclipse.org/jetty/download.php) of jetty are actively supported for security issues. [Deprecated versions](https://www.eclipse.org/jetty/download.php) may be supported for serious security issues or on a commercial support basis.
-
-## Reporting a Vulnerability
-
-Do not open a public issue to report a security vulnerability. Please send a message to security@eclipse.org and we will create a private issue in which the issue can be triaged and handled.
-
-## Handling a Vulnerability
-
-The [following checklist](https://www.eclipse.org/jetty/security_processes.php) is used to handle security issues:
-
-- [ ] On receipt of a security report via security@webtide.com or other channels, if it cannot be trivially dismissed (already fixed, known not a problem, etc.), then a Github security advisory is created by project leadership.
-- [ ] Copy this list as a markdown in the security advisory for tracking the completion of various tasks.
-- [ ] Jetty committers and the reporters are added to the security advisory. Individual committers can also be named in the comments for addition.
-- [ ] Initial triage and discussion are performed in the comments of the advisory.
-- [ ] If enough information exists to attempt reproduction or fix, then a private repository is created as part of the GitHub security advisory.
-- [ ] If the vulnerability cannot be confirmed then close the security advisory, else continue.
-- [ ] Generate a CVE score and add it to the advisory description.
-- [ ] Identify a CWE Definition and add it to the advisory description.
-- [ ] Identify vulnerable version(s), including current and past versions that are affected (e.g. 9.4.0 through 9.4.35, and 10.0.0.alpha1 through 10.0.0.beta3…​etc.)
-- [ ] Identify and document workaround(s), if applicable, in the comments of the security advisory.
-- [ ] Open an Eclipse Bugzilla issue to have a CVE allocated. The issue should be opened under the Community "Product" category with a "Component" of Vulnerability Reports. The CVE should include the following:
- 1. Version(s) affected
- 2. CVE Score
- 3. CWE Identifier(s)
- 4. Brief description of the issue
-- [ ] Once the CVE is allocated update the Security Advisory with the number
-- [ ] Build and test fix(es) locally and in CI environment.
-- [ ] Merge tests and fix - ensure description does not mention vulnerability directly. Do not merge directly from the security advisory as it can be traced back before publication.
-- [ ] Build and stage release candidate.
-- [ ] Notify interested parties of pending security advisory and staged release:
- 1. Include CVE number, CVE score, and CWE
- 2. Include Workarounds
- 3. Stress that it is confidential
- 4. Advise the security advisory will be published in 2 days unless they indicate they need more time.
-- [ ] If testing is OK, then the release is promoted.
-- [ ] Interested parties are notified of the availability of release on Maven Central.
-- [ ] Publish security advisory and CVE publicly.
-- [ ] Edit VERSION.txt and so that the CVE number is now recorded against merged PR.
-- [ ] Edit the release(s) on Github to identify CVE number that was addressed/resolved.
-- [ ] Update downstream images (Docker, etc.).
-- [ ] Update project website with new security entry.
-- [ ] Review security processes & completion.
-
diff --git a/VERSION.txt b/VERSION.txt
index 17d9ac1c850..8b6842d5029 100644
--- a/VERSION.txt
+++ b/VERSION.txt
@@ -1,228 +1,4 @@
-jetty-11.0.10-SNAPSHOT
-
-jetty-11.0.9 - 30 March 2022
- + 5681 Unrecognized jetty-home/start.jar command line option not reported
- clearly
- + 5965 Option --write-module-graph produces wrong .dot file
- + 6879 Remove jminix (not maintained) module as hawtio provide same features
- + 7182 jetty.sh start process should remove jetty_state whenever deleting the
- pid
- + 7344 Incompatible with jacoco due to shutdown race condition
- + 7414 QoSFilter.setMaxRequests throws NullPointerException
- + 7513 Getter/setter type mismatch for mbean attribute file in class
- org.eclipse.jetty.deploy.PropertiesConfigurationManager
- + 7517 Some ArrayTrie methods throw StackOverflowError when cointaining a very
- large entry
- + 7518 ArrayTrie getBest fails to match the empty string entry in certain
- cases
- + 7545 Named arguments do not work in jetty-openid.xml
- + 7548 Interrupt flag is not always cleared in between requests
- + 7567 Gzip compression not working for multipart/form-data when added to the
- allowed list using addIncludedMimeTypes.
- + 7573 WebSockets - "Unsupported PathParam Type: java.lang.Integer"
- + 7575 Misleading docs for `HttpClientTransportDynamic`
- + 7613 Configurations.add(Configuration) results in
- UnsupportedOperationException
- + 7615 HttpServletResponse.encodeURL not working for URLs starting with ../
- + 7617 Logback-access RequestLog not working
- + 7625 HTTP/3 error against www.google.com
- + 7677 jetty-maven-plugin - maven internal dependencies included on webapp
- classloader
- + 7683 GZIPContentDecoder ignores setUseInputDirectByteBuffers setting and
- always uses non-direct buffers (causing GC locking)
- + 7688 Read data to native memory from HttpInput
- + 7748 Allow overriding of url-pattern mapping in ServletContextHandler to
- allow for regex or uri-template matching
-
-jetty-11.0.8 - 07 February 2022
- + 2504 Expose more WebSocket details in JMX and Server Dump
- + 4275 Path Normalization/Traversal - Context Matching
- + 4317 EventSource does not work with GzipHandler
- + 6017 Property overriding does not work
- + 6282 SecuredRedirectHandler should probably redirect with 301
- + 6497 Replace SameFileAliasChecker
- + 6728 QUIC and HTTP/3
- + 6730 HTTP3: update Quiche to 0.9.0
- + 6965 Expose Spec `ServerContainer.upgrade()` API
- + 6973 Jetty starts consuming CPU that remains high even without any traffic
- + 6974 Major websocket memory change in 9.4.36
- + 6980 ELContextCleaner failed because cannot access a member of class
- javax.el.BeanELResolver with modifiers "private static final"
- + 6985 ELContextCleaner references javax class in jetty-11
- + 6987 jetty-unixdomain-server is missing from jetty-bom
- + 6990 UnixDomainServerConnector throws misleading exception on invalid socket
- path
- + 7008 Problem with jetty.sh start regression 10.0.6 -> 10.0.7 when using
- JETTY_USER
- + 7012 Remove all old geronimo spec jars from jetty-10
- + 7031 ResponseWriter.println(char) does not print newline
- + 7042 Simplify configuration to use different OpenIdConfiguration per webapp
- + 7059 NPE in AllowedResourceAliasChecker.getPath()
- + 7063 Simplify command line use of org.eclipse.jetty.util.Password
- + 7064 Cleanup or clarify `(null)` in output of `--list-config`
- + 7086 WebSocket: java.lang.IllegalStateException: already released
- RetainableByteBuffer
- + 7103 Rework LaF of distro landing page
- + 7107 Client timeout and async close exceptions when setting max duration on
- pool
- + 7109 Deprecate UnixSocket JNR support
- + 7111 Add support to deprecate jetty-home modules
- + 7113 Improve Unix-Domain client documentation
- + 7124 Add default methods on LifeCycle.Listener interface
- + 7131 Use Charset instead of encoding string where possible
- + 7157 Multiplexed connection pools retain CLOSED entries
- + 7160 HttpURI considers %25 to be ambiguous, preventing access to static
- resources with % in their name
- + 7240 Clarify and javadoc InvocationType
- + 7243 Reset pooled ByteBuffer endianness
- + 7262 Allow the SerlvetHandler.getFilterChain method to be overridden
- + 7277 Allow override of `ServletRequest.getLocalName()` and `.getLocalPort()`
- in post-intermediary scenarios
- + 7280 Interceptors don't get destroyed in HttpInput
- + 7281 EOFs are not passed to interceptors any more - shouldn't they?
- + 7284 HttpInput reopen/recycle cleanup
- + 7297 Deprecate log4j 1.x support
- + 7313 addBean(_attributes); only called in the Convenience constructor of
- org.eclipse.jetty.server.Server
- + 7327 jetty-slf4j-impl missing from BOM
- + 7348 Slow CONNECT request causes NPE
- + 7351 Large WebSocket payloads with permessage-deflate hang on 10.0.7
- + 7354 Demo jars should not be in jetty-home
- + 7369 Document CustomRequestLog
- + 7375 Some environments require Request scoping during session save
- + 7435 Investigate Infinispan transitive dependencies
- + 7494 Remove modules in Jetty 11 that are not supporting jakarta.servlet yet
- + 7496 Transient 400: Bad Request responses in jetty-9.4.45.v20220128
- + 7514 Adding InheritedListeners to already-started components can cause
- IllegalStateException
- + 7523 Typo in AnnotationConfiguration
- + 7524 Missing package in JmxConfiguration
- + 7529 Upgrade quiche to version 0.11.0
-
-jetty-10.0.9 - 30 March 2022
- + 5681 Unrecognized jetty-home/start.jar command line option not reported
- clearly
- + 5965 Option --write-module-graph produces wrong .dot file
- + 6879 Remove jminix (not maintained) module as hawtio provide same features
- + 7182 jetty.sh start process should remove jetty_state whenever deleting the
- pid
- + 7344 Incompatible with jacoco due to shutdown race condition
- + 7414 QoSFilter.setMaxRequests throws NullPointerException
- + 7513 Getter/setter type mismatch for mbean attribute file in class
- org.eclipse.jetty.deploy.PropertiesConfigurationManager
- + 7517 Some ArrayTrie methods throw StackOverflowError when cointaining a very
- large entry
- + 7518 ArrayTrie getBest fails to match the empty string entry in certain
- cases
- + 7545 Named arguments do not work in jetty-openid.xml
- + 7548 Interrupt flag is not always cleared in between requests
- + 7567 Gzip compression not working for multipart/form-data when added to the
- allowed list using addIncludedMimeTypes.
- + 7573 WebSockets - "Unsupported PathParam Type: java.lang.Integer"
- + 7575 Misleading docs for `HttpClientTransportDynamic`
- + 7613 Configurations.add(Configuration) results in
- UnsupportedOperationException
- + 7615 HttpServletResponse.encodeURL not working for URLs starting with ../
- + 7617 Logback-access RequestLog not working
- + 7625 HTTP/3 error against www.google.com
- + 7677 jetty-maven-plugin - maven internal dependencies included on webapp
- classloader
- + 7683 GZIPContentDecoder ignores setUseInputDirectByteBuffers setting and
- always uses non-direct buffers (causing GC locking)
- + 7688 Read data to native memory from HttpInput
- + 7748 Allow overriding of url-pattern mapping in ServletContextHandler to
- allow for regex or uri-template matching
-
-jetty-10.0.8 - 07 February 2022
- + 2504 Expose more WebSocket details in JMX and Server Dump
- + 4275 Path Normalization/Traversal - Context Matching
- + 4317 EventSource does not work with GzipHandler
- + 6017 Property overriding does not work
- + 6282 SecuredRedirectHandler should probably redirect with 301
- + 6497 Replace SameFileAliasChecker
- + 6728 QUIC and HTTP/3
- + 6730 HTTP3: update Quiche to 0.9.0
- + 6965 Expose Spec `ServerContainer.upgrade()` API
- + 6973 Jetty starts consuming CPU that remains high even without any traffic
- + 6974 Major websocket memory change in 9.4.36
- + 6980 ELContextCleaner failed because cannot access a member of class
- javax.el.BeanELResolver with modifiers "private static final"
- + 6987 jetty-unixdomain-server is missing from jetty-bom
- + 6990 UnixDomainServerConnector throws misleading exception on invalid socket
- path
- + 7008 Problem with jetty.sh start regression 10.0.6 -> 10.0.7 when using
- JETTY_USER
- + 7012 Remove all old geronimo spec jars from jetty-10
- + 7031 ResponseWriter.println(char) does not print newline
- + 7042 Simplify configuration to use different OpenIdConfiguration per webapp
- + 7059 NPE in AllowedResourceAliasChecker.getPath()
- + 7063 Simplify command line use of org.eclipse.jetty.util.Password
- + 7064 Cleanup or clarify `(null)` in output of `--list-config`
- + 7086 WebSocket: java.lang.IllegalStateException: already released
- RetainableByteBuffer
- + 7103 Rework LaF of distro landing page
- + 7107 Client timeout and async close exceptions when setting max duration on
- pool
- + 7109 Deprecate UnixSocket JNR support
- + 7111 Add support to deprecate jetty-home modules
- + 7113 Improve Unix-Domain client documentation
- + 7124 Add default methods on LifeCycle.Listener interface
- + 7131 Use Charset instead of encoding string where possible
- + 7157 Multiplexed connection pools retain CLOSED entries
- + 7160 HttpURI considers %25 to be ambiguous, preventing access to static
- resources with % in their name
- + 7240 Clarify and javadoc InvocationType
- + 7243 Reset pooled ByteBuffer endianness
- + 7262 Allow the SerlvetHandler.getFilterChain method to be overridden
- + 7277 Allow override of `ServletRequest.getLocalName()` and `.getLocalPort()`
- in post-intermediary scenarios
- + 7280 Interceptors don't get destroyed in HttpInput
- + 7281 EOFs are not passed to interceptors any more - shouldn't they?
- + 7284 HttpInput reopen/recycle cleanup
- + 7297 Deprecate log4j 1.x support
- + 7313 addBean(_attributes); only called in the Convenience constructor of
- org.eclipse.jetty.server.Server
- + 7327 jetty-slf4j-impl missing from BOM
- + 7348 Slow CONNECT request causes NPE
- + 7351 Large WebSocket payloads with permessage-deflate hang on 10.0.7
- + 7354 Demo jars should not be in jetty-home
- + 7369 Document CustomRequestLog
- + 7375 Some environments require Request scoping during session save
- + 7435 Investigate Infinispan transitive dependencies
- + 7496 Transient 400: Bad Request responses in jetty-9.4.45.v20220128
- + 7514 Adding InheritedListeners to already-started components can cause
- IllegalStateException
- + 7523 Typo in AnnotationConfiguration
- + 7524 Missing package in JmxConfiguration
- + 7529 Upgrade quiche to version 0.11.0
-
-jetty-9.4.45.v20220203 - 03 February 2022
- + 4275 Path Normalization/Traversal - Context Matching
- + 6497 Replace SameFileAliasChecker
- + 6687 Upgrade Infinispan in all active Jetty branches
- + 6965 Expose Spec `ServerContainer.upgrade()` API
- + 6969 Getting 404 failures when trying to enable `logging-log4j` module
- + 6974 Major websocket memory change in 9.4.36
- + 7031 ResponseWriter.println(char) does not print newline
- + 7059 NPE in AllowedResourceAliasChecker.getPath()
- + 7073 Error in parse parameter in broken UTF-8 encoding
- + 7078 CompressionPools are not shared between multiple contexts for 9.4
- WebSocket
- + 7107 Client timeout and async close exceptions when setting max duration on
- pool
- + 7124 Add default methods on LifeCycle.Listener interface
- + 7157 Multiplexed connection pools retain CLOSED entries
- + 7243 Reset pooled ByteBuffer endianness
- + 7266 Wrong ALPN jars are selected for newer versions of JDK8
- + 7271 It is necessary to set MAX_CAPACITY to ArrayTernaryTrie/ArrayTrie
- + 7277 Allow override of `ServletRequest.getLocalName()` and `.getLocalPort()`
- in post-intermediary scenarios
- + 7297 Deprecate log4j 1.x support
- + 7348 Slow CONNECT request causes NPE
- + 7375 Some environments require Request scoping during session save
- + 7435 Investigate Infinispan transitive dependencies
- + 7440 ContextHandler.getAliasChecks() breaks Spring Boot
- + 7496 Transient 400: Bad Request responses in jetty-9.4.45.v20220128
+jetty-12.0.0-SNAPSHOT
jetty-11.0.7 - 06 October 2021
+ 3514 Use interpolation of versions from pom in mod files
@@ -238,15 +14,15 @@ jetty-11.0.7 - 06 October 2021
active modules
+ 6487 Expose ServletHolder getter in ServletHandler$ChainEnd for auditing
libraries to use
- + 6489 Some URI valid compliance modes cannot be set in .ini file
+ + 6489 Some URI valid compliance modes cannot be set in .ini file.
+ 6491 onDataAvailable() not called when HttpParser is closed prematurely
+ 6497 Replace SameFileAliasChecker
- + 6520 Error page has HTML error when writePoweredBy is enabled
+ + 6520 Error page has HTML error when writePoweredBy is enabled.
+ 6544 Using jetty.gzip.excludedMimeTypeList property results in an error
+ 6545 image/webp MIME type support
+ 6552 FileBufferedInterceptor.dispose not working due to locked file
+ 6553 Review usage of Authentication.UNAUTHENTICATED in SecurityHandler
- + 6554 Allow creation of DefaultIdentityService without realmName
+ + 6554 Allow creation of DefaultIdentityService without realmName.
+ 6556 MemcachedSessionDataMap needs to set the context classloader before
serialization/deseriazliation.
+ 6558 Allow to configure return type in JSON array parsing
@@ -262,7 +38,7 @@ jetty-11.0.7 - 06 October 2021
+ 6617 Add basic auth support for OpenId token endpoint (client_secret_basic)
+ 6618 ID token `azp`Â claim should not be required if `aud` is single value
array
- + 6642 WebSocket handling of Connection: upgrade,close
+ + 6642 WebSocket handling of Connection: upgrade,close.
+ 6646 Deadlock in HTTP2Flusher when using a small thread pool due to
incorrect InvocableType
+ 6652 Improve ReservedThreadExecutor dump
@@ -285,6 +61,19 @@ jetty-11.0.7 - 06 October 2021
+ 6883 Welcome file redirects do not honor the relativeRedirectAllowed option
+ 6938 module-info.java file do not use the canonical order for the elements
+jetty-11.0.6 - 29 June 2021
+ + 6375 Always check XML `Set` elements with `property` attribute
+ + 6382 HttpClient TimeoutException message reports transient values
+ + 6394 Review osgi manifests within Jetty 10
+ + 6407 Malformed scheme logical expression check in WebSocket
+ ClientUpgradeRequest
+ + 6410 Ensure Jetty IO uses SocketAddress instead of InetSocketAddress
+ + 6418 Bad and/or missing Require-Capability for osgi.serviceloader
+ + 6425 Update to asm 9.1
+ + 6447 Deprecate support for UTF16 encoding in URIs
+ + 6451 Request#getServletPath() returns null for ROOT mapping
+ + 6464 Wrong files/lib definitions in certain *-capture.mod files?
+
jetty-10.0.7 - 06 October 2021
+ 3514 Use interpolation of versions from pom in mod files
+ 6043 Reimplement UnixSocket support based on Java 16
@@ -298,15 +87,15 @@ jetty-10.0.7 - 06 October 2021
active modules
+ 6487 Expose ServletHolder getter in ServletHandler$ChainEnd for auditing
libraries to use
- + 6489 Some URI valid compliance modes cannot be set in .ini file
+ + 6489 Some URI valid compliance modes cannot be set in .ini file.
+ 6491 onDataAvailable() not called when HttpParser is closed prematurely
+ 6497 Replace SameFileAliasChecker
- + 6520 Error page has HTML error when writePoweredBy is enabled
+ + 6520 Error page has HTML error when writePoweredBy is enabled.
+ 6544 Using jetty.gzip.excludedMimeTypeList property results in an error
+ 6545 image/webp MIME type support
+ 6552 FileBufferedInterceptor.dispose not working due to locked file
+ 6553 Review usage of Authentication.UNAUTHENTICATED in SecurityHandler
- + 6554 Allow creation of DefaultIdentityService without realmName
+ + 6554 Allow creation of DefaultIdentityService without realmName.
+ 6556 MemcachedSessionDataMap needs to set the context classloader before
serialization/deseriazliation.
+ 6558 Allow to configure return type in JSON array parsing
@@ -321,7 +110,7 @@ jetty-10.0.7 - 06 October 2021
+ 6617 Add basic auth support for OpenId token endpoint (client_secret_basic)
+ 6618 ID token `azp`Â claim should not be required if `aud` is single value
array
- + 6642 WebSocket handling of Connection: upgrade,close
+ + 6642 WebSocket handling of Connection: upgrade,close.
+ 6646 Deadlock in HTTP2Flusher when using a small thread pool due to
incorrect InvocableType
+ 6652 Improve ReservedThreadExecutor dump
@@ -342,45 +131,6 @@ jetty-10.0.7 - 06 October 2021
+ 6883 Welcome file redirects do not honor the relativeRedirectAllowed option
+ 6938 module-info.java file do not use the canonical order for the elements
-jetty-9.4.44.v20210927 - 27 September 2021
- + 3514 Use interpolation of versions from pom in mod files
- + 6369 Increment default jetty.http2.rateControl.maxEventsPerSecond
- + 6372 Review socket options configuration
- + 6487 Expose ServletHolder getter in ServletHandler$ChainEnd for auditing
- libraries to use
- + 6491 onDataAvailable() not called when HttpParser is closed prematurely
- + 6520 Error page has HTML error when writePoweredBy is enabled
- + 6545 image/webp MIME type support
- + 6553 Review usage of Authentication.UNAUTHENTICATED in SecurityHandler
- + 6554 Allow creation of DefaultIdentityService without realmName
- + 6558 Allow to configure return type in JSON array parsing
- + 6562 HttpOutput.write(ByteBuffer buffer)
- + 6603 HTTP/2 max local stream count exceeded
- + 6617 Add basic auth support for OpenId token endpoint (client_secret_basic)
- + 6618 ID token `azp`Â claim should not be required if `aud` is single value
- array
- + 6652 Improve ReservedThreadExecutor dump
- + 6671 Update to apache jsp 8.5.70
- + 6772 Update to asm 9.2
- + 6853 Remove pack200 plugins
- + 6860 Correct IPv6 format
- + 6869 Correct Content-Type within HTML error pages
- + 6870 Encode control characters in URIUtil.encodePath
- + 6883 Welcome file redirects do not honor the relativeRedirectAllowed option
-
-jetty-11.0.6 - 29 June 2021
- + 6375 Always check XML `Set` elements with `property` attribute
- + 6382 HttpClient TimeoutException message reports transient values
- + 6394 Review osgi manifests within Jetty 10
- + 6407 Malformed scheme logical expression check in WebSocket
- ClientUpgradeRequest
- + 6410 Ensure Jetty IO uses SocketAddress instead of InetSocketAddress
- + 6418 Bad and/or missing Require-Capability for osgi.serviceloader
- + 6425 Update to asm 9.1
- + 6447 Deprecate support for UTF16 encoding in URIs
- + 6451 Request#getServletPath() returns null for ROOT mapping
- + 6464 Wrong files/lib definitions in certain *-capture.mod files?
-
jetty-10.0.6 - 29 June 2021
+ 6375 Always check XML `Set` elements with `property` attribute
+ 6382 HttpClient TimeoutException message reports transient values
diff --git a/apache-jsp/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer b/apache-jsp/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer
deleted file mode 100644
index 634670591f6..00000000000
--- a/apache-jsp/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer
+++ /dev/null
@@ -1 +0,0 @@
-org.eclipse.jetty.apache.jsp.JettyJasperInitializer
diff --git a/apache-jsp/src/main/resources/META-INF/services/org.apache.juli.logging.Log b/apache-jsp/src/main/resources/META-INF/services/org.apache.juli.logging.Log
deleted file mode 100644
index efa397b7c60..00000000000
--- a/apache-jsp/src/main/resources/META-INF/services/org.apache.juli.logging.Log
+++ /dev/null
@@ -1 +0,0 @@
-org.eclipse.jetty.apache.jsp.JuliLog
diff --git a/build-resources/jetty-codestyle-eclipse-ide.xml b/build/build-resources/jetty-codestyle-eclipse-ide.xml
similarity index 100%
rename from build-resources/jetty-codestyle-eclipse-ide.xml
rename to build/build-resources/jetty-codestyle-eclipse-ide.xml
diff --git a/build-resources/jetty-codestyle-intellij.xml b/build/build-resources/jetty-codestyle-intellij.xml
similarity index 100%
rename from build-resources/jetty-codestyle-intellij.xml
rename to build/build-resources/jetty-codestyle-intellij.xml
diff --git a/build-resources/pom.xml b/build/build-resources/pom.xml
similarity index 96%
rename from build-resources/pom.xml
rename to build/build-resources/pom.xml
index 4dcfa070076..2cfa013be4f 100644
--- a/build-resources/pom.xml
+++ b/build/build-resources/pom.xml
@@ -7,7 +7,7 @@
-->
org.eclipse.jettybuild-resources
- 11.0.10-SNAPSHOT
+ 12.0.0-SNAPSHOTJetty :: Build Resourcesjar
@@ -15,7 +15,7 @@
UTF-83.0.0-M2
- 3.4.0
+ 3.3.11.6.03.0.0-M5
diff --git a/build-resources/src/main/resources/jetty-checkstyle.xml b/build/build-resources/src/main/resources/jetty-checkstyle.xml
similarity index 100%
rename from build-resources/src/main/resources/jetty-checkstyle.xml
rename to build/build-resources/src/main/resources/jetty-checkstyle.xml
diff --git a/jetty-unixsocket/pom.xml b/build/pom.xml
similarity index 53%
rename from jetty-unixsocket/pom.xml
rename to build/pom.xml
index 38055172b8a..58db6fd7ca4 100644
--- a/jetty-unixsocket/pom.xml
+++ b/build/pom.xml
@@ -1,25 +1,22 @@
+
org.eclipse.jettyjetty-project
- 11.0.10-SNAPSHOT
+ 12.0.0-SNAPSHOT4.0.0
- jetty-unixsocket
+ org.eclipse.jetty.build
+ build
+ Build :: Parentpom
- Jetty :: UnixSocket
-
- Jetty UnixSocket Parent
-
-
- jetty-unixsocket-common
- jetty-unixsocket-client
- jetty-unixsocket-server
-
- org.eclipse.jetty.unixsocket.*
+ true
+
+ build-resources
+
diff --git a/scripts/clirr-gen-master-index.output-foot.html b/build/scripts/clirr-gen-master-index.output-foot.html
similarity index 100%
rename from scripts/clirr-gen-master-index.output-foot.html
rename to build/scripts/clirr-gen-master-index.output-foot.html
diff --git a/scripts/clirr-gen-master-index.output-head.html b/build/scripts/clirr-gen-master-index.output-head.html
similarity index 100%
rename from scripts/clirr-gen-master-index.output-head.html
rename to build/scripts/clirr-gen-master-index.output-head.html
diff --git a/scripts/clirr-gen-master-index.output-html.xslt b/build/scripts/clirr-gen-master-index.output-html.xslt
similarity index 100%
rename from scripts/clirr-gen-master-index.output-html.xslt
rename to build/scripts/clirr-gen-master-index.output-html.xslt
diff --git a/scripts/clirr-gen-master-index.sh b/build/scripts/clirr-gen-master-index.sh
similarity index 100%
rename from scripts/clirr-gen-master-index.sh
rename to build/scripts/clirr-gen-master-index.sh
diff --git a/scripts/git-log-csv.sh b/build/scripts/git-log-csv.sh
similarity index 100%
rename from scripts/git-log-csv.sh
rename to build/scripts/git-log-csv.sh
diff --git a/scripts/looptest.sh b/build/scripts/looptest.sh
similarity index 100%
rename from scripts/looptest.sh
rename to build/scripts/looptest.sh
diff --git a/scripts/query-git-stats.sh b/build/scripts/query-git-stats.sh
similarity index 100%
rename from scripts/query-git-stats.sh
rename to build/scripts/query-git-stats.sh
diff --git a/scripts/release-jetty.sh b/build/scripts/release-jetty.sh
similarity index 100%
rename from scripts/release-jetty.sh
rename to build/scripts/release-jetty.sh
diff --git a/demos/demo-async-rest/pom.xml b/demos/demo-async-rest/pom.xml
deleted file mode 100644
index a344b4b5a40..00000000000
--- a/demos/demo-async-rest/pom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
- org.eclipse.jetty.demos
- demos-parent
- 11.0.10-SNAPSHOT
-
-
- 4.0.0
- demo-async-rest-parent
- pom
- Demo :: Async Rest
-
-
- demo-async-rest-jar
- demo-async-rest-webapp
- demo-async-rest-server
-
-
-
diff --git a/demos/demo-jetty-webapp/src/test/resources/jetty-logging.properties b/demos/demo-jetty-webapp/src/test/resources/jetty-logging.properties
deleted file mode 100644
index 04724735a9d..00000000000
--- a/demos/demo-jetty-webapp/src/test/resources/jetty-logging.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-# Jetty Logging using jetty-slf4j-impl
-com.acme.LEVEL=INFO
-# org.eclipse.jetty.annotations.LEVEL=DEBUG
\ No newline at end of file
diff --git a/demos/demo-mock-resources/src/main/resources/META-INF/javaxmail.providers b/demos/demo-mock-resources/src/main/resources/META-INF/javaxmail.providers
deleted file mode 100644
index 5ab3340c05a..00000000000
--- a/demos/demo-mock-resources/src/main/resources/META-INF/javaxmail.providers
+++ /dev/null
@@ -1 +0,0 @@
- protocol=smtp; type=transport; class=com.acme.MockTransport; vendor=Acme Tests;
diff --git a/demos/demo-spec/demo-container-initializer/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer b/demos/demo-spec/demo-container-initializer/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer
deleted file mode 100644
index 622cbd01213..00000000000
--- a/demos/demo-spec/demo-container-initializer/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer
+++ /dev/null
@@ -1 +0,0 @@
-com.acme.initializer.FooInitializer
diff --git a/documentation/jetty-asciidoctor-extensions/pom.xml b/documentation/jetty-asciidoctor-extensions/pom.xml
index 4bab6afb942..939986ccc5e 100644
--- a/documentation/jetty-asciidoctor-extensions/pom.xml
+++ b/documentation/jetty-asciidoctor-extensions/pom.xml
@@ -2,8 +2,8 @@
org.eclipse.jetty.documentation
- documentation-parent
- 11.0.10-SNAPSHOT
+ documentation
+ 12.0.0-SNAPSHOT4.0.0
diff --git a/documentation/jetty-documentation/pom.xml b/documentation/jetty-documentation/pom.xml
index f1351320e2d..641f05f9b8a 100644
--- a/documentation/jetty-documentation/pom.xml
+++ b/documentation/jetty-documentation/pom.xml
@@ -2,14 +2,17 @@
org.eclipse.jetty.documentation
- documentation-parent
- 11.0.10-SNAPSHOT
+ documentation
+ 12.0.0-SNAPSHOT4.0.0jetty-documentationJetty :: Documentationjar
+
+ ee9
+
@@ -136,6 +139,18 @@
+
+
+
+ org.eclipse.jetty.${ee.version}
+ jetty-${ee.version}-bom
+ ${project.version}
+ pom
+ import
+
+
+
+
org.eclipse.jetty.toolchain
@@ -162,20 +177,20 @@
jetty-server
- org.eclipse.jetty
- jetty-servlet
+ org.eclipse.jetty.${ee.version}
+ jetty-${ee.version}-servlet
- org.eclipse.jetty
- jetty-servlets
+ org.eclipse.jetty.${ee.version}
+ jetty-${ee.version}-servletsorg.eclipse.jettyjetty-util-ajax
- org.eclipse.jetty
- jetty-webapp
+ org.eclipse.jetty.${ee.version}
+ jetty-${ee.version}-webapporg.eclipse.jetty.fcgi
@@ -215,16 +230,16 @@
jetty-nosql
- org.eclipse.jetty.websocket
- websocket-jetty-client
+ org.eclipse.jetty.${ee.version}
+ jetty-${ee.version}-websocket-jetty-client
- org.eclipse.jetty.websocket
- websocket-jakarta-server
+ org.eclipse.jetty.${ee.version}
+ jetty-${ee.version}-websocket-jakarta-server
- org.eclipse.jetty.websocket
- websocket-jetty-server
+ org.eclipse.jetty.${ee.version}
+ jetty-${ee.version}-websocket-jetty-server
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/annotations/quick-annotations-setup.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/annotations/quick-annotations-setup.adoc
index 2cdb351b97b..b7e82bee667 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/annotations/quick-annotations-setup.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/annotations/quick-annotations-setup.adoc
@@ -28,7 +28,7 @@ Annotations and JNDI are pre-enabled for the Maven plugin.
==== Embedding
To use annotations in an embedded scenario, you will need to include the `jetty-annotations` jar and all its dependencies onto your classpath.
-You will also need to include the `org.eclipse.jetty.annotations.AnnotationConfiguration` class into the list of link:#webapp-configurations[Configuration classes] applied to the `org.eclipse.jetty.webapp.WebAppContext` class representing your webapp.
+You will also need to include the `org.eclipse.jetty.annotations.AnnotationConfiguration` class into the list of link:#webapp-configurations[Configuration classes] applied to the `org.eclipse.jetty.ee9.webapp.WebAppContext` class representing your webapp.
Below is an example application that sets up the standard `test-spec.war` webapp from the distribution in embedded fashion.
It can also be found in the Jetty GitHub repository on the examples/embedded page as link:{GITBROWSEURL}/examples/embedded/src/main/java/org/eclipse/jetty/embedded[`ServerWithAnnotations.java`.]
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/annotations/using-annotations-embedded.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/annotations/using-annotations-embedded.adoc
index 29c7c315e9c..739924a4167 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/annotations/using-annotations-embedded.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/annotations/using-annotations-embedded.adoc
@@ -38,7 +38,7 @@ The code is as follows:
----
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.ee9.webapp.WebAppContext;
/**
* ServerWithAnnotations
@@ -53,9 +53,9 @@ public class ServerWithAnnotations
Server server = new Server(8080);
//Enable parsing of jndi-related parts of web.xml and jetty-env.xml
- org.eclipse.jetty.webapp.Configuration.ClassList classlist = org.eclipse.jetty.webapp.Configuration.ClassList.setServerDefault(server);
- classlist.addAfter("org.eclipse.jetty.webapp.FragmentConfiguration", "org.eclipse.jetty.plus.webapp.EnvConfiguration", "org.eclipse.jetty.plus.webapp.PlusConfiguration");
- classlist.addBefore("org.eclipse.jetty.webapp.JettyWebXmlConfiguration", "org.eclipse.jetty.annotations.AnnotationConfiguration");
+ org.eclipse.jetty.ee9.webapp.Configuration.ClassList classlist = org.eclipse.jetty.ee9.webapp.Configuration.ClassList.setServerDefault(server);
+ classlist.addAfter("org.eclipse.jetty.ee9.webapp.FragmentConfiguration", "org.eclipse.jetty.plus.webapp.EnvConfiguration", "org.eclipse.jetty.plus.webapp.PlusConfiguration");
+ classlist.addBefore("org.eclipse.jetty.ee9.webapp.JettyWebXmlConfiguration", "org.eclipse.jetty.annotations.AnnotationConfiguration");
//Create a WebApp
WebAppContext webapp = new WebAppContext();
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/ant/jetty-ant.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/ant/jetty-ant.adoc
index 324c5ede3a0..e6da9506c7b 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/ant/jetty-ant.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/ant/jetty-ant.adoc
@@ -462,7 +462,7 @@ deploying more than one web application:::
As the `org.eclipse.jetty.ant.AntWebAppContext` class is an extension of
the
-link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html[`org.eclipse.jetty.webapp.WebAppContext`]
+link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html[`org.eclipse.jetty.ee9.webapp.WebAppContext`]
class, you can configure it by adding attributes of the same name
(without the `set` or `add` prefix) as the setter methods.
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/architecture/jetty-classloading.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/architecture/jetty-classloading.adoc
index 074900b4adf..5b97ab66493 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/architecture/jetty-classloading.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/architecture/jetty-classloading.adoc
@@ -57,12 +57,12 @@ Below is an example of implementing this feature using Jetty IoC XML format:
[source, xml, options="header"]
----
-
+
...
-
+
@@ -97,7 +97,7 @@ The default system classes are:
|org.eclipse.jetty.jndi. |Webapp can see and not change naming classes.
|org.eclipse.jetty.jaas. |Webapp can see and not change JAAS classes.
|org.eclipse.jetty.websocket. |WebSocket is a Jetty extension.
-|org.eclipse.jetty.servlet.DefaultServlet |Webapp can see and not change default servlet.
+|org.eclipse.jetty.ee9.servlet.DefaultServlet |Webapp can see and not change default servlet.
|=======================================================================
Absolute classname can be passed, names ending with `.` are treated as packages names, and names starting with `-` are treated as negative matches and must be listed before any enclosing packages.
@@ -105,8 +105,8 @@ Absolute classname can be passed, names ending with `.` are treated as packages
[[setting-server-classes]]
===== Setting Server Classes
-You can call the methods link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html#setServerClasses%28java.lang.String%5B%5D%29[org.eclipse.jetty.webapp.WebAppContext.setServerClasses(String Array)] or
-link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html#addServerClass(java.lang.String)[org.eclipse.jetty.webapp.WebAppContext.addServerClass(String)] to allow fine control over which classes are considered Server classes.
+You can call the methods link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html#setServerClasses%28java.lang.String%5B%5D%29[org.eclipse.jetty.ee9.webapp.WebAppContext.setServerClasses(String Array)] or
+link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html#addServerClass(java.lang.String)[org.eclipse.jetty.ee9.webapp.WebAppContext.addServerClass(String)] to allow fine control over which classes are considered Server classes.
* A web application cannot see a Server class.
* A WEB-INF class can replace a Server class.
@@ -120,9 +120,9 @@ The default server classes are:
|-org.eclipse.jetty.continuation. |Don't hide continuation classes.
|-org.eclipse.jetty.jndi. |Don't hide naming classes.
|-org.eclipse.jetty.jaas. |Don't hide jaas classes.
-|-org.eclipse.jetty.servlets. |Don't hide utility servlet classes if provided.
-|-org.eclipse.jetty.servlet.DefaultServlet |Don't hide default servlet.
-|-org.eclipse.jetty.servlet.listener. |Don't hide utility listeners
+|-org.eclipse.jetty.ee9.servlets. |Don't hide utility servlet classes if provided.
+|-org.eclipse.jetty.ee9.servlet.DefaultServlet |Don't hide default servlet.
+|-org.eclipse.jetty.ee9.servlet.listener. |Don't hide utility listeners
|-org.eclipse.jetty.websocket. |Don't hide websocket extension.
| org.eclipse.jetty. |Do hide all other Jetty classes.
|=======================================================================
@@ -145,12 +145,12 @@ You can place additional Jars here.
[[using-extra-classpath-method]]
===== Using the extraClasspath() method
-You can add an additional classpath to a context classloader by calling link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html#setExtraClasspath(java.lang.String)[org.eclipse.jetty.webapp.WebAppContext.setExtraClasspath(String)] with a comma-separated list of paths.
+You can add an additional classpath to a context classloader by calling link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html#setExtraClasspath(java.lang.String)[org.eclipse.jetty.ee9.webapp.WebAppContext.setExtraClasspath(String)] with a comma-separated list of paths.
You can do so directly to the API via a context XML file such as the following:
[source, xml, subs="{sub-order}"]
----
-
+
...
../my/classes,../my/jars/special.jar,../my/jars/other.jar
...
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/contexts/custom-error-pages.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/contexts/custom-error-pages.adoc
index e4ed161a3fc..95616785c53 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/contexts/custom-error-pages.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/contexts/custom-error-pages.adoc
@@ -74,7 +74,7 @@ Context files are normally located in `${jetty.base}/webapps/` (see `DeployerMan
-
+/test/webapps/test
@@ -114,8 +114,8 @@ Context files are normally located in `${jetty.base}/webapps/` (see `DeployerMan
==== Custom ErrorHandler class
-If no error page mapping is defined, or if the error page resource itself has an error, then the error page will be generated by an instance of `ErrorHandler` configured either the Context or the Server.
-An `ErrorHandler` may extend the `ErrorHandler` class and may totally replace the handle method to generate an error page, or it can implement some or all of the following methods to partially modify the error pages:
+If no error page mapping is defined, or if the error page resource itself has an error, then the error page will be generated by an instance of `ErrorProcessor` configured either the Context or the Server.
+An `ErrorProcessor` may extend the `ErrorProcessor` class and may totally replace the handle method to generate an error page, or it can implement some or all of the following methods to partially modify the error pages:
[source, java, subs="{sub-order}"]
----
@@ -128,7 +128,7 @@ void writeErrorPageMessage(HttpServletRequest request, Writer writer, int code,
void writeErrorPageStacks(HttpServletRequest request, Writer writer) throws IOException
----
-An `ErrorHandler` instance may be set on a Context by calling the `ContextHandler.setErrorHandler` method. This can be done by embedded code or via context IoC XML.
+An `ErrorProcessor` instance may be set on a Context by calling the `ContextHandler.setErrorHandler` method. This can be done by embedded code or via context IoC XML.
For example:
[source, xml, subs="{sub-order}"]
@@ -142,7 +142,7 @@ For example:
----
-An `ErrorHandler` instance may be set on the entire server by setting it as a dependent bean on the Server instance.
+An `ErrorProcessor` instance may be set on the entire server by setting it as a dependent bean on the Server instance.
This can be done by calling `Server.addBean(Object)` via embedded code or in `jetty.xml` IoC XML:
[source, xml, subs="{sub-order}"]
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/contexts/setting-context-path.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/contexts/setting-context-path.adoc
index b8e1967563b..1e78118fe85 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/contexts/setting-context-path.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/contexts/setting-context-path.adoc
@@ -42,7 +42,7 @@ For example:
[source, xml, subs="{sub-order}"]
----
-
+/test
...
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/contexts/setting-form-size.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/contexts/setting-form-size.adoc
index 3bb44ee25c6..072bdee408f 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/contexts/setting-form-size.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/contexts/setting-form-size.adoc
@@ -36,7 +36,7 @@ In either case the syntax of the XML file is the same:
[source,xml,subs="{sub-order}"]
----
-
+
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/contexts/temporary-directories.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/contexts/temporary-directories.adoc
index 0c85b607ced..da025dc2bf7 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/contexts/temporary-directories.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/contexts/temporary-directories.adoc
@@ -39,7 +39,7 @@ Once the temp directory is created, it is retrievable as the value (as a File) o
===== The location of the temp directory
By default, Jetty will create this directory inside the directory named by the `java.io.tmpdir` System property.
-You can instruct Jetty to use a different parent directory by setting the context attribute `org.eclipse.jetty.webapp.basetempdir` to the name of the desired parent directory.
+You can instruct Jetty to use a different parent directory by setting the context attribute `org.eclipse.jetty.ee9.webapp.basetempdir` to the name of the desired parent directory.
The directory named by this attribute _must_ exist and be __writeable__.
As usual with Jetty, you can either set this attribute in a context xml file, or you can do it in code.
@@ -48,13 +48,13 @@ Here's an example of setting it in an xml file:
[source, xml, subs="{sub-order}"]
----
-
+/testfoo.war
- org.eclipse.jetty.webapp.basetempdir
+ org.eclipse.jetty.ee9.webapp.basetempdir/home/my/foo
@@ -67,7 +67,7 @@ The equivalent in code is:
WebAppContext context = new WebAppContext();
context.setContextPath("/test");
context.setWar("foo.war");
-context.setAttribute("org.eclipse.jetty.webapp.basetempdir", "/tmp/foo");
+context.setAttribute("org.eclipse.jetty.ee9.webapp.basetempdir", "/tmp/foo");
----
==== Setting a Specific Temp Directory
@@ -80,7 +80,7 @@ Here is an example of setting the temp directory in XML:
[source, xml, subs="{sub-order}"]
----
-
+/testfoo.war
@@ -105,7 +105,7 @@ Again, you can do this in XML:
[source, xml, subs="{sub-order}"]
----
-
+/testfoo.war
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/deploying/configuring-specific-webapp-deployment.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/deploying/configuring-specific-webapp-deployment.adoc
index b1fd94de0af..13b7d92689a 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/deploying/configuring-specific-webapp-deployment.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/deploying/configuring-specific-webapp-deployment.adoc
@@ -43,7 +43,7 @@ For example, here is a descriptor file that deploys the file `/opt/myapp/myapp.w
-
+/wiki/opt/myapp/myapp.war
@@ -57,7 +57,7 @@ For example, if the system property is set to `myapp.home=/opt/myapp`, the previ
-
+/wiki/myapp.war
@@ -85,7 +85,7 @@ This can help make it clear that users should not make changes to the temporary
-
+/wiki/myapp.warfalse
@@ -101,7 +101,7 @@ However, since the `web.xml` for the web application is processed after the depl
-
+/wiki/myapp.war
@@ -122,7 +122,7 @@ This feature is useful when adding parameters or additional Servlet mappings wit
-
+/wiki/myapp.war/opt/myapp/overlay-web.xml
@@ -137,7 +137,7 @@ If the `web.xml` does not include a reference to this data source, an override d
-
+/wiki/myapp.war
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/deploying/deployment-architecture.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/deploying/deployment-architecture.adoc
index 19cb134d76c..349e4758219 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/deploying/deployment-architecture.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/deploying/deployment-architecture.adoc
@@ -76,11 +76,11 @@ The format for the XML file is the same as any context XML file and can be used
To use this binding, you can either modify the existing `jetty-deploy.xml` which comes with the Jetty distribution (be sure to link:#startup-base-and-home[copy it to your $JETTY_BASE/etc directory first]), or by link:#custom-modules[creating a new module] file which calls to an additional XML file.
-[source, xml, subs="{sub-order}"]
+[source,xml,subs="{sub-order}"]
----
-
+ /etc/global-webapp-config.xml
@@ -96,7 +96,7 @@ It supports hot (re)deployment.
The basic operation of the `WebAppProvider` is to periodically scan a directory for deployables.
In the standard Jetty Distribution, this is configured in the `${jetty.home}/etc/jetty-deploy.xml` file.
-[source, xml, subs="{sub-order}"]
+[source,xml,subs="{sub-order}"]
----
@@ -110,7 +110,7 @@ In the standard Jetty Distribution, this is configured in the `${jetty.home}/etc
-
+ /webapps/etc/webdefault.xml1
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/deploying/deployment-processing-webapps.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/deploying/deployment-processing-webapps.adoc
index fe7fbd87606..1a3b5536179 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/deploying/deployment-processing-webapps.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/deploying/deployment-processing-webapps.adoc
@@ -23,27 +23,27 @@ If instead you're looking for information on how to configure a specific `WebApp
[[webapp-configurations]]
==== Configuration Classes
-As a webapp is being deployed, a series of link:{JDURL}/org/eclipse/jetty/webapp/Configuration.html[org.eclipse.jetty.webapp.Configuration] classes are applied to it, each one performing a specific function.
+As a webapp is being deployed, a series of link:{JDURL}/org/eclipse/jetty/webapp/Configuration.html[org.eclipse.jetty.ee9.webapp.Configuration] classes are applied to it, each one performing a specific function.
The ordering of these Configurations is significant as subsequent Configurations tend to build on information extracted or setup in foregoing Configurations.
-These are the default list, in order, of Configurations that are applied to each link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html[org.eclipse.jetty.webapp.WebAppContex]t:
+These are the default list, in order, of Configurations that are applied to each link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html[org.eclipse.jetty.ee9.webapp.WebAppContex]t:
.Default Configuration classes
[cols=",",]
|=======================================================================
-|link:{JDURL}/org/eclipse/jetty/webapp/WebInfConfiguration.html[org.eclipse.jetty.webapp.WebInfConfiguration]
+|link:{JDURL}/org/eclipse/jetty/webapp/WebInfConfiguration.html[org.eclipse.jetty.ee9.webapp.WebInfConfiguration]
|Extracts war, orders jars and defines classpath
-|link:{JDURL}/org/eclipse/jetty/webapp/WebXmlConfiguration.html[org.eclipse.jetty.webapp.WebXmlConfiguration]
+|link:{JDURL}/org/eclipse/jetty/webapp/WebXmlConfiguration.html[org.eclipse.jetty.ee9.webapp.WebXmlConfiguration]
|Processes a WEB-INF/web.xml file
-|link:{JDURL}/org/eclipse/jetty/webapp/MetaInfConfiguration.html[org.eclipse.jetty.webapp.MetaInfConfiguration]
+|link:{JDURL}/org/eclipse/jetty/webapp/MetaInfConfiguration.html[org.eclipse.jetty.ee9.webapp.MetaInfConfiguration]
|Looks in container and webapp jars for META-INF/resources and
META-INF/web-fragment.xml
-|link:{JDURL}/org/eclipse/jetty/webapp/FragmentConfiguration.html[org.eclipse.jetty.webapp.FragmentConfiguration]
+|link:{JDURL}/org/eclipse/jetty/webapp/FragmentConfiguration.html[org.eclipse.jetty.ee9.webapp.FragmentConfiguration]
|Processes all discovered META-INF/web-fragment.xml files
-|link:{JDURL}/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.html[org.eclipse.jetty.webapp.JettyWebXmlConfiguration]
+|link:{JDURL}/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.html[org.eclipse.jetty.ee9.webapp.JettyWebXmlConfiguration]
|Processes a WEB-INF/jetty-web.xml file
|=======================================================================
@@ -99,7 +99,7 @@ To achieve that, we use 2 extra Configurations:
|Processes JNDI related aspects of `WEB-INF/web.xml` and hooks up naming entries
|=======================================================================
-These configurations must be added in _exactly_ the order shown above and should be inserted _immediately before_ the link:{JDURL}/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.html[org.eclipse.jetty.webapp.JettyWebXmlConfiguration] class in the list of configurations.
+These configurations must be added in _exactly_ the order shown above and should be inserted _immediately before_ the link:{JDURL}/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.html[org.eclipse.jetty.ee9.webapp.JettyWebXmlConfiguration] class in the list of configurations.
To fully support JNDI additional configuration is required, full details of which can be found link:#jndi[here].
====== Example: Annotation Configurations
@@ -114,7 +114,7 @@ We need just one extra Configuration class to help provide servlet annotation sc
@WebListener etc
|=======================================================================
-The above configuration class must be _inserted immediately before_ the link:{JDURL}/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.html[org.eclipse.jetty.webapp.JettyWebXmlConfiguration] class in the list of configurations.
+The above configuration class must be _inserted immediately before_ the link:{JDURL}/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.html[org.eclipse.jetty.ee9.webapp.JettyWebXmlConfiguration] class in the list of configurations.
To fully support annotations additional configuration is require, details of which can be found link:#webapp-context-attributes[below.]
===== How to Set the List of Configurations
@@ -132,20 +132,20 @@ Let's see an example of how we would add in the Configurations for both JNDI _an
-
+/webapps/my-cool-webapp
- org.eclipse.jetty.webapp.WebInfConfiguration
- org.eclipse.jetty.webapp.WebXmlConfiguration
- org.eclipse.jetty.webapp.MetaInfConfiguration
- org.eclipse.jetty.webapp.FragmentConfiguration
+ org.eclipse.jetty.ee9.webapp.WebInfConfiguration
+ org.eclipse.jetty.ee9.webapp.WebXmlConfiguration
+ org.eclipse.jetty.ee9.webapp.MetaInfConfiguration
+ org.eclipse.jetty.ee9.webapp.FragmentConfigurationorg.eclipse.jetty.plus.webapp.EnvConfigurationorg.eclipse.jetty.plus.webapp.PlusConfigurationorg.eclipse.jetty.annotations.AnnotationConfiguration
- org.eclipse.jetty.webapp.JettyWebXmlConfiguration
+ org.eclipse.jetty.ee9.webapp.JettyWebXmlConfiguration
@@ -159,7 +159,7 @@ Of course, you can also use this method to reduce the Configurations applied to
If you use the link:#deployment-architecture[deployer], you can set up the list of Configuration classes on the link:#default-web-app-provider[WebAppProvider].
They will then be applied to each `WebAppContext` deployed by the deployer:
-[source, xml, subs="{sub-order}"]
+[source,xml,subs="{sub-order}"]
----
@@ -174,18 +174,18 @@ They will then be applied to each `WebAppContext` deployed by the deployer:
-
+ /webapps
- org.eclipse.jetty.webapp.WebInfConfiguration
- org.eclipse.jetty.webapp.WebXmlConfiguration
- org.eclipse.jetty.webapp.MetaInfConfiguration
- org.eclipse.jetty.webapp.FragmentConfiguration
+ org.eclipse.jetty.ee9.webapp.WebInfConfiguration
+ org.eclipse.jetty.ee9.webapp.WebXmlConfiguration
+ org.eclipse.jetty.ee9.webapp.MetaInfConfiguration
+ org.eclipse.jetty.ee9.webapp.FragmentConfigurationorg.eclipse.jetty.plus.webapp.EnvConfigurationorg.eclipse.jetty.plus.webapp.PlusConfigurationorg.eclipse.jetty.annotations.AnnotationConfiguration
- org.eclipse.jetty.webapp.JettyWebXmlConfiguration
+ org.eclipse.jetty.ee9.webapp.JettyWebXmlConfiguration
@@ -213,10 +213,10 @@ This example uses an xml file, in fact it is the `$JETTY_HOME/etc/jetty-plus.xml
-
+
- org.eclipse.jetty.webapp.FragmentConfiguration
+ org.eclipse.jetty.ee9.webapp.FragmentConfigurationorg.eclipse.jetty.plus.webapp.EnvConfiguration
@@ -229,7 +229,7 @@ This example uses an xml file, in fact it is the `$JETTY_HOME/etc/jetty-plus.xml
----
-The link:{JDURL}/org/eclipse/jetty/webapp/Configuration.html[org.eclipse.jetty.webapp.Configuration.ClassList] class provides these methods for insertion:
+The link:{JDURL}/org/eclipse/jetty/webapp/Configuration.html[org.eclipse.jetty.ee9.webapp.Configuration.ClassList] class provides these methods for insertion:
addAfter::
Inserts the supplied list of `Configuration` class names after the given Configuration class name.
@@ -242,7 +242,7 @@ addBefore::
[[container-include-jar-pattern]]
===== org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern
-This is a link:#context_attributes[context attribute] that can be set on link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html[an org.eclipse.jetty.webapp.WebAppContext] to control which parts of the _container's_ classpath should be processed for things like annotations, `META-INF/resources`, `META-INF/web-fragment.xml` and `tlds` inside `META-INF`.
+This is a link:#context_attributes[context attribute] that can be set on link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html[an org.eclipse.jetty.ee9.webapp.WebAppContext] to control which parts of the _container's_ classpath should be processed for things like annotations, `META-INF/resources`, `META-INF/web-fragment.xml` and `tlds` inside `META-INF`.
Normally, nothing from the container classpath will be included for processing.
However, sometimes you will need to include some.
@@ -258,7 +258,7 @@ Here's an example from a context xml file (although as always, you could have ac
-
+org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern
@@ -284,7 +284,7 @@ Here's an example in a xml file of a pattern that matches any jar that starts wi
-
+org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/deploying/quickstart-webapp.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/deploying/quickstart-webapp.adoc
index d45c93f7276..180d5ffdb22 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/deploying/quickstart-webapp.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/deploying/quickstart-webapp.adoc
@@ -59,9 +59,9 @@ In a Maven project you add a dependency on the artifact `jetty-quickstart`.
===== Configuration
-Webapps need to be instances of link:{JDURL}/org/eclipse/jetty/quickstart/QuickStartWebApp.html[`org.eclipse.jetty.quickstart.QuickStartWebApp`] rather than the normal `org.eclipse.jetty.webapp.WebAppContext`.
+Webapps need to be instances of link:{JDURL}/org/eclipse/jetty/quickstart/QuickStartWebApp.html[`org.eclipse.jetty.quickstart.QuickStartWebApp`] rather than the normal `org.eclipse.jetty.ee9.webapp.WebAppContext`.
-`org.eclipse.jetty.quickstart.QuickStartWebApp` instances offer the same setters as the familiar `org.eclipse.jetty.webapp.WebAppContext`, with the addition of:
+`org.eclipse.jetty.quickstart.QuickStartWebApp` instances offer the same setters as the familiar `org.eclipse.jetty.ee9.webapp.WebAppContext`, with the addition of:
autoPreconfigure::
(true/false).
@@ -108,7 +108,7 @@ Otherwise, create a context xml file with the following information (in addition
====== In Code
-Create an instance of link:{JDURL}/org/eclipse/jetty/quickstart/QuickStartWebApp.html[`org.eclipse.jetty.quickstart.QuickStartWebApp`] rather than the normal `org.eclipse.jetty.webapp.WebAppContext`. You then use the QuickStartWebApp instance in exactly the same way that you would a WebAppContext.
+Create an instance of link:{JDURL}/org/eclipse/jetty/quickstart/QuickStartWebApp.html[`org.eclipse.jetty.quickstart.QuickStartWebApp`] rather than the normal `org.eclipse.jetty.ee9.webapp.WebAppContext`. You then use the QuickStartWebApp instance in exactly the same way that you would a WebAppContext.
Here's a snippet:
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/cgi-servlet.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/cgi-servlet.adoc
index e3bcb41b516..1dc3f359d5d 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/cgi-servlet.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/cgi-servlet.adoc
@@ -17,7 +17,7 @@
[[cgi-servlet-metadata]]
==== Info
-* Classname: `org.eclipse.jetty.servlets.CGI`
+* Classname: `org.eclipse.jetty.ee9.servlets.CGI`
* Maven Artifact: org.eclipse.jetty:jetty-servlets
* Javadoc: {JDURL}/org/eclipse/jetty/servlets/CGI.html
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/cross-origin-filter.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/cross-origin-filter.adoc
index 9be9657f778..2bd60159d20 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/cross-origin-filter.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/cross-origin-filter.adoc
@@ -17,7 +17,7 @@
[[cross-origin-filter-metadata]]
==== Info
-* Classname: `org.eclipse.jetty.servlets.CrossOriginFilter`
+* Classname: `org.eclipse.jetty.ee9.servlets.CrossOriginFilter`
* Maven Artifact: org.eclipse.jetty:jetty-servlets
* Javadoc: {JDURL}/org/eclipse/jetty/servlets/CrossOriginFilter.html
@@ -80,7 +80,7 @@ A typical configuration could be:
cross-origin
- org.eclipse.jetty.servlets.CrossOriginFilter
+ org.eclipse.jetty.ee9.servlets.CrossOriginFiltercross-origin
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/default-servlet.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/default-servlet.adoc
index 4cdf18602a1..5ba7ec0b4d0 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/default-servlet.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/default-servlet.adoc
@@ -17,7 +17,7 @@
[[default-servlet-metadata]]
==== Info
-* Classname: `org.eclipse.jetty.servlet.DefaultServlet`
+* Classname: `org.eclipse.jetty.ee9.servlet.DefaultServlet`
* Maven Artifact: org.eclipse.jetty:jetty-servlet
* Javadoc: {JDURL}/org/eclipse/jetty/servlet/DefaultServlet.html
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/dos-filter.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/dos-filter.adoc
index 7058841396f..cc2455f4d4a 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/dos-filter.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/dos-filter.adoc
@@ -17,7 +17,7 @@
[[dos-filter-metadata]]
==== Info
-* Classname: `org.eclipse.jetty.servlets.DoSFilter`
+* Classname: `org.eclipse.jetty.ee9.servlets.DoSFilter`
* Maven Artifact: org.eclipse.jetty:jetty-servlets
* Javadoc: {JDURL}/org/eclipse/jetty/servlets/DoSFilter.html
@@ -53,7 +53,7 @@ This example allow 30 requests at a time:
----
DoSFilter
- org.eclipse.jetty.servlets.DoSFilter
+ org.eclipse.jetty.ee9.servlets.DoSFiltermaxRequestsPerSec30
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/header-filter.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/header-filter.adoc
index f17ce6c1849..0e587382113 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/header-filter.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/header-filter.adoc
@@ -17,7 +17,7 @@
[[header-filter-metadata]]
==== Info
-* Classname: `org.eclipse.jetty.servlets.HeaderFilter`
+* Classname: `org.eclipse.jetty.ee9.servlets.HeaderFilter`
* Maven Artifact: org.eclipse.jetty:jetty-servlets
* Javadoc: {JDURL}/org/eclipse/jetty/servlets/HeaderFilter.html
@@ -54,7 +54,7 @@ ____
----
HeaderFilter
- org.eclipse.jetty.servlets.HeaderFilter
+ org.eclipse.jetty.ee9.servlets.HeaderFilterheaderConfig
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/qos-filter.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/qos-filter.adoc
index 857420490e6..c40a5b2b326 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/qos-filter.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/extras/qos-filter.adoc
@@ -17,7 +17,7 @@
[[qos-filter-metadata]]
==== Info
-* Classname: `org.eclipse.jetty.servlets.QoSFilter`
+* Classname: `org.eclipse.jetty.ee9.servlets.QoSFilter`
* Maven Artifact: org.eclipse.jetty:jetty-servlets
* Javadoc: {JDURL}/org/eclipse/jetty/servlets/QoSFilter.html
@@ -82,7 +82,7 @@ This example processes fifty requests at a time:
----
QoSFilter
- org.eclipse.jetty.servlets.QoSFilter
+ org.eclipse.jetty.ee9.servlets.QoSFiltermaxRequests50
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/fastcgi/configuring-fastcgi.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/fastcgi/configuring-fastcgi.adoc
index d0260b6af46..70d10757200 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/fastcgi/configuring-fastcgi.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/fastcgi/configuring-fastcgi.adoc
@@ -41,11 +41,11 @@ For FastCGI there is no web application that needs developed - all the work has
As such you only need to deploy a Jetty context XML file that configures the web application directly.
Copy and paste the following content as `$JETTY_BASE/webapps/jetty-wordpress.xml`:
-[source, xml, subs="{sub-order}"]
+[source,xml,subs="{sub-order}"]
----
-
+/var/www/wordpress
@@ -58,7 +58,7 @@ Copy and paste the following content as `$JETTY_BASE/webapps/jetty-wordpress.xml
- org.eclipse.jetty.fcgi.server.proxy.TryFilesFilter
+ org.eclipse.jetty.ee9.fcgi.server.proxy.TryFilesFilterorg.eclipse.jetty.ee9.fcgi.server.proxy.TryFilesFilter/*
@@ -73,11 +73,11 @@ Copy and paste the following content as `$JETTY_BASE/webapps/jetty-wordpress.xml
-
+ default
- org.eclipse.jetty.servlet.DefaultServlet
+ org.eclipse.jetty.ee9.servlet.DefaultServlet
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/frameworks/cdi.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/frameworks/cdi.adoc
index b25ff07f786..96cd3d17318 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/frameworks/cdi.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/frameworks/cdi.adoc
@@ -33,12 +33,12 @@ The Jetty distribution come with several CDI modules.
These modules do not provide CDI, but instead enable one of more integration mechanisms.
===== Jetty `cdi` Module
-The `cdi` module supports either two modes of CDI integration which can be selected either by the "org.eclipse.jetty.cdi" context init parameter or the "org.eclipse.jetty.cdi" server attribute (which is initialised from the "jetty.cdi.mode" start property).
+The `cdi` module supports either two modes of CDI integration which can be selected either by the "org.eclipse.jetty.ee9.cdi" context init parameter or the "org.eclipse.jetty.ee9.cdi" server attribute (which is initialised from the "jetty.cdi.mode" start property).
Supported modes are:
* `CdiSpiDecorator` Jetty will call the CDI SPI within the webapp to decorate objects (default).
- * `CdiDecoratingLister` The webapp may register a decorator on the context attribute "org.eclipse.jetty.cdi.decorator".
+ * `CdiDecoratingLister` The webapp may register a decorator on the context attribute "org.eclipse.jetty.ee9.cdi.decorator".
-------------------------
cd $JETTY_BASE
java -jar $JETTY_HOME/start.jar --add-to-start=cdi
@@ -74,7 +74,7 @@ This module is equivalent to directly modifying the class path configuration wit
-------------------------------------------------------------
-
+-org.eclipse.jetty.util.Decorator
@@ -88,7 +88,7 @@ This module is equivalent to directly modifying the class path configuration wit
-org.eclipse.jetty.server.handler.ContextHandler
- -org.eclipse.jetty.servlet.ServletContextHandler
+ -org.eclipse.jetty.ee9.servlet.ServletContextHandler
-------------------------------------------------------------
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/frameworks/osgi.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/frameworks/osgi.adoc
index e5cd9600c35..2b931c12444 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/frameworks/osgi.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/frameworks/osgi.adoc
@@ -115,7 +115,7 @@ Here's how you would specify it:
+
[source, plain, subs="{sub-order}"]
----
-jetty.home.bundle=org.eclipse.jetty.osgi.boot
+jetty.home.bundle=org.eclipse.jetty.ee9.osgi.boot
----
+
@@ -357,7 +357,7 @@ Here's an example of the contents of a `META-INF/jetty-webapp-context.xml` file:
-
+META-INF/webdefault.xml
----
@@ -440,7 +440,7 @@ include::{SRCDIR}/jetty-osgi/test-jetty-osgi-context/src/main/context/acme.xml[]
[[services-as-webapps]]
==== Deploying Services as Webapps
-In addition to listening for bundles whose format or `MANIFEST` entries define a webapp or `ContextHandler` for to be deployed, the Jetty OSGi container also listens for the registration of OSGi services that are instances of `org.eclipse.jetty.webapp.WebAppContext`.
+In addition to listening for bundles whose format or `MANIFEST` entries define a webapp or `ContextHandler` for to be deployed, the Jetty OSGi container also listens for the registration of OSGi services that are instances of `org.eclipse.jetty.ee9.webapp.WebAppContext`.
So you may programmatically create a `WebAppContext`, register it as a service, and have Jetty pick it up and deploy it.
Here's an example of doing that with a simple bundle that serves static content, and an `org.osgi.framework.BundleActivator` that instantiates the `WebAppContext`:
@@ -679,7 +679,7 @@ Here is the list of recommended jars (NOTE the version numbers may change in fut
|org.eclipse.jdt.core.compiler.batch |Distribution lib/apache-jsp
|org.eclipse.jetty.osgi:jetty-osgi-boot-jsp
-|org.eclipse.jetty.osgi.boot.jsp
+|org.eclipse.jetty.ee9.osgi.boot.jsp
|https://repo1.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-boot-jsp[Maven central]
|=======================================================================
@@ -748,15 +748,15 @@ The format of the *Require-TldBundle* header is a comma separated list of one or
Some TLD jars are required to be found on the Jetty OSGi container's classpath, rather than considered part of the web bundle's classpath.
For example, this is true of JSTL and Java Server Faces.
-The Jetty OSGi container takes care of JSTL for you, but you can control which other jars are considered as part of the container's classpath by using the System property **org.eclipse.jetty.osgi.tldbundles**:
+The Jetty OSGi container takes care of JSTL for you, but you can control which other jars are considered as part of the container's classpath by using the System property **org.eclipse.jetty.ee9.osgi.tldbundles**:
-org.eclipse.jetty.osgi.tldbundles::
+org.eclipse.jetty.ee9.osgi.tldbundles::
System property defined on the OSGi environment that is a comma separated list of symbolic names of bundles containing taglibs that will be treated as if they are on the container's classpath for web bundles.
For example:
+
[source, plain, subs="{sub-order}"]
----
-org.eclipse.jetty.osgi.tldbundles=com.acme.special.tags,com.foo.web,org.bar.web.framework
+org.eclipse.jetty.ee9.osgi.tldbundles=com.acme.special.tags,com.foo.web,org.bar.web.framework
----
+
You will still need to define the *Import-Bundle* header in the `MANIFEST` file for the web bundle to ensure that the TLD bundles are on the OSGi classpath.
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/gettingstarted/configuring/what-to-configure.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/gettingstarted/configuring/what-to-configure.adoc
index 410da188650..c3195a46c45 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/gettingstarted/configuring/what-to-configure.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/gettingstarted/configuring/what-to-configure.adoc
@@ -201,7 +201,7 @@ To set the contextPath from within the WAR file, you can include a `WEB-INF/jett
-
+/contextpath
----
@@ -214,7 +214,7 @@ Instead of allowing the WAR file to be discovered by the deployer, an IoC XML fi
-
+/webapps/test.war/test
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/gettingstarted/getting-started/jetty-running.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/gettingstarted/getting-started/jetty-running.adoc
index c1290ac09f1..f4b5230b1e5 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/gettingstarted/getting-started/jetty-running.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/gettingstarted/getting-started/jetty-running.adoc
@@ -69,9 +69,9 @@ $ cd demo-base/
2017-09-20 16:23:04.306:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@371a67ec{/async-rest,[file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-async-rest.war-_async-rest-any-5319296087878801290.dir/webapp/, jar:file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-async-rest.war-_async-rest-any-5319296087878801290.dir/webapp/WEB-INF/lib/example-async-rest-jar-{VERSION}.jar!/META-INF/resources],AVAILABLE}{/async-rest.war}
2017-09-20 16:23:04.429:INFO:oeja.AnnotationConfiguration:main: Scanning elapsed time=53ms
2017-09-20 16:23:04.432:WARN::main: test webapp is deployed. DO NOT USE IN PRODUCTION!
-2017-09-20 16:23:04.511:INFO:oejsh.ManagedAttributeListener:main: update PushFilter null->org.eclipse.jetty.servlets.PushCacheFilter@2362f559 on o.e.j.w.WebAppContext@35e2d654{/test,file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test.war-_test-any-6279588879522983394.dir/webapp/,STARTING}{/test.war}
-2017-09-20 16:23:04.516:INFO:oejsh.ManagedAttributeListener:main: update QoSFilter null->org.eclipse.jetty.servlets.QoSFilter@7770f470 on o.e.j.w.WebAppContext@35e2d654{/test,file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test.war-_test-any-6279588879522983394.dir/webapp/,STARTING}{/test.war}
-2017-09-20 16:23:04.519:WARN:oeju.DeprecationWarning:main: Using @Deprecated Class org.eclipse.jetty.servlets.MultiPartFilter
+2017-09-20 16:23:04.511:INFO:oejsh.ManagedAttributeListener:main: update PushFilter null->org.eclipse.jetty.ee9.servlets.PushCacheFilter@2362f559 on o.e.j.w.WebAppContext@35e2d654{/test,file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test.war-_test-any-6279588879522983394.dir/webapp/,STARTING}{/test.war}
+2017-09-20 16:23:04.516:INFO:oejsh.ManagedAttributeListener:main: update QoSFilter null->org.eclipse.jetty.ee9.servlets.QoSFilter@7770f470 on o.e.j.w.WebAppContext@35e2d654{/test,file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test.war-_test-any-6279588879522983394.dir/webapp/,STARTING}{/test.war}
+2017-09-20 16:23:04.519:WARN:oeju.DeprecationWarning:main: Using @Deprecated Class org.eclipse.jetty.ee9.servlets.MultiPartFilter
2017-09-20 16:23:04.549:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@35e2d654{/test,file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test.war-_test-any-6279588879522983394.dir/webapp/,AVAILABLE}{/test.war}
2017-09-20 16:23:04.646:INFO:oeja.AnnotationConfiguration:main: Scanning elapsed time=12ms
2017-09-20 16:23:04.649:WARN::main: test-jndi webapp is deployed. DO NOT USE IN PRODUCTION!
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/http2/configuring-push.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/http2/configuring-push.adoc
index 4768aefaece..4280d753d8c 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/http2/configuring-push.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/http2/configuring-push.adoc
@@ -32,7 +32,7 @@ HTTP/2 Push can be automated in your application by configuring a link:{JDURL}/o
...
PushFilter
- org.eclipse.jetty.servlets.PushCacheFilter
+ org.eclipse.jetty.ee9.servlets.PushCacheFiltertrue
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/jetty-xml/jetty-env-xml.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/jetty-xml/jetty-env-xml.adoc
index 5254aa3a423..f9b857fdd8f 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/jetty-xml/jetty-env-xml.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/jetty-xml/jetty-env-xml.adoc
@@ -23,7 +23,7 @@ You define global naming resources on the server via `jetty.xml`.
[[jetty-env-root-element]]
==== jetty-env.xml Root Element
-Jetty applies `jetty-env.xml` on a per-webapp basis, and configures an instance of `org.eclipse.jetty.webapp.WebAppContext.`
+Jetty applies `jetty-env.xml` on a per-webapp basis, and configures an instance of `org.eclipse.jetty.ee9.webapp.WebAppContext.`
[source, xml, subs="{sub-order}"]
----
@@ -31,7 +31,7 @@ Jetty applies `jetty-env.xml` on a per-webapp basis, and configures an instance
-
+
..
@@ -54,7 +54,7 @@ Place the `jetty-env.xml` file in your web application's WEB-INF folder.
-
+
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/jetty-xml/jetty-web-xml-config.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/jetty-xml/jetty-web-xml-config.adoc
index 63a9b21ddab..683a521e917 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/jetty-xml/jetty-web-xml-config.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/jetty-xml/jetty-web-xml-config.adoc
@@ -23,14 +23,14 @@ For a more in-depth look at the syntax, see xref:jetty-xml-syntax[].
[[root-element-jetty-web-xml]]
==== Root Element
-`jetty-web.xml` applies on a per-webapp basis, and configures an instance of `org.eclipse.jetty.webapp.WebAppContext`.
+`jetty-web.xml` applies on a per-webapp basis, and configures an instance of `org.eclipse.jetty.ee9.webapp.WebAppContext`.
[source, xml, subs="{sub-order}"]
----
-
+
..
----
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/jetty-xml/override-web-xml.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/jetty-xml/override-web-xml.adoc
index 726a90f91ff..407c313a990 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/jetty-xml/override-web-xml.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/jetty-xml/override-web-xml.adoc
@@ -31,7 +31,7 @@ For example, if you had a webapp named MyApp, you would place a deployable xml f
[source, xml, subs="{sub-order}"]
----
-
+
...
@@ -44,7 +44,7 @@ The equivalent in code is:
[source, java, subs="{sub-order}"]
----
-import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.ee9.webapp.WebAppContext;
...
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/jetty-xml/webdefault-xml.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/jetty-xml/webdefault-xml.adoc
index 78b8f8d1474..c0d2f613102 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/jetty-xml/webdefault-xml.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/jetty-xml/webdefault-xml.adoc
@@ -57,7 +57,7 @@ You can specify a custom `webdefault.xml` for an individual web application in t
[source, xml, subs="{sub-order}"]
----
-
+
...
/my/path/to/webdefault.xml
@@ -72,7 +72,7 @@ The equivalent in code is:
[source, java, subs="{sub-order}"]
----
-import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.ee9.webapp.WebAppContext;
...
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/jndi/jndi-configuration.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/jndi/jndi-configuration.adoc
index 53df5dacf95..11f6c6e4303 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/jndi/jndi-configuration.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/jndi/jndi-configuration.adoc
@@ -100,7 +100,7 @@ This example configures it as scoped to a web app with the id of __wac__:
[source, xml, subs="{sub-order}"]
----
-
+jdbc/myds
@@ -164,7 +164,7 @@ Here is an example of binding an http://activemq.apache.org[ActiveMQ] in-JVM con
[source, xml, subs="{sub-order}"]
----
-
+jms/connectionFactory
@@ -197,7 +197,7 @@ Jetty also provides infrastructure for access to `javax.mail.Sessions` from with
[source, xml, subs="{sub-order}"]
----
-
+mail/Session
@@ -259,7 +259,7 @@ In a context xml file:
[source, xml, subs="{sub-order}"]
----
-
+jdbc/mydatasource
@@ -295,7 +295,7 @@ In a context xml file declare `jdbc/mydatasource`:
[source, xml, subs="{sub-order}"]
----
-
+jdbc/mydatasource
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/jndi/jndi-embedded.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/jndi/jndi-embedded.adoc
index ab2d8908c29..6a9e5c9e6b1 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/jndi/jndi-embedded.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/jndi/jndi-embedded.adoc
@@ -38,7 +38,7 @@ We'll use some mocked up classes for the transaction manager and the DataSource
----
import java.util.Properties;
import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.ee9.webapp.WebAppContext;
/**
* ServerWithJNDI
@@ -54,8 +54,8 @@ public class ServerWithJNDI
Server server = new Server(8080);
//Enable parsing of jndi-related parts of web.xml and jetty-env.xml
- org.eclipse.jetty.webapp.Configuration.ClassList classlist = org.eclipse.jetty.webapp.Configuration.ClassList.setServerDefault(server);
- classlist.addAfter("org.eclipse.jetty.webapp.FragmentConfiguration", "org.eclipse.jetty.plus.webapp.EnvConfiguration", "org.eclipse.jetty.plus.webapp.PlusConfiguration");
+ org.eclipse.jetty.ee9.webapp.Configuration.ClassList classlist = org.eclipse.jetty.ee9.webapp.Configuration.ClassList.setServerDefault(server);
+ classlist.addAfter("org.eclipse.jetty.ee9.webapp.FragmentConfiguration", "org.eclipse.jetty.plus.webapp.EnvConfiguration", "org.eclipse.jetty.plus.webapp.PlusConfiguration");
//Create a WebApp
WebAppContext webapp = new WebAppContext();
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/jndi/using-jndi.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/jndi/using-jndi.adoc
index b67c9eed4c4..cf6977c8737 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/jndi/using-jndi.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/jndi/using-jndi.adoc
@@ -125,7 +125,7 @@ For example:
+
[source, xml, subs="{sub-order}"]
----
-
+jms/connectionFactory
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/jsp/configuring-jsp.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/jsp/configuring-jsp.adoc
index 610606984e0..e5bf14d6e4c 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/jsp/configuring-jsp.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/jsp/configuring-jsp.adoc
@@ -52,14 +52,14 @@ Alternatively, you can manually wire in the appropriate ServletContainerInitiali
You can either follow the instructions on precompilation provided by Apache, or if you are using Maven for your builds, you can use the link:#jetty-jspc-maven-plugin[jetty-jspc-maven] plugin to do it for you.
If you have precompiled your JSPs, and have customized the output package prefix (which is `org.apache.jsp` by default), you should configure your webapp context to tell Jetty about this custom package name.
-You can do this using a servlet context init-param called `org.eclipse.jetty.servlet.jspPackagePrefix`.
+You can do this using a servlet context init-param called `org.eclipse.jetty.ee9.servlet.jspPackagePrefix`.
For example, suppose you have precompiled your JSPs with the custom package prefix of `com.acme`, then you would add the following lines to your `web.xml` file:
[source, xml, subs="{sub-order}"]
----
- org.eclipse.jetty.servlet.jspPackagePrefix
+ org.eclipse.jetty.ee9.servlet.jspPackagePrefixcom.acme
----
@@ -206,7 +206,7 @@ If you are using the Jetty distribution, and you want to change the JSP settings
[source, xml, subs="{sub-order}"]
----
-
+ /foo/webapps/foobar.war/home/smith/dev/webdefault.xml
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/runner/jetty-runner.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/runner/jetty-runner.adoc
index 60e8d41d291..245cddbd9de 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/runner/jetty-runner.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/runner/jetty-runner.adoc
@@ -60,11 +60,11 @@ By default, `jetty-runner` implements all Configuration Classes so that users ca
If you wish to only implement certain Configuration Classes, they will need to be defined in the context xml for the webapp/context.
The default Configuration Classes are:
-`org.eclipse.jetty.webapp.WebInfConfiguration`
-`org.eclipse.jetty.webapp.WebXmlConfiguration`
-`org.eclipse.jetty.webapp.MetaInfConfiguration`
-`org.eclipse.jetty.webapp.FragmentConfiguration`
-`org.eclipse.jetty.webapp.JettyWebXmlConfiguration`
+`org.eclipse.jetty.ee9.webapp.WebInfConfiguration`
+`org.eclipse.jetty.ee9.webapp.WebXmlConfiguration`
+`org.eclipse.jetty.ee9.webapp.MetaInfConfiguration`
+`org.eclipse.jetty.ee9.webapp.FragmentConfiguration`
+`org.eclipse.jetty.ee9.webapp.JettyWebXmlConfiguration`
`org.eclipse.jetty.plus.webapp.EnvConfiguration`
`org.eclipse.jetty.plus.webapp.PlusConfiguration`
`org.eclipse.jetty.annotations.AnnotationConfiguration`
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/security/authentication.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/security/authentication.adoc
index 8139c8d4818..64dde19ae00 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/security/authentication.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/security/authentication.adoc
@@ -149,7 +149,7 @@ Here's an example of doing both of these, using a link:#deployable-descriptor-fi
[source, xml, subs="{sub-order}"]
----
-
+
@@ -174,7 +174,7 @@ Here's how to define the same HashLoginService, but inside a link:#deployable-de
[source, xml, subs="{sub-order}"]
----
-
+/test/webapps/test
@@ -467,7 +467,7 @@ In the example below, a `HashLoginService` is defined with authorization being g
[source, xml, subs="{sub-order}"]
----
-
+Test RealmBASIC
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/security/configuring-form-size.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/security/configuring-form-size.adoc
index 242d979c357..1da8a847816 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/security/configuring-form-size.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/security/configuring-form-size.adoc
@@ -36,7 +36,7 @@ These methods may be called directly when embedding Jetty, but more commonly are
[source, xml, subs="{sub-order}"]
----
-
+
...
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/security/jaas-support.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/security/jaas-support.adoc
index 3779c694211..603ba99794c 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/security/jaas-support.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/security/jaas-support.adoc
@@ -101,7 +101,7 @@ An example:
+
[source, xml, subs="{sub-order}"]
----
-
+
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/troubleshooting/troubleshooting-locked-files.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/troubleshooting/troubleshooting-locked-files.adoc
index a9816dfade4..427feadca01 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/troubleshooting/troubleshooting-locked-files.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/troubleshooting/troubleshooting-locked-files.adoc
@@ -49,7 +49,7 @@ Add the following to your context xml file:
[source, xml, subs="{sub-order}"]
----
- org.eclipse.jetty.servlet.Default.useFileMappedBuffer
+ org.eclipse.jetty.ee9.servlet.Default.useFileMappedBufferfalse
----
@@ -63,7 +63,7 @@ Add the following to the plugin's configuration under the `` element:
[source, xml, subs="{sub-order}"]
----
<_initParams>
- false
+ false
----
@@ -77,7 +77,7 @@ Configure this in an xml file like so:
[source, xml, subs="{sub-order}"]
----
-
+/./webapps/fredapptrue
diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/websockets/jetty/jetty-websocket-server-api.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/websockets/jetty/jetty-websocket-server-api.adoc
index d21985fe6f2..d13e31bcf9b 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/websockets/jetty/jetty-websocket-server-api.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/websockets/jetty/jetty-websocket-server-api.adoc
@@ -73,4 +73,4 @@ Other uses for a `JettyWebSocketCreator`:
* Obtaining the Servlet HttpSession object (if it exists)
* Specifying a response status code and reason
-If you don't want to accept the upgrade, simply return null from the link:{JDURL}/org/eclipse/jetty/websocket/servlet/JettyWebSocketCreator.html#createWebSocket(org.eclipse.jetty.websocket.api.UpgradeRequest,org.eclipse.jetty.websocket.api.UpgradeResponse)[`JettyWebSocketCreator.createWebSocket(UpgradeRequest req, UpgradeResponse resp)`] method.
+If you don't want to accept the upgrade, simply return null from the link:{JDURL}/org/eclipse/jetty/websocket/servlet/JettyWebSocketCreator.html#createWebSocket(org.eclipse.jetty.ee9.websocket.api.UpgradeRequest,org.eclipse.jetty.ee9.websocket.api.UpgradeResponse)[`JettyWebSocketCreator.createWebSocket(UpgradeRequest req, UpgradeResponse resp)`] method.
diff --git a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/annotations/chapter.adoc b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/annotations/chapter.adoc
index 45404597423..ce55492f206 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/annotations/chapter.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/annotations/chapter.adoc
@@ -50,7 +50,7 @@ Here's an example context xml file that calls this method:
- <1>
+ <1>
false <2>
----
@@ -78,7 +78,7 @@ Here's an example from a context xml file that includes any jar whose name start
- <1>
+ <1>
<2>
org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern <3>
.*/foo-[^/]*\.jar$|.*/bar-[^/]*\.jar$|.*/classes/.* <4>
@@ -108,7 +108,7 @@ Here's an example of a context xml file that sets a pattern that matches any jar
- <1>
+ <1>
<2>
org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern <3>
.*/spring-[^/]*\.jar$ <4>
@@ -174,7 +174,7 @@ Here's an example of setting the context attribute in a context xml file:
- <1>
+ <1>
<2>
org.eclipse.jetty.containerInitializerExclusionPattern <3>
com.acme.*|com.corp.SlowContainerInitializer <4>
@@ -205,7 +205,7 @@ Here is an example context xml file that ensures the `com.example.PrioritySCI` w
- <1>
+ <1>
<2>
org.eclipse.jetty.containerInitializerOrder <3>
org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer, com.acme.FooSCI, * <4>
diff --git a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/begin/deploy.adoc b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/begin/deploy.adoc
index f622c9fe55c..ed20e96c220 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/begin/deploy.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/begin/deploy.adoc
@@ -42,7 +42,7 @@ mywebapp.war
<1> Publicly accessible resources such as `+*.html+`, `+*.jsp+`, `+*.css+`, `+*.js+` files, etc. are placed in `+*.war+` or in sub-directories of the `+*.war+`.
<2> `WEB-INF` is a special directory used to store anything related to the web application that must not be publicly accessible, but may be accessed by other resources.
<3> `WEB-INF/classes` stores the web application compiled `+*.class+` files
-<4> `WEB-INF/lib` stores the web application `+*.jar+` files
+<4> `WEB-INF/classes` stores the web application `+*.jar+` files
<5> `WEB-INF/web.xml` is the web application deployment descriptor defines the components and the configuration of your web application.
====
diff --git a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-extract-war.adoc b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-extract-war.adoc
index d1cf9f3fa4f..38b8794a9d4 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-extract-war.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-extract-war.adoc
@@ -26,7 +26,7 @@ If you do not want Jetty to extract the `+*.war+` files, you can disable this fe
-
+/mywebapp/opt/webapps/mywebapp.warfalse
diff --git a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-jetty.adoc b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-jetty.adoc
index 1b129a68172..bbb4f0e11fb 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-jetty.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-jetty.adoc
@@ -28,7 +28,7 @@ A simple Jetty context XML file, for example named `wiki.xml` is the following:
- <1>
+ <1>
/wiki <2>
/opt/myapps/myapp.war <3>
@@ -62,7 +62,7 @@ You can use the features of xref:og-xml[Jetty XML files] to avoid to hard-code f
-
+/wiki/myapp.war
diff --git a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-jndi.adoc b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-jndi.adoc
index 469db12af2d..989bd427a99 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-jndi.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-jndi.adoc
@@ -23,7 +23,7 @@ The JNDI entry must be _defined_ in a xref:og-jndi-xml[Jetty XML file], for exam
-
+/mywebapp/opt/webapps/mywebapp.war
#
diff --git a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-override-webxml.adoc b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-override-webxml.adoc
index d8d234b0dc0..23f40f4b1dd 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-override-webxml.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-override-webxml.adoc
@@ -24,7 +24,7 @@ This allows you to add host specific configuration or server specific configurat
-
+/mywebapp/opt/webapps/mywebapp.war/opt/webapps/mywebapp-web.xml
diff --git a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-virtual-hosts.adoc b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-virtual-hosts.adoc
index 6c1a66f84b6..c3bcf340cbb 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-virtual-hosts.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/deploy/deploy-virtual-hosts.adoc
@@ -58,7 +58,7 @@ If you have a web application `mywebapp.war` you can configure its virtual hosts
-
+/mywebapp/opt/webapps/mywebapp.war
@@ -103,7 +103,7 @@ To achieve this, you simply use the same context path of `/` for each of your we
-
+//opt/webapps/domain.war
@@ -120,7 +120,7 @@ To achieve this, you simply use the same context path of `/` for each of your we
-
+//opt/webapps/hobby.war
@@ -148,7 +148,7 @@ In this case, you want to xref:og-protocols[configure multiple connectors], each
-
+//opt/webapps/domain.war
@@ -165,7 +165,7 @@ In this case, you want to xref:og-protocols[configure multiple connectors], each
-
+//opt/webapps/hobby.war
diff --git a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jaas/chapter.adoc b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jaas/chapter.adoc
index 6a748a98a33..f7bde4aaa8d 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jaas/chapter.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jaas/chapter.adoc
@@ -115,7 +115,7 @@ Here's an example of this type of XML file:
----
-
+
diff --git a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jndi/chapter.adoc b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jndi/chapter.adoc
index b13dfa2b276..8fe02e965f0 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jndi/chapter.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jndi/chapter.adoc
@@ -120,7 +120,7 @@ In this example, we'll configure a link:http://db.apache.org/derby[Derby] DataSo
[source,xml,subs=verbatim]
----
-
+jdbc/myds
@@ -166,7 +166,7 @@ Here is an example of binding an link:http://activemq.apache.org[ActiveMQ] in-JV
[source,xml,subs=verbatim]
----
-
+jms/connectionFactory
@@ -202,7 +202,7 @@ To configure access to `javax.mail.Session` from within a webapp, declare an `or
[source,xml,subs=verbatim]
----
-
+mail/Session
@@ -277,7 +277,7 @@ The context XML file declares `jdbc/workforce`:
[source,xml,subs=verbatim]
----
-
+jdbc/workforce
@@ -374,7 +374,7 @@ For example:
<1> We refer to the id `Server` which identifies the default `org.eclipse.jetty.server.Server` instance.
*Webapp scope:*
-The name is unique to the `org.eclipse.jetty.webapp.WebAppContext` instance, and is only visible to that application.
+The name is unique to the `org.eclipse.jetty.ee9.webapp.WebAppContext` instance, and is only visible to that application.
This scope is represented by referencing the instance as the first parameter to the resource declaration.
For example:
[source,xml,subs=verbatim]
@@ -389,4 +389,4 @@ For example:
----
-<1> We refer to an instance of an `org.eclipse.jetty.webapp.WebAppContext` which has been previously defined.
+<1> We refer to an instance of an `org.eclipse.jetty.ee9.webapp.WebAppContext` which has been previously defined.
diff --git a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jsp/chapter.adoc b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jsp/chapter.adoc
index bccda278906..993d39c71d5 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jsp/chapter.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jsp/chapter.adoc
@@ -197,7 +197,7 @@ Here's an example of using a context xml file to add in a pattern to match files
-
+org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern.*/jetty-servlet-api-[^/]*\.jar$|.*/javax.servlet.jsp.jstl-.*\.jar$|.*/org.apache.taglibs.taglibs-standard-impl-.*\.jar$|.*/jsf-[^/]*\.jar$
diff --git a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/sessions/session-xml.adoc b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/sessions/session-xml.adoc
index 759a6f982af..f47de2b9482 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/sessions/session-xml.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/sessions/session-xml.adoc
@@ -22,7 +22,7 @@ Below is an example of how you could configure a the xref:og-session-filesystem[
[source,xml]
----
-
+
diff --git a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/xml/xml-syntax.adoc b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/xml/xml-syntax.adoc
index fe2e097f838..f5f6121475b 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/xml/xml-syntax.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/xml/xml-syntax.adoc
@@ -351,7 +351,7 @@ For example, you may want to configure the context path of your web application
-
+
##
diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/http/client-http-transport.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/http/client-http-transport.adoc
index 91cf621ec8c..c3baee55716 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/http/client-http-transport.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/http/client-http-transport.adoc
@@ -156,12 +156,9 @@ The dynamic transport, however, has been implemented to support multiple transpo
include::../../{doc_code}/org/eclipse/jetty/docs/programming/client/http/HTTPClientDocs.java[tag=dynamicH1H2]
----
-NOTE: The order in which the protocols are specified to `HttpClientTransportDynamic` indicates what is the client preference.
-
-IMPORTANT: When using TLS (i.e. URIs with the `https` scheme), the application protocol is _negotiated_ between client and server via ALPN, and it is the server that decides what is the application protocol to use for the communication, regardless of the client preference.
-
-When clear-text communication is used (i.e. URIs with the `http` scheme) there is no application protocol negotiation, and therefore the application must know _a priori_ whether the server supports the protocol or not.
-For example, if the server only supports clear-text HTTP/2, and `HttpClientTransportDynamic` is configured as in the example above, the client will send, by default, a clear-text HTTP/1.1 request to a clear-text HTTP/2 only server, which will result in a communication failure.
+IMPORTANT: The order in which the protocols are specified to `HttpClientTransportDynamic` indicates what is the client preference.
+If the protocol is negotiated via ALPN, it is the server that decides what is the protocol to use for the communication, regardless of the client preference.
+If the protocol is not negotiated, the client preference is honored.
Provided that the server supports both HTTP/1.1 and HTTP/2 clear-text, client applications can explicitly hint the version they want to use:
@@ -170,13 +167,13 @@ Provided that the server supports both HTTP/1.1 and HTTP/2 clear-text, client ap
include::../../{doc_code}/org/eclipse/jetty/docs/programming/client/http/HTTPClientDocs.java[tag=dynamicClearText]
----
-In case of TLS encrypted communication using the `https` scheme, things are a little more complicated.
+In case of TLS encrypted communication using the HTTPS scheme, things are a little more complicated.
-If the client application explicitly specifies the HTTP version, then ALPN is not used by the client.
+If the client application explicitly specifies the HTTP version, then ALPN is not used on the client.
By specifying the HTTP version explicitly, the client application has prior-knowledge of what HTTP version the server supports, and therefore ALPN is not needed.
If the server does not support the HTTP version chosen by the client, then the communication will fail.
-If the client application does not explicitly specify the HTTP version, then ALPN will be used by the client.
+If the client application does not explicitly specify the HTTP version, then ALPN will be used on the client.
If the server also supports ALPN, then the protocol will be negotiated via ALPN and the server will choose the protocol to use.
If the server does not support ALPN, the client will try to use the first protocol configured in `HttpClientTransportDynamic`, and the communication may succeed or fail depending on whether the server supports the protocol chosen by the client.
diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/websocket/client-websocket.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/websocket/client-websocket.adoc
index af95fd0b4d6..cc2a5291af3 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/websocket/client-websocket.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/websocket/client-websocket.adoc
@@ -35,7 +35,7 @@ The Maven artifact coordinates are the following:
[[pg-client-websocket-start]]
==== Starting WebSocketClient
-The main class is `org.eclipse.jetty.websocket.client.WebSocketClient`; you instantiate it, configure it, and then start it like may other Jetty components.
+The main class is `org.eclipse.jetty.ee9.websocket.client.WebSocketClient`; you instantiate it, configure it, and then start it like may other Jetty components.
This is a minimal example:
[source,java,indent=0]
@@ -119,7 +119,7 @@ In code:
include::../../{doc_code}/org/eclipse/jetty/docs/programming/client/websocket/WebSocketClientDocs.java[tags=connectHTTP11]
----
-`WebSocketClient.connect()` links the client-side WebSocket _endpoint_ to a specific server URI, and returns a `CompletableFuture` of an `org.eclipse.jetty.websocket.api.Session`.
+`WebSocketClient.connect()` links the client-side WebSocket _endpoint_ to a specific server URI, and returns a `CompletableFuture` of an `org.eclipse.jetty.ee9.websocket.api.Session`.
The endpoint offers APIs to _receive_ WebSocket data (or errors) from the server, while the session offers APIs to _send_ WebSocket data to the server.
diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/maven/jetty-maven-plugin.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/maven/jetty-maven-plugin.adoc
index e8621cda731..84a1ec58051 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/maven/jetty-maven-plugin.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/maven/jetty-maven-plugin.adoc
@@ -338,7 +338,7 @@ Here is an example, which turns on scanning for changes every ten seconds, and s
===== Configuration
webApp::
-This is an instance of link:{javadoc-url}/org/eclipse/jetty/maven/plugin/MavenWebAppContext.html[org.eclipse.jetty.maven.plugin.MavenWebAppContext], which is an extension to the class link:{javadoc-url}/org/eclipse/jetty/webapp/WebAppContext.hml[`org.eclipse.jetty.webapp.WebAppContext`].
+This is an instance of link:{javadoc-url}/org/eclipse/jetty/maven/plugin/MavenWebAppContext.html[org.eclipse.jetty.maven.plugin.MavenWebAppContext], which is an extension to the class link:{javadoc-url}/org/eclipse/jetty/webapp/WebAppContext.hml[`org.eclipse.jetty.ee9.webapp.WebAppContext`].
You can use any of the setter methods on this object to configure your webapp.
Here are a few of the most useful ones:
+
@@ -565,7 +565,7 @@ This goal will generate output from jetty into the `target/jetty-start.out` file
These configuration parameters are available:
webApp::
-This is an instance of link:{javadoc-url}/org/eclipse/jetty/maven/plugin/MavenWebAppContext.html[org.eclipse.jetty.maven.plugin.MavenWebAppContext], which is an extension to the class link:{javadoc-url}/org/eclipse/jetty/webapp/WebAppContext.hml[`org.eclipse.jetty.webapp.WebAppContext`].
+This is an instance of link:{javadoc-url}/org/eclipse/jetty/maven/plugin/MavenWebAppContext.html[org.eclipse.jetty.maven.plugin.MavenWebAppContext], which is an extension to the class link:{javadoc-url}/org/eclipse/jetty/webapp/WebAppContext.hml[`org.eclipse.jetty.ee9.webapp.WebAppContext`].
You can use any of the setter methods on this object to configure your webapp.
Here are a few of the most useful ones:
+
@@ -1032,7 +1032,7 @@ Putting the configuration in webapp A's `pom.xml`:
[IMPORTANT]
====
-If the `ContextHandler` you are deploying is a webapp, it is *essential* that you use an `org.eclipse.jetty.maven.plugin.MavenWebAppContext` instance rather than a standard `org.eclipse.jetty.webapp.WebAppContext` instance.
+If the `ContextHandler` you are deploying is a webapp, it is *essential* that you use an `org.eclipse.jetty.maven.plugin.MavenWebAppContext` instance rather than a standard `org.eclipse.jetty.ee9.webapp.WebAppContext` instance.
Only the former will allow the webapp to function correctly in the maven environment.
====
diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http-handler-use.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http-handler-use.adoc
index f29dafcedcc..a3df908ba12 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http-handler-use.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http-handler-use.adoc
@@ -383,7 +383,7 @@ Web applications cannot downcast Servlet's `HttpServletRequest` to Jetty's `Requ
Lastly, the Servlet specification requires that other classes, also called _system classes_, such as `javax.servlet.http.HttpServletRequest` or JDK classes such as `java.lang.String` or `java.sql.Connection` cannot be modified by web applications by putting, for example, modified versions of those classes in `WEB-INF/classes` so that they are loaded first by the web application class loader (instead of the class-path class loader where they are normally loaded from).
-`WebAppContext` implements this class loader logic using a single class loader, `org.eclipse.jetty.webapp.WebAppClassLoader`, with filtering capabilities: when it loads a class, it checks whether the class is a _system class_ or a _server class_ and acts according to the Servlet specification.
+`WebAppContext` implements this class loader logic using a single class loader, `org.eclipse.jetty.ee9.webapp.WebAppClassLoader`, with filtering capabilities: when it loads a class, it checks whether the class is a _system class_ or a _server class_ and acts according to the Servlet specification.
When `WebAppClassLoader` is asked to load a class, it first tries to find the class locally (since it must use the inverted child-first model); if the class is found, and it is not a _system class_, the class is loaded; otherwise the class is not found locally.
If the class is not found locally, the parent class loader is asked to load the class; the parent class loader uses the standard parent-first model, so it delegates the class loading to its parent, and so on.
diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http.adoc
index 6b37f3b2368..24d4e51c662 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http.adoc
@@ -110,23 +110,23 @@ This event is converted to a call to `AbstractConnection.onFillable()`, where th
The parser emit events that are protocol specific; the HTTP/2 parser, for example, emits events for each HTTP/2 frame that has been parsed, and similarly does the HTTP/3 parser.
The parser events are then converted to protocol independent events such as _"request start"_, _"request headers"_, _"request content chunk"_, etc.
-that in turn are converted into method calls to `HttpChannel`.
+that in turn are converted into method calls to `HttpChannelState`.
When enough of the HTTP request is arrived, the `Connection` calls `HttpChannel.handle()` that calls the `Handler` chain, that eventually calls the server application code.
[[pg-server-http-channel-events]]
===== HttpChannel Events
-The central component processing HTTP requests is `HttpChannel`.
-There is a 1-to-1 relationship between an HTTP request/response and an `HttpChannel`, no matter what is the specific protocol that carries the HTTP request over the network (HTTP/1.1, HTTP/2, HTTP/3 or FastCGI).
+The central component processing HTTP requests is `HttpChannelState`.
+There is a 1-to-1 relationship between an HTTP request/response and an `HttpChannelState`, no matter what is the specific protocol that carries the HTTP request over the network (HTTP/1.1, HTTP/2, HTTP/3 or FastCGI).
-Advanced server applications may be interested in the progress of the processing of an HTTP request/response by `HttpChannel`.
+Advanced server applications may be interested in the progress of the processing of an HTTP request/response by `HttpChannelState`.
A typical case is to know exactly _when_ the HTTP request/response processing is complete, for example to monitor processing times.
NOTE: A `Handler` or a Servlet `Filter` may not report precisely when an HTTP request/response processing is finished.
A server application may write a small enough content that is aggregated by Jetty for efficiency reasons; the write returns immediately, but nothing has been written to the network yet.
-`HttpChannel` notifies ``HttpChannel.Listener``s of the progress of the HTTP request/response handling.
+`HttpChannelState` notifies ``HttpChannel.Listener``s of the progress of the HTTP request/response handling.
Currently, the following events are available:
* `requestBegin`
diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/sessions/session-sessionhandler.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/sessions/session-sessionhandler.adoc
index 60f3807d066..918d84b0a99 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/sessions/session-sessionhandler.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/sessions/session-sessionhandler.adoc
@@ -27,7 +27,7 @@ checkingRemoteSessionIdEncoding::
Boolean, default `false`.
This controls whether or not the `javax.servlet.http.Response.encodeURL(String)` method will include the session id as a path parameter when the URL is destined for a remote node.
This can also be configured by:
-* setting the `org.eclipse.jetty.servlet.CheckingRemoteSessionIdEncoding` context init paramter
+* setting the `org.eclipse.jetty.ee9.servlet.CheckingRemoteSessionIdEncoding` context init paramter
setMaxInactiveInterval::
Integer, seconds.
@@ -69,14 +69,14 @@ This is the name of the session cookie.
It can alternatively be configured by:
* using `javax.servlet.SessionCookieConfig.setName(String)` method
-* setting the `org.eclipse.jetty.servlet.SessionCookie` context init parameter.
+* setting the `org.eclipse.jetty.ee9.servlet.SessionCookie` context init parameter.
sessionIdPathParameterName::
String, default is `jsessionid`.
This is the name of the path parameter used to transmit the session id on request URLs, and on encoded URLS in responses.
It can alternatively be configured by:
-* setting the `org.eclipse.jetty.servlet.SessionIdPathParameterName` context init parameter
+* setting the `org.eclipse.jetty.ee9.servlet.SessionIdPathParameterName` context init parameter
sessionTrackingModes::
`Set`.
@@ -99,7 +99,7 @@ This can also be configured by:
There are also a few session settings that do not have SessionHandler setters, but can be configured with context init parameters:
[[pg-server-session-handler-maxAge]]
-org.eclipse.jetty.servlet.MaxAge::
+org.eclipse.jetty.ee9.servlet.MaxAge::
This is the maximum number of seconds that the session cookie will be considered to be valid.
By default, the cookie has no maximum validity time.
See also xref:pg-server-session-handler-refreshcookie[refreshing the session cookie].
@@ -107,7 +107,7 @@ The value can also be configured by:
* calling the `SessionCookieConfig.setMaxAge(int)` method.
-org.eclipse.jetty.servlet.SessionDomain::
+org.eclipse.jetty.ee9.servlet.SessionDomain::
String, default `null`.
This is the domain of the session cookie.
This can also be configured by:
@@ -115,7 +115,7 @@ This can also be configured by:
* using the `javax.servlet.SessionCookieConfig.setDomain(String)` method
* defining the `` element in `web.xml`
-org.eclipse.jetty.servlet.SessionPath::
+org.eclipse.jetty.ee9.servlet.SessionPath::
String, default `null`.
This is used when creating a new session cookie.
If nothing is configured, the context path is used instead, defaulting to `/`.
diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/websocket/server-websocket-filter.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/websocket/server-websocket-filter.adoc
index b7db4b7929d..8723882a5e4 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/websocket/server-websocket-filter.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/websocket/server-websocket-filter.adoc
@@ -44,7 +44,7 @@ For example:
cross-origin
- org.eclipse.jetty.servlets.CrossOriginFilter
+ org.eclipse.jetty.ee9.servlets.CrossOriginFiltertrue
diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/websocket/server-websocket-jetty.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/websocket/server-websocket-jetty.adoc
index 82542a534ef..8ad0f12cdcf 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/websocket/server-websocket-jetty.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/websocket/server-websocket-jetty.adoc
@@ -76,7 +76,7 @@ Calling `JettyWebSocketServletContainerInitializer.configure(\...)` must be done
Once you have xref:pg-server-websocket-jetty-container[setup] the `JettyWebSocketServerContainer`, you can configure your xref:pg-websocket-endpoints[WebSocket endpoints].
-Differently from the xref:pg-server-websocket-standard-endpoints[configuration of standard WebSocket endpoints], WebSocket endpoint classes may be annotated with Jetty WebSocket API annotations, or extend the `org.eclipse.jetty.websocket.api.WebSocketListener` interface, but they are not automatically discovered, not even when deploying web applications using xref:pg-server-http-handler-use-webapp-context[`WebAppContext`].
+Differently from the xref:pg-server-websocket-standard-endpoints[configuration of standard WebSocket endpoints], WebSocket endpoint classes may be annotated with Jetty WebSocket API annotations, or extend the `org.eclipse.jetty.ee9.websocket.api.WebSocketListener` interface, but they are not automatically discovered, not even when deploying web applications using xref:pg-server-http-handler-use-webapp-context[`WebAppContext`].
[IMPORTANT]
====
diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/websocket.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/websocket.adoc
index 225f4dc4a85..2d99d9ce277 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/websocket.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/websocket.adoc
@@ -57,7 +57,7 @@ Applications interested in this type of messages receive a `byte[]` representing
[[pg-websocket-endpoints-listener]]
===== Listener Endpoints
-A WebSocket endpoint may implement the `org.eclipse.jetty.websocket.api.WebSocketListener` interface to receive WebSocket events:
+A WebSocket endpoint may implement the `org.eclipse.jetty.ee9.websocket.api.WebSocketListener` interface to receive WebSocket events:
[source,java,indent=0]
----
@@ -70,7 +70,7 @@ include::{doc_code}/org/eclipse/jetty/docs/programming/WebSocketDocs.java[tags=l
If you need to deal with large WebSocket messages, you may reduce the memory usage by streaming the message content.
For large WebSocket messages, the memory usage may be large due to the fact that the text or the bytes must be accumulated until the message is complete before delivering the message event.
-To stream textual or binary messages, you must implement interface `org.eclipse.jetty.websocket.api.WebSocketPartialListener` instead of `WebSocketListener`.
+To stream textual or binary messages, you must implement interface `org.eclipse.jetty.ee9.websocket.api.WebSocketPartialListener` instead of `WebSocketListener`.
Interface `WebSocketPartialListener` exposes one method for textual messages, and one method to binary messages that receive _chunks_ of, respectively, text and bytes that form the whole WebSocket message.
@@ -84,7 +84,7 @@ include::{doc_code}/org/eclipse/jetty/docs/programming/WebSocketDocs.java[tags=s
[[pg-websocket-endpoints-annotated]]
===== Annotated Endpoints
-A WebSocket endpoint may annotate methods with `org.eclipse.jetty.websocket.api.annotations.*` annotations to receive WebSocket events.
+A WebSocket endpoint may annotate methods with `org.eclipse.jetty.ee9.websocket.api.annotations.*` annotations to receive WebSocket events.
Each annotated method may take an optional `Session` argument as its first parameter:
[source,java,indent=0]
@@ -144,7 +144,7 @@ A WebSocket session is the entity that offers an API to send data to the remote
[[pg-websocket-session-configure]]
===== Configuring the Session
-You may configure the WebSocket session behavior using the `org.eclipse.jetty.websocket.api.Session` APIs.
+You may configure the WebSocket session behavior using the `org.eclipse.jetty.ee9.websocket.api.Session` APIs.
You want to do this as soon as you have access to the `Session` object, typically from the xref:pg-websocket-endpoints[_connect_ event] handler:
[source,java,indent=0]
@@ -254,7 +254,7 @@ The WebSocket protocol defines two special frame, named `Ping` and `Pong` that m
* Calculate the round-trip time with the remote peer.
* Keep the connection from being closed due to idle timeout -- a heartbeat-like mechanism.
-To handle `Ping`/`Pong` events, you may implement interface `org.eclipse.jetty.websocket.api.WebSocketPingPongListener`.
+To handle `Ping`/`Pong` events, you may implement interface `org.eclipse.jetty.ee9.websocket.api.WebSocketPingPongListener`.
[NOTE]
====
diff --git a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/WebSocketDocs.java b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/WebSocketDocs.java
index ef3ceff4149..c29db7a07df 100644
--- a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/WebSocketDocs.java
+++ b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/WebSocketDocs.java
@@ -20,19 +20,19 @@ import java.nio.ByteBuffer;
import java.nio.file.Path;
import java.time.Duration;
+import org.eclipse.jetty.ee9.websocket.api.RemoteEndpoint;
+import org.eclipse.jetty.ee9.websocket.api.Session;
+import org.eclipse.jetty.ee9.websocket.api.StatusCode;
+import org.eclipse.jetty.ee9.websocket.api.WebSocketListener;
+import org.eclipse.jetty.ee9.websocket.api.WebSocketPartialListener;
+import org.eclipse.jetty.ee9.websocket.api.WebSocketPingPongListener;
+import org.eclipse.jetty.ee9.websocket.api.WriteCallback;
+import org.eclipse.jetty.ee9.websocket.api.annotations.OnWebSocketClose;
+import org.eclipse.jetty.ee9.websocket.api.annotations.OnWebSocketConnect;
+import org.eclipse.jetty.ee9.websocket.api.annotations.OnWebSocketError;
+import org.eclipse.jetty.ee9.websocket.api.annotations.OnWebSocketMessage;
+import org.eclipse.jetty.ee9.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.util.IteratingCallback;
-import org.eclipse.jetty.websocket.api.RemoteEndpoint;
-import org.eclipse.jetty.websocket.api.Session;
-import org.eclipse.jetty.websocket.api.StatusCode;
-import org.eclipse.jetty.websocket.api.WebSocketListener;
-import org.eclipse.jetty.websocket.api.WebSocketPartialListener;
-import org.eclipse.jetty.websocket.api.WebSocketPingPongListener;
-import org.eclipse.jetty.websocket.api.WriteCallback;
-import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
-import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
-import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
-import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
-import org.eclipse.jetty.websocket.api.annotations.WebSocket;
@SuppressWarnings("unused")
public class WebSocketDocs
diff --git a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/http2/HTTP2ClientDocs.java b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/http2/HTTP2ClientDocs.java
index d1214006493..dfbf13d2e25 100644
--- a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/http2/HTTP2ClientDocs.java
+++ b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/http2/HTTP2ClientDocs.java
@@ -26,7 +26,6 @@ import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
-import org.eclipse.jetty.http2.ErrorCode;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.client.HTTP2Client;
@@ -35,6 +34,7 @@ import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.PushPromiseFrame;
import org.eclipse.jetty.http2.frames.ResetFrame;
import org.eclipse.jetty.http2.frames.SettingsFrame;
+import org.eclipse.jetty.http2.internal.ErrorCode;
import org.eclipse.jetty.io.ClientConnector;
import org.eclipse.jetty.util.Callback;
diff --git a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/websocket/WebSocketClientDocs.java b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/websocket/WebSocketClientDocs.java
index dce2373692b..fb234689778 100644
--- a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/websocket/WebSocketClientDocs.java
+++ b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/websocket/WebSocketClientDocs.java
@@ -22,14 +22,14 @@ import org.eclipse.jetty.client.HttpProxy;
import org.eclipse.jetty.client.HttpRequest;
import org.eclipse.jetty.client.HttpResponse;
import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic;
+import org.eclipse.jetty.ee9.websocket.api.Session;
+import org.eclipse.jetty.ee9.websocket.client.ClientUpgradeRequest;
+import org.eclipse.jetty.ee9.websocket.client.JettyUpgradeListener;
+import org.eclipse.jetty.ee9.websocket.client.WebSocketClient;
import org.eclipse.jetty.http2.client.HTTP2Client;
import org.eclipse.jetty.http2.client.http.ClientConnectionFactoryOverHTTP2;
import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
import org.eclipse.jetty.util.component.LifeCycle;
-import org.eclipse.jetty.websocket.api.Session;
-import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
-import org.eclipse.jetty.websocket.client.JettyUpgradeListener;
-import org.eclipse.jetty.websocket.client.WebSocketClient;
@SuppressWarnings("unused")
public class WebSocketClientDocs
diff --git a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java
index c1abe671d88..86615425cd1 100644
--- a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java
+++ b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java
@@ -27,6 +27,12 @@ import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
+import org.eclipse.jetty.ee9.servlet.DefaultServlet;
+import org.eclipse.jetty.ee9.servlet.FilterHolder;
+import org.eclipse.jetty.ee9.servlet.ServletContextHandler;
+import org.eclipse.jetty.ee9.servlet.ServletHolder;
+import org.eclipse.jetty.ee9.servlets.CrossOriginFilter;
+import org.eclipse.jetty.ee9.webapp.WebAppContext;
import org.eclipse.jetty.http.HttpCompliance;
import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.HttpMethod;
@@ -42,7 +48,6 @@ import org.eclipse.jetty.rewrite.handler.RewriteHandler;
import org.eclipse.jetty.rewrite.handler.RewriteRegexRule;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.CustomRequestLog;
-import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.ProxyConnectionFactory;
@@ -65,18 +70,13 @@ import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.server.handler.SecuredRedirectHandler;
import org.eclipse.jetty.server.handler.StatisticsHandler;
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
-import org.eclipse.jetty.servlet.DefaultServlet;
-import org.eclipse.jetty.servlet.FilterHolder;
-import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.eclipse.jetty.servlet.ServletHolder;
-import org.eclipse.jetty.servlets.CrossOriginFilter;
+import org.eclipse.jetty.server.internal.HttpChannelState;
import org.eclipse.jetty.unixdomain.server.UnixDomainServerConnector;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.resource.ResourceCollection;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.eclipse.jetty.webapp.WebAppContext;
import static java.lang.System.Logger.Level.INFO;
@@ -119,7 +119,7 @@ public class HTTPServerDocs
public void httpChannelListener() throws Exception
{
// tag::httpChannelListener[]
- class TimingHttpChannelListener implements HttpChannel.Listener
+ class TimingHttpChannelListener implements HttpChannelState.Listener
{
private final ConcurrentMap times = new ConcurrentHashMap<>();
diff --git a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/http2/HTTP2ServerDocs.java b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/http2/HTTP2ServerDocs.java
index c8dc47bf141..a3dac9ec95c 100644
--- a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/http2/HTTP2ServerDocs.java
+++ b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/http2/HTTP2ServerDocs.java
@@ -24,7 +24,6 @@ import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
-import org.eclipse.jetty.http2.ErrorCode;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
@@ -33,6 +32,7 @@ import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.PushPromiseFrame;
import org.eclipse.jetty.http2.frames.ResetFrame;
import org.eclipse.jetty.http2.frames.SettingsFrame;
+import org.eclipse.jetty.http2.internal.ErrorCode;
import org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
diff --git a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/session/SessionDocs.java b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/session/SessionDocs.java
index c5985193406..9d4c3eb7d4d 100644
--- a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/session/SessionDocs.java
+++ b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/session/SessionDocs.java
@@ -16,25 +16,25 @@ package org.eclipse.jetty.docs.programming.server.session;
import java.io.File;
import java.net.InetSocketAddress;
+import org.eclipse.jetty.ee9.servlet.ServletContextHandler;
+import org.eclipse.jetty.ee9.webapp.WebAppContext;
import org.eclipse.jetty.memcached.session.MemcachedSessionDataMapFactory;
import org.eclipse.jetty.nosql.mongodb.MongoSessionDataStoreFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
-import org.eclipse.jetty.server.session.CachingSessionDataStoreFactory;
-import org.eclipse.jetty.server.session.DatabaseAdaptor;
-import org.eclipse.jetty.server.session.DefaultSessionCache;
-import org.eclipse.jetty.server.session.DefaultSessionCacheFactory;
-import org.eclipse.jetty.server.session.DefaultSessionIdManager;
-import org.eclipse.jetty.server.session.FileSessionDataStore;
-import org.eclipse.jetty.server.session.FileSessionDataStoreFactory;
-import org.eclipse.jetty.server.session.HouseKeeper;
-import org.eclipse.jetty.server.session.NullSessionCache;
-import org.eclipse.jetty.server.session.NullSessionCacheFactory;
-import org.eclipse.jetty.server.session.NullSessionDataStore;
-import org.eclipse.jetty.server.session.SessionCache;
-import org.eclipse.jetty.server.session.SessionHandler;
-import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.session.CachingSessionDataStoreFactory;
+import org.eclipse.jetty.session.DatabaseAdaptor;
+import org.eclipse.jetty.session.DefaultSessionCache;
+import org.eclipse.jetty.session.DefaultSessionCacheFactory;
+import org.eclipse.jetty.session.DefaultSessionIdManager;
+import org.eclipse.jetty.session.FileSessionDataStore;
+import org.eclipse.jetty.session.FileSessionDataStoreFactory;
+import org.eclipse.jetty.session.HouseKeeper;
+import org.eclipse.jetty.session.NullSessionCache;
+import org.eclipse.jetty.session.NullSessionCacheFactory;
+import org.eclipse.jetty.session.NullSessionDataStore;
+import org.eclipse.jetty.session.SessionCache;
+import org.eclipse.jetty.session.SessionHandler;
@SuppressWarnings("unused")
public class SessionDocs
@@ -114,7 +114,7 @@ public class SessionDocs
//EVICT_ON_INACTIVE: evict a session after 60sec inactivity
cacheFactory.setEvictionPolicy(60);
//Only useful with the EVICT_ON_INACTIVE policy
- cacheFactory.setSaveOnInactiveEvict(true);
+ cacheFactory.setSaveOnInactiveEviction(true);
cacheFactory.setFlushOnResponseCommit(true);
cacheFactory.setInvalidateOnShutdown(false);
cacheFactory.setRemoveUnloadableSessions(true);
diff --git a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/websocket/WebSocketServerDocs.java b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/websocket/WebSocketServerDocs.java
index c5a6d7ad10d..8776f670b9c 100644
--- a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/websocket/WebSocketServerDocs.java
+++ b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/websocket/WebSocketServerDocs.java
@@ -24,16 +24,16 @@ import jakarta.websocket.DeploymentException;
import jakarta.websocket.server.ServerContainer;
import jakarta.websocket.server.ServerEndpoint;
import jakarta.websocket.server.ServerEndpointConfig;
+import org.eclipse.jetty.ee9.servlet.ServletContextHandler;
+import org.eclipse.jetty.ee9.webapp.WebAppContext;
+import org.eclipse.jetty.ee9.websocket.api.annotations.WebSocket;
+import org.eclipse.jetty.ee9.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer;
+import org.eclipse.jetty.ee9.websocket.server.JettyWebSocketCreator;
+import org.eclipse.jetty.ee9.websocket.server.JettyWebSocketServerContainer;
+import org.eclipse.jetty.ee9.websocket.server.JettyWebSocketServlet;
+import org.eclipse.jetty.ee9.websocket.server.JettyWebSocketServletFactory;
+import org.eclipse.jetty.ee9.websocket.server.config.JettyWebSocketServletContainerInitializer;
import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.eclipse.jetty.webapp.WebAppContext;
-import org.eclipse.jetty.websocket.api.annotations.WebSocket;
-import org.eclipse.jetty.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer;
-import org.eclipse.jetty.websocket.server.JettyWebSocketCreator;
-import org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer;
-import org.eclipse.jetty.websocket.server.JettyWebSocketServlet;
-import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory;
-import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
@SuppressWarnings("unused")
public class WebSocketServerDocs
diff --git a/documentation/pom.xml b/documentation/pom.xml
index 02955c82956..5f5f75e909f 100644
--- a/documentation/pom.xml
+++ b/documentation/pom.xml
@@ -3,12 +3,12 @@
org.eclipse.jettyjetty-project
- 11.0.10-SNAPSHOT
+ 12.0.0-SNAPSHOT4.0.0org.eclipse.jetty.documentation
- documentation-parent
+ documentationJetty :: Documentation :: Parentpom
diff --git a/javadoc/pom.xml b/javadoc/pom.xml
index 56785ebdd3b..8e780427e5f 100644
--- a/javadoc/pom.xml
+++ b/javadoc/pom.xml
@@ -3,7 +3,7 @@
org.eclipse.jettyjetty-project
- 11.0.10-SNAPSHOT
+ 12.0.0-SNAPSHOT4.0.0
@@ -14,6 +14,7 @@
${project.build.directory}/jetty-sourcestrue
+ truetruetrue
@@ -108,10 +109,6 @@
infinispan-remote,
jetty-test-helper,
alpn-api,
- quic-quiche,
- quic-quiche-common,
- quic-quiche-foreign-incubator,
- quic-quiche-jna,
javax.servlet,
javax.websocket,
jakarta.servlet,
@@ -157,6 +154,8 @@
org.eclipse.jetty.http3.qpack.internal.*;
org.eclipse.jetty.http3.server.internal;
org.eclipse.jetty.quic.common.internal;
+ org.eclipse.jetty.quic.quiche;
+ org.eclipse.jetty.quic.quiche.*;
org.eclipse.jetty.quic.server.internal;
@@ -347,11 +346,6 @@
jetty-unixsocket-clientprovided
-
- org.eclipse.jetty
- jetty-unixsocket-server
- provided
- org.eclipse.jetty.websocketwebsocket-jakarta-server
@@ -400,12 +394,6 @@
org.eclipse.jettyjetty-jspc-maven-pluginprovided
-
-
- javax.annotation
- javax.annotation-api
-
- org.eclipse.jetty
diff --git a/jetty-annotations/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration b/jetty-annotations/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration
deleted file mode 100644
index 87590589c0e..00000000000
--- a/jetty-annotations/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration
+++ /dev/null
@@ -1 +0,0 @@
-org.eclipse.jetty.annotations.AnnotationConfiguration
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AsyncContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AsyncContentProvider.java
deleted file mode 100644
index 5b8f9cf7012..00000000000
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/AsyncContentProvider.java
+++ /dev/null
@@ -1,44 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License v. 2.0 which is available at
-// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-// ========================================================================
-//
-
-package org.eclipse.jetty.client;
-
-import java.util.EventListener;
-
-import org.eclipse.jetty.client.api.ContentProvider;
-import org.eclipse.jetty.client.api.Request;
-
-/**
- * A {@link ContentProvider} that notifies listeners that content is available.
- *
- * @deprecated no replacement, use {@link Request.Content} instead.
- */
-@Deprecated
-public interface AsyncContentProvider extends ContentProvider
-{
- /**
- * @param listener the listener to be notified of content availability
- */
- public void setListener(Listener listener);
-
- /**
- * A listener that is notified of content availability
- */
- public interface Listener extends EventListener
- {
- /**
- * Callback method invoked when content is available
- */
- public void onContent();
- }
-}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/api/ContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/api/ContentProvider.java
deleted file mode 100644
index b27ddd4ac5b..00000000000
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/api/ContentProvider.java
+++ /dev/null
@@ -1,94 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License v. 2.0 which is available at
-// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-// ========================================================================
-//
-
-package org.eclipse.jetty.client.api;
-
-import java.io.Closeable;
-import java.nio.ByteBuffer;
-import java.util.Iterator;
-
-import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.client.internal.RequestContentAdapter;
-import org.eclipse.jetty.client.util.ByteBufferContentProvider;
-import org.eclipse.jetty.client.util.PathContentProvider;
-
-/**
- *
{@link ContentProvider} provides a source of request content.
- *
Implementations should return an {@link Iterator} over the request content.
- * If the request content comes from a source that needs to be closed (for
- * example, an {@link java.io.InputStream}), then the iterator implementation class
- * must implement {@link Closeable} and will be closed when the request is
- * completed (either successfully or failed).
- *
Applications should rely on utility classes such as {@link ByteBufferContentProvider}
- * or {@link PathContentProvider}.
- *
{@link ContentProvider} provides a {@link #getLength() length} of the content
- * it represents.
- * If the length is positive, it typically overrides any {@code Content-Length}
- * header set by applications; if the length is negative, it typically removes
- * any {@code Content-Length} header set by applications, resulting in chunked
- * content (i.e. {@code Transfer-Encoding: chunked}) being sent to the server.
- *
- * @deprecated use {@link Request.Content} instead, or {@link #toRequestContent(ContentProvider)}
- * to convert ContentProvider to {@link Request.Content}.
- */
-@Deprecated
-public interface ContentProvider extends Iterable
-{
- /**
- *
Converts a ContentProvider to a {@link Request.Content}.
- *
- * @param provider the ContentProvider to convert
- * @return a {@link Request.Content} that wraps the ContentProvider
- */
- public static Request.Content toRequestContent(ContentProvider provider)
- {
- return new RequestContentAdapter(provider);
- }
-
- /**
- * @return the content length, if known, or -1 if the content length is unknown
- */
- long getLength();
-
- /**
- *
Whether this ContentProvider can produce exactly the same content more
- * than once.
- *
Implementations should return {@code true} only if the content can be
- * produced more than once, which means that invocations to {@link #iterator()}
- * must return a new, independent, iterator instance over the content.
- *
The {@link HttpClient} implementation may use this method in particular
- * cases where it detects that it is safe to retry a request that failed.
- *
- * @return whether the content can be produced more than once
- */
- default boolean isReproducible()
- {
- return false;
- }
-
- /**
- * An extension of {@link ContentProvider} that provides a content type string
- * to be used as a {@code Content-Type} HTTP header in requests.
- *
- * @deprecated use {@link Request.Content} instead
- */
- @Deprecated
- public interface Typed extends ContentProvider
- {
- /**
- * @return the content type string such as "application/octet-stream" or
- * "application/json;charset=UTF8", or null if no content type must be set
- */
- public String getContentType();
- }
-}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/internal/RequestContentAdapter.java b/jetty-client/src/main/java/org/eclipse/jetty/client/internal/RequestContentAdapter.java
deleted file mode 100644
index a810c7f0f1f..00000000000
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/internal/RequestContentAdapter.java
+++ /dev/null
@@ -1,324 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License v. 2.0 which is available at
-// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-// ========================================================================
-//
-
-package org.eclipse.jetty.client.internal;
-
-import java.io.Closeable;
-import java.nio.ByteBuffer;
-import java.util.Iterator;
-
-import org.eclipse.jetty.client.AsyncContentProvider;
-import org.eclipse.jetty.client.Synchronizable;
-import org.eclipse.jetty.client.api.ContentProvider;
-import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.IO;
-import org.eclipse.jetty.util.thread.AutoLock;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
Implements the conversion from {@link ContentProvider} to {@link Request.Content}.
- */
-public class RequestContentAdapter implements Request.Content, Request.Content.Subscription, AsyncContentProvider.Listener, Callback
-{
- private static final Logger LOG = LoggerFactory.getLogger(RequestContentAdapter.class);
-
- private final AutoLock lock = new AutoLock();
- private final ContentProvider provider;
- private Iterator iterator;
- private Consumer consumer;
- private boolean emitInitialContent;
- private boolean lastContent;
- private boolean committed;
- private int demand;
- private boolean stalled;
- private boolean hasContent;
- private Throwable failure;
-
- public RequestContentAdapter(ContentProvider provider)
- {
- this.provider = provider;
- if (provider instanceof AsyncContentProvider)
- ((AsyncContentProvider)provider).setListener(this);
- }
-
- public ContentProvider getContentProvider()
- {
- return provider;
- }
-
- @Override
- public String getContentType()
- {
- return provider instanceof ContentProvider.Typed ? ((ContentProvider.Typed)provider).getContentType() : null;
- }
-
- @Override
- public long getLength()
- {
- return provider.getLength();
- }
-
- @Override
- public boolean isReproducible()
- {
- return provider.isReproducible();
- }
-
- @Override
- public Subscription subscribe(Consumer consumer, boolean emitInitialContent)
- {
- try (AutoLock ignored = lock.lock())
- {
- if (this.consumer != null && !isReproducible())
- throw new IllegalStateException("Multiple subscriptions not supported on " + this);
- this.iterator = provider.iterator();
- this.consumer = consumer;
- this.emitInitialContent = emitInitialContent;
- this.lastContent = false;
- this.committed = false;
- this.demand = 0;
- this.stalled = true;
- this.hasContent = false;
- }
- return this;
- }
-
- @Override
- public void demand()
- {
- boolean produce;
- try (AutoLock ignored = lock.lock())
- {
- ++demand;
- produce = stalled;
- if (stalled)
- stalled = false;
- }
- if (LOG.isDebugEnabled())
- LOG.debug("Content demand, producing {} for {}", produce, this);
- if (produce)
- produce();
- }
-
- @Override
- public void fail(Throwable failure)
- {
- try (AutoLock ignored = lock.lock())
- {
- if (this.failure == null)
- this.failure = failure;
- }
- failed(failure);
- }
-
- @Override
- public void onContent()
- {
- boolean produce = false;
- try (AutoLock ignored = lock.lock())
- {
- hasContent = true;
- if (demand > 0)
- {
- produce = stalled;
- if (stalled)
- stalled = false;
- }
- }
- if (LOG.isDebugEnabled())
- LOG.debug("Content event, processing {} for {}", produce, this);
- if (produce)
- produce();
- }
-
- @Override
- public void succeeded()
- {
- if (iterator instanceof Callback)
- ((Callback)iterator).succeeded();
- if (lastContent && iterator instanceof Closeable)
- IO.close((Closeable)iterator);
- }
-
- @Override
- public void failed(Throwable x)
- {
- if (iterator == null)
- failed(provider, x);
- else
- failed(iterator, x);
- }
-
- private void failed(Object object, Throwable failure)
- {
- if (object instanceof Callback)
- ((Callback)object).failed(failure);
- if (object instanceof Closeable)
- IO.close((Closeable)object);
- }
-
- @Override
- public InvocationType getInvocationType()
- {
- return InvocationType.NON_BLOCKING;
- }
-
- private void produce()
- {
- while (true)
- {
- Throwable failure;
- try (AutoLock ignored = lock.lock())
- {
- failure = this.failure;
- }
- if (failure != null)
- {
- notifyFailure(failure);
- return;
- }
-
- if (committed)
- {
- ByteBuffer content = advance();
- if (content != null)
- {
- notifyContent(content, lastContent);
- }
- else
- {
- try (AutoLock ignored = lock.lock())
- {
- // Call to advance() said there was no content,
- // but some content may have arrived meanwhile.
- if (hasContent)
- {
- hasContent = false;
- continue;
- }
- else
- {
- stalled = true;
- }
- }
- if (LOG.isDebugEnabled())
- LOG.debug("No content, processing stalled for {}", this);
- return;
- }
- }
- else
- {
- committed = true;
- if (emitInitialContent)
- {
- ByteBuffer content = advance();
- if (content != null)
- notifyContent(content, lastContent);
- else
- notifyContent(BufferUtil.EMPTY_BUFFER, false);
- }
- else
- {
- notifyContent(BufferUtil.EMPTY_BUFFER, false);
- }
- }
- boolean noDemand;
- try (AutoLock ignored = lock.lock())
- {
- noDemand = demand == 0;
- if (noDemand)
- stalled = true;
- }
- if (noDemand)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("No demand, processing stalled for {}", this);
- return;
- }
- }
- }
-
- private ByteBuffer advance()
- {
- if (iterator instanceof Synchronizable)
- {
- synchronized (((Synchronizable)iterator).getLock())
- {
- return next();
- }
- }
- else
- {
- return next();
- }
- }
-
- private ByteBuffer next()
- {
- boolean hasNext = iterator.hasNext();
- ByteBuffer bytes = hasNext ? iterator.next() : null;
- boolean hasMore = hasNext && iterator.hasNext();
- lastContent = !hasMore;
- return hasNext ? bytes : BufferUtil.EMPTY_BUFFER;
- }
-
- private void notifyContent(ByteBuffer buffer, boolean last)
- {
- try (AutoLock ignored = lock.lock())
- {
- --demand;
- hasContent = false;
- }
-
- try
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Notifying content last={} {} for {}", last, BufferUtil.toDetailString(buffer), this);
- consumer.onContent(buffer, last, this);
- }
- catch (Throwable x)
- {
- fail(x);
- }
- }
-
- private void notifyFailure(Throwable failure)
- {
- try
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Notifying failure for {}", this, failure);
- consumer.onFailure(failure);
- }
- catch (Exception x)
- {
- LOG.trace("Failure while notifying content failure {}", failure, x);
- }
- }
-
- @Override
- public String toString()
- {
- int demand;
- boolean stalled;
- try (AutoLock ignored = lock.lock())
- {
- demand = this.demand;
- stalled = this.stalled;
- }
- return String.format("%s@%x[demand=%d,stalled=%b]", getClass().getSimpleName(), hashCode(), demand, stalled);
- }
-}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/ByteBufferContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/ByteBufferContentProvider.java
deleted file mode 100644
index 938e8f70f6d..00000000000
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/ByteBufferContentProvider.java
+++ /dev/null
@@ -1,96 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License v. 2.0 which is available at
-// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-// ========================================================================
-//
-
-package org.eclipse.jetty.client.util;
-
-import java.nio.ByteBuffer;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.jetty.client.api.ContentProvider;
-
-/**
- * A {@link ContentProvider} for {@link ByteBuffer}s.
- *
- * The position and limit of the {@link ByteBuffer}s passed to the constructor are not modified,
- * and each invocation of the {@link #iterator()} method returns a {@link ByteBuffer#slice() slice}
- * of the original {@link ByteBuffer}.
- *
- * @deprecated use {@link ByteBufferRequestContent} instead.
- */
-@Deprecated
-public class ByteBufferContentProvider extends AbstractTypedContentProvider
-{
- private final ByteBuffer[] buffers;
- private final int length;
-
- public ByteBufferContentProvider(ByteBuffer... buffers)
- {
- this("application/octet-stream", buffers);
- }
-
- public ByteBufferContentProvider(String contentType, ByteBuffer... buffers)
- {
- super(contentType);
- this.buffers = buffers;
- int length = 0;
- for (ByteBuffer buffer : buffers)
- {
- length += buffer.remaining();
- }
- this.length = length;
- }
-
- @Override
- public long getLength()
- {
- return length;
- }
-
- @Override
- public boolean isReproducible()
- {
- return true;
- }
-
- @Override
- public Iterator iterator()
- {
- return new Iterator()
- {
- private int index;
-
- @Override
- public boolean hasNext()
- {
- return index < buffers.length;
- }
-
- @Override
- public ByteBuffer next()
- {
- try
- {
- ByteBuffer buffer = buffers[index];
- buffers[index] = buffer.slice();
- ++index;
- return buffer;
- }
- catch (ArrayIndexOutOfBoundsException x)
- {
- throw new NoSuchElementException();
- }
- }
- };
- }
-}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/BytesContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/BytesContentProvider.java
deleted file mode 100644
index 16ff874ef83..00000000000
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/BytesContentProvider.java
+++ /dev/null
@@ -1,89 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License v. 2.0 which is available at
-// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-// ========================================================================
-//
-
-package org.eclipse.jetty.client.util;
-
-import java.nio.ByteBuffer;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.jetty.client.api.ContentProvider;
-
-/**
- * A {@link ContentProvider} for byte arrays.
- *
- * @deprecated use {@link BytesRequestContent} instead.
- */
-@Deprecated
-public class BytesContentProvider extends AbstractTypedContentProvider
-{
- private final byte[][] bytes;
- private final long length;
-
- public BytesContentProvider(byte[]... bytes)
- {
- this("application/octet-stream", bytes);
- }
-
- public BytesContentProvider(String contentType, byte[]... bytes)
- {
- super(contentType);
- this.bytes = bytes;
- long length = 0;
- for (byte[] buffer : bytes)
- {
- length += buffer.length;
- }
- this.length = length;
- }
-
- @Override
- public long getLength()
- {
- return length;
- }
-
- @Override
- public boolean isReproducible()
- {
- return true;
- }
-
- @Override
- public Iterator iterator()
- {
- return new Iterator()
- {
- private int index;
-
- @Override
- public boolean hasNext()
- {
- return index < bytes.length;
- }
-
- @Override
- public ByteBuffer next()
- {
- try
- {
- return ByteBuffer.wrap(bytes[index++]);
- }
- catch (ArrayIndexOutOfBoundsException x)
- {
- throw new NoSuchElementException();
- }
- }
- };
- }
-}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/DeferredContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/DeferredContentProvider.java
deleted file mode 100644
index 690bccf4e67..00000000000
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/DeferredContentProvider.java
+++ /dev/null
@@ -1,343 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License v. 2.0 which is available at
-// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-// ========================================================================
-//
-
-package org.eclipse.jetty.client.util;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.nio.ByteBuffer;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Deque;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Objects;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.eclipse.jetty.client.AsyncContentProvider;
-import org.eclipse.jetty.client.Synchronizable;
-import org.eclipse.jetty.client.api.ContentProvider;
-import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.client.api.Response;
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Callback;
-
-/**
- * A {@link ContentProvider} that allows to add content after {@link Request#send(Response.CompleteListener)}
- * has been called, therefore providing the request content at a later time.
- *
- * {@link DeferredContentProvider} can only be used in conjunction with
- * {@link Request#send(Response.CompleteListener)} (and not with its blocking counterpart {@link Request#send()})
- * because it provides content asynchronously.
- *
- * The deferred content is provided once and then fully consumed.
- * Invocations to the {@link #iterator()} method after the first will return an "empty" iterator
- * because the stream has been consumed on the first invocation.
- * However, it is possible for subclasses to override {@link #offer(ByteBuffer)} and {@link #close()} to copy
- * the content to another location (for example a file) and be able to support multiple invocations
- * of of {@link #iterator()} returning the iterator provided by this
- * class on the first invocation, and an iterator on the bytes copied to the other location
- * for subsequent invocations.
- *
- * Typical usage of {@link DeferredContentProvider} is in asynchronous proxies, where HTTP headers arrive
- * separately from HTTP content chunks.
- *
- * The deferred content must be provided through {@link #offer(ByteBuffer)}, which can be invoked multiple
- * times, and when all content has been provided it must be signaled with a call to {@link #close()}.
- *
- * Example usage:
- *
- * HttpClient httpClient = ...;
- *
- * // Use try-with-resources to autoclose DeferredContentProvider
- * try (DeferredContentProvider content = new DeferredContentProvider())
- * {
- * httpClient.newRequest("localhost", 8080)
- * .content(content)
- * .send(new Response.CompleteListener()
- * {
- * @Override
- * public void onComplete(Result result)
- * {
- * // Your logic here
- * }
- * });
- *
- * // At a later time...
- * content.offer(ByteBuffer.wrap("some content".getBytes()));
- * }
- *
- *
- * @deprecated use {@link AsyncRequestContent} instead.
- */
-@Deprecated
-public class DeferredContentProvider implements AsyncContentProvider, Callback, Closeable
-{
- private static final Chunk CLOSE = new Chunk(BufferUtil.EMPTY_BUFFER, Callback.NOOP);
-
- private final Object lock = this;
- private final Deque chunks = new ArrayDeque<>();
- private final AtomicReference listener = new AtomicReference<>();
- private final DeferredContentProviderIterator iterator = new DeferredContentProviderIterator();
- private final AtomicBoolean closed = new AtomicBoolean();
- private long length = -1;
- private int size;
- private Throwable failure;
-
- /**
- * Creates a new {@link DeferredContentProvider} with the given initial content
- *
- * @param buffers the initial content
- */
- public DeferredContentProvider(ByteBuffer... buffers)
- {
- for (ByteBuffer buffer : buffers)
- {
- offer(buffer);
- }
- }
-
- @Override
- public void setListener(Listener listener)
- {
- if (!this.listener.compareAndSet(null, listener))
- throw new IllegalStateException(String.format("The same %s instance cannot be used in multiple requests",
- AsyncContentProvider.class.getName()));
-
- if (isClosed())
- {
- synchronized (lock)
- {
- long total = 0;
- for (Chunk chunk : chunks)
- {
- total += chunk.buffer.remaining();
- }
- length = total;
- }
- }
- }
-
- @Override
- public long getLength()
- {
- return length;
- }
-
- /**
- * Adds the given content buffer to this content provider
- * and notifies the listener that content is available.
- *
- * @param buffer the content to add
- * @return true if the content was added, false otherwise
- */
- public boolean offer(ByteBuffer buffer)
- {
- return offer(buffer, Callback.NOOP);
- }
-
- public boolean offer(ByteBuffer buffer, Callback callback)
- {
- return offer(new Chunk(buffer, callback));
- }
-
- private boolean offer(Chunk chunk)
- {
- Throwable failure;
- boolean result = false;
- synchronized (lock)
- {
- failure = this.failure;
- if (failure == null)
- {
- result = chunks.offer(chunk);
- if (result && chunk != CLOSE)
- ++size;
- }
- }
- if (failure != null)
- chunk.callback.failed(failure);
- else if (result)
- notifyListener();
- return result;
- }
-
- private void clear()
- {
- synchronized (lock)
- {
- chunks.clear();
- }
- }
-
- public void flush() throws IOException
- {
- synchronized (lock)
- {
- try
- {
- while (true)
- {
- if (failure != null)
- throw new IOException(failure);
- if (size == 0)
- break;
- lock.wait();
- }
- }
- catch (InterruptedException x)
- {
- throw new InterruptedIOException();
- }
- }
- }
-
- /**
- * No more content will be added to this content provider
- * and notifies the listener that no more content is available.
- */
- @Override
- public void close()
- {
- if (closed.compareAndSet(false, true))
- offer(CLOSE);
- }
-
- public boolean isClosed()
- {
- return closed.get();
- }
-
- @Override
- public void failed(Throwable failure)
- {
- iterator.failed(failure);
- }
-
- private void notifyListener()
- {
- Listener listener = this.listener.get();
- if (listener != null)
- listener.onContent();
- }
-
- @Override
- public Iterator iterator()
- {
- return iterator;
- }
-
- private class DeferredContentProviderIterator implements Iterator, Callback, Synchronizable
- {
- private Chunk current;
-
- @Override
- public boolean hasNext()
- {
- synchronized (lock)
- {
- return chunks.peek() != CLOSE;
- }
- }
-
- @Override
- public ByteBuffer next()
- {
- synchronized (lock)
- {
- Chunk chunk = current = chunks.poll();
- if (chunk == CLOSE)
- {
- // Slow path: reinsert the CLOSE chunk
- // so that hasNext() works correctly.
- chunks.offerFirst(CLOSE);
- throw new NoSuchElementException();
- }
- return chunk == null ? null : chunk.buffer;
- }
- }
-
- @Override
- public void remove()
- {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void succeeded()
- {
- Chunk chunk;
- synchronized (lock)
- {
- chunk = current;
- current = null;
- if (chunk != null)
- {
- --size;
- lock.notify();
- }
- }
- if (chunk != null)
- chunk.callback.succeeded();
- }
-
- @Override
- public void failed(Throwable x)
- {
- List chunks = new ArrayList<>();
- synchronized (lock)
- {
- failure = x;
- // Transfer all chunks to fail them all.
- Chunk chunk = current;
- current = null;
- if (chunk != null)
- chunks.add(chunk);
- chunks.addAll(DeferredContentProvider.this.chunks);
- clear();
- lock.notify();
- }
- for (Chunk chunk : chunks)
- {
- chunk.callback.failed(x);
- }
- }
-
- @Override
- public Object getLock()
- {
- return lock;
- }
- }
-
- public static class Chunk
- {
- public final ByteBuffer buffer;
- public final Callback callback;
-
- public Chunk(ByteBuffer buffer, Callback callback)
- {
- this.buffer = Objects.requireNonNull(buffer);
- this.callback = Objects.requireNonNull(callback);
- }
-
- @Override
- public String toString()
- {
- return String.format("%s@%x", getClass().getSimpleName(), hashCode());
- }
- }
-}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/FormContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/FormContentProvider.java
deleted file mode 100644
index 78684d19b1c..00000000000
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/FormContentProvider.java
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License v. 2.0 which is available at
-// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-// ========================================================================
-//
-
-package org.eclipse.jetty.client.util;
-
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-
-import org.eclipse.jetty.client.api.ContentProvider;
-import org.eclipse.jetty.util.Fields;
-
-/**
- * A {@link ContentProvider} for form uploads with the
- * "application/x-www-form-urlencoded" content type.
- *
- * @deprecated use {@link FormRequestContent} instead.
- */
-@Deprecated
-public class FormContentProvider extends StringContentProvider
-{
- public FormContentProvider(Fields fields)
- {
- this(fields, StandardCharsets.UTF_8);
- }
-
- public FormContentProvider(Fields fields, Charset charset)
- {
- super("application/x-www-form-urlencoded", convert(fields, charset), charset);
- }
-
- public static String convert(Fields fields)
- {
- return convert(fields, StandardCharsets.UTF_8);
- }
-
- public static String convert(Fields fields, Charset charset)
- {
- return FormRequestContent.convert(fields, charset);
- }
-}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/InputStreamContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/InputStreamContentProvider.java
deleted file mode 100644
index 74bf1a794ed..00000000000
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/InputStreamContentProvider.java
+++ /dev/null
@@ -1,256 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License v. 2.0 which is available at
-// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-// ========================================================================
-//
-
-package org.eclipse.jetty.client.util;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.jetty.client.api.ContentProvider;
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Callback;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A {@link ContentProvider} for an {@link InputStream}.
- *
- * The input stream is read once and therefore fully consumed.
- * Invocations to the {@link #iterator()} method after the first will return an "empty" iterator
- * because the stream has been consumed on the first invocation.
- *
- * However, it is possible for subclasses to override {@link #onRead(byte[], int, int)} to copy
- * the content read from the stream to another location (for example a file), and be able to
- * support multiple invocations of {@link #iterator()}, returning the iterator provided by this
- * class on the first invocation, and an iterator on the bytes copied to the other location
- * for subsequent invocations.
- *
- * It is possible to specify, at the constructor, a buffer size used to read content from the
- * stream, by default 4096 bytes.
- *
- * The {@link InputStream} passed to the constructor is by default closed when is it fully
- * consumed (or when an exception is thrown while reading it), unless otherwise specified
- * to the {@link #InputStreamContentProvider(java.io.InputStream, int, boolean) constructor}.
- *
- * @deprecated use {@link InputStreamRequestContent} instead
- */
-@Deprecated
-public class InputStreamContentProvider implements ContentProvider, Callback, Closeable
-{
- private static final Logger LOG = LoggerFactory.getLogger(InputStreamContentProvider.class);
-
- private final InputStreamContentProviderIterator iterator = new InputStreamContentProviderIterator();
- private final InputStream stream;
- private final int bufferSize;
- private final boolean autoClose;
-
- public InputStreamContentProvider(InputStream stream)
- {
- this(stream, 4096);
- }
-
- public InputStreamContentProvider(InputStream stream, int bufferSize)
- {
- this(stream, bufferSize, true);
- }
-
- public InputStreamContentProvider(InputStream stream, int bufferSize, boolean autoClose)
- {
- this.stream = stream;
- this.bufferSize = bufferSize;
- this.autoClose = autoClose;
- }
-
- @Override
- public long getLength()
- {
- return -1;
- }
-
- /**
- * Callback method invoked just after having read from the stream,
- * but before returning the iteration element (a {@link ByteBuffer}
- * to the caller.
- *
- * Subclasses may override this method to copy the content read from
- * the stream to another location (a file, or in memory if the content
- * is known to fit).
- *
- * @param buffer the byte array containing the bytes read
- * @param offset the offset from where bytes should be read
- * @param length the length of the bytes read
- * @return a {@link ByteBuffer} wrapping the byte array
- */
- protected ByteBuffer onRead(byte[] buffer, int offset, int length)
- {
- if (length <= 0)
- return BufferUtil.EMPTY_BUFFER;
- return ByteBuffer.wrap(buffer, offset, length);
- }
-
- /**
- * Callback method invoked when an exception is thrown while reading
- * from the stream.
- *
- * @param failure the exception thrown while reading from the stream.
- */
- protected void onReadFailure(Throwable failure)
- {
- }
-
- @Override
- public Iterator iterator()
- {
- return iterator;
- }
-
- @Override
- public void close()
- {
- if (autoClose)
- {
- try
- {
- stream.close();
- }
- catch (IOException x)
- {
- LOG.trace("IGNORED", x);
- }
- }
- }
-
- @Override
- public void failed(Throwable failure)
- {
- // TODO: forward the failure to the iterator.
- close();
- }
-
- /**
- * Iterating over an {@link InputStream} is tricky, because {@link #hasNext()} must return false
- * if the stream reads -1. However, we don't know what to return until we read the stream, which
- * means that stream reading must be performed by {@link #hasNext()}, which introduces a side-effect
- * on what is supposed to be a simple query method (with respect to the Query Command Separation
- * Principle).
- *
- * Alternatively, we could return {@code true} from {@link #hasNext()} even if we don't know that
- * we will read -1, but then when {@link #next()} reads -1 it must return an empty buffer.
- * However this is problematic, since GETs with no content indication would become GET with chunked
- * content, and not understood by servers.
- *
- * Therefore we need to make sure that {@link #hasNext()} does not perform any side effect (so that
- * it can be called multiple times) until {@link #next()} is called.
- */
- private class InputStreamContentProviderIterator implements Iterator, Closeable
- {
- private Throwable failure;
- private ByteBuffer buffer;
- private Boolean hasNext;
-
- @Override
- public boolean hasNext()
- {
- try
- {
- if (hasNext != null)
- return hasNext;
-
- byte[] bytes = new byte[bufferSize];
- int read = stream.read(bytes);
- if (LOG.isDebugEnabled())
- LOG.debug("Read {} bytes from {}", read, stream);
- if (read > 0)
- {
- hasNext = Boolean.TRUE;
- buffer = onRead(bytes, 0, read);
- return true;
- }
- else if (read < 0)
- {
- hasNext = Boolean.FALSE;
- buffer = null;
- close();
- return false;
- }
- else
- {
- hasNext = Boolean.TRUE;
- buffer = BufferUtil.EMPTY_BUFFER;
- return true;
- }
- }
- catch (Throwable x)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Failed to read", x);
- if (failure == null)
- {
- failure = x;
- onReadFailure(x);
- // Signal we have more content to cause a call to
- // next() which will throw NoSuchElementException.
- hasNext = Boolean.TRUE;
- buffer = null;
- close();
- return true;
- }
- throw new IllegalStateException();
- }
- }
-
- @Override
- public ByteBuffer next()
- {
- if (failure != null)
- {
- // Consume the failure so that calls to hasNext() will return false.
- hasNext = Boolean.FALSE;
- buffer = null;
- throw (NoSuchElementException)new NoSuchElementException().initCause(failure);
- }
- if (!hasNext())
- throw new NoSuchElementException();
-
- ByteBuffer result = buffer;
- if (result == null)
- {
- hasNext = Boolean.FALSE;
- buffer = null;
- throw new NoSuchElementException();
- }
- else
- {
- hasNext = null;
- buffer = null;
- return result;
- }
- }
-
- @Override
- public void remove()
- {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void close()
- {
- InputStreamContentProvider.this.close();
- }
- }
-}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java
deleted file mode 100644
index 302fa196379..00000000000
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java
+++ /dev/null
@@ -1,408 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License v. 2.0 which is available at
-// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-// ========================================================================
-//
-
-package org.eclipse.jetty.client.util;
-
-import java.io.ByteArrayOutputStream;
-import java.io.Closeable;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.eclipse.jetty.client.AsyncContentProvider;
-import org.eclipse.jetty.client.Synchronizable;
-import org.eclipse.jetty.client.api.ContentProvider;
-import org.eclipse.jetty.http.HttpField;
-import org.eclipse.jetty.http.HttpFields;
-import org.eclipse.jetty.http.HttpHeader;
-import org.eclipse.jetty.io.RuntimeIOException;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.IO;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
A {@link ContentProvider} for form uploads with the {@code "multipart/form-data"}
- * content type.
- *
- * @deprecated use {@link MultiPartRequestContent} instead.
- */
-@Deprecated
-public class MultiPartContentProvider extends AbstractTypedContentProvider implements AsyncContentProvider, Closeable
-{
- private static final Logger LOG = LoggerFactory.getLogger(MultiPartContentProvider.class);
- private static final byte[] COLON_SPACE_BYTES = new byte[]{':', ' '};
- private static final byte[] CR_LF_BYTES = new byte[]{'\r', '\n'};
-
- private final List parts = new ArrayList<>();
- private final ByteBuffer firstBoundary;
- private final ByteBuffer middleBoundary;
- private final ByteBuffer onlyBoundary;
- private final ByteBuffer lastBoundary;
- private final AtomicBoolean closed = new AtomicBoolean();
- private Listener listener;
- private long length = -1;
-
- public MultiPartContentProvider()
- {
- this(makeBoundary());
- }
-
- public MultiPartContentProvider(String boundary)
- {
- super("multipart/form-data; boundary=" + boundary);
- String firstBoundaryLine = "--" + boundary + "\r\n";
- this.firstBoundary = ByteBuffer.wrap(firstBoundaryLine.getBytes(StandardCharsets.US_ASCII));
- String middleBoundaryLine = "\r\n" + firstBoundaryLine;
- this.middleBoundary = ByteBuffer.wrap(middleBoundaryLine.getBytes(StandardCharsets.US_ASCII));
- String onlyBoundaryLine = "--" + boundary + "--\r\n";
- this.onlyBoundary = ByteBuffer.wrap(onlyBoundaryLine.getBytes(StandardCharsets.US_ASCII));
- String lastBoundaryLine = "\r\n" + onlyBoundaryLine;
- this.lastBoundary = ByteBuffer.wrap(lastBoundaryLine.getBytes(StandardCharsets.US_ASCII));
- }
-
- private static String makeBoundary()
- {
- StringBuilder builder = new StringBuilder("JettyHttpClientBoundary");
- builder.append(Long.toString(System.identityHashCode(builder), 36));
- builder.append(Long.toString(System.identityHashCode(Thread.currentThread()), 36));
- builder.append(Long.toString(System.nanoTime(), 36));
- return builder.toString();
- }
-
- /**
- *
Adds a field part with the given {@code name} as field name, and the given
- * {@code content} as part content.
- *
The {@code Content-Type} of this part will be obtained from:
- *
- *
the {@code Content-Type} header in the {@code fields} parameter; otherwise
- *
the {@link org.eclipse.jetty.client.api.ContentProvider.Typed#getContentType()} method if the {@code content} parameter
- * implements {@link org.eclipse.jetty.client.api.ContentProvider.Typed}; otherwise
- *
"text/plain"
- *
- *
- * @param name the part name
- * @param content the part content
- * @param fields the headers associated with this part
- */
- public void addFieldPart(String name, ContentProvider content, HttpFields fields)
- {
- addPart(new Part(name, null, "text/plain", content, fields));
- }
-
- /**
- *
Adds a file part with the given {@code name} as field name, the given
- * {@code fileName} as file name, and the given {@code content} as part content.
- *
The {@code Content-Type} of this part will be obtained from:
- *
- *
the {@code Content-Type} header in the {@code fields} parameter; otherwise
- *
the {@link org.eclipse.jetty.client.api.ContentProvider.Typed#getContentType()} method if the {@code content} parameter
- * implements {@link org.eclipse.jetty.client.api.ContentProvider.Typed}; otherwise
- *
"application/octet-stream"
- *
- *
- * @param name the part name
- * @param fileName the file name associated to this part
- * @param content the part content
- * @param fields the headers associated with this part
- */
- public void addFilePart(String name, String fileName, ContentProvider content, HttpFields fields)
- {
- addPart(new Part(name, fileName, "application/octet-stream", content, fields));
- }
-
- private void addPart(Part part)
- {
- parts.add(part);
- if (LOG.isDebugEnabled())
- LOG.debug("Added {}", part);
- }
-
- @Override
- public void setListener(Listener listener)
- {
- this.listener = listener;
- if (closed.get())
- this.length = calculateLength();
- }
-
- private long calculateLength()
- {
- // Compute the length, if possible.
- if (parts.isEmpty())
- {
- return onlyBoundary.remaining();
- }
- else
- {
- long result = 0;
- for (int i = 0; i < parts.size(); ++i)
- {
- result += (i == 0) ? firstBoundary.remaining() : middleBoundary.remaining();
- Part part = parts.get(i);
- long partLength = part.length;
- result += partLength;
- if (partLength < 0)
- {
- result = -1;
- break;
- }
- }
- if (result > 0)
- result += lastBoundary.remaining();
- return result;
- }
- }
-
- @Override
- public long getLength()
- {
- return length;
- }
-
- @Override
- public Iterator iterator()
- {
- return new MultiPartIterator();
- }
-
- @Override
- public void close()
- {
- closed.compareAndSet(false, true);
- }
-
- private static class Part
- {
- private final String name;
- private final String fileName;
- private final String contentType;
- private final ContentProvider content;
- private final HttpFields fields;
- private final ByteBuffer headers;
- private final long length;
-
- private Part(String name, String fileName, String contentType, ContentProvider content, HttpFields fields)
- {
- this.name = name;
- this.fileName = fileName;
- this.contentType = contentType;
- this.content = content;
- this.fields = fields;
- this.headers = headers();
- this.length = content.getLength() < 0 ? -1 : headers.remaining() + content.getLength();
- }
-
- private ByteBuffer headers()
- {
- try
- {
- // Compute the Content-Disposition.
- String contentDisposition = "Content-Disposition: form-data; name=\"" + name + "\"";
- if (fileName != null)
- contentDisposition += "; filename=\"" + fileName + "\"";
- contentDisposition += "\r\n";
-
- // Compute the Content-Type.
- String contentType = fields == null ? null : fields.get(HttpHeader.CONTENT_TYPE);
- if (contentType == null)
- {
- if (content instanceof Typed)
- contentType = ((Typed)content).getContentType();
- else
- contentType = this.contentType;
- }
- contentType = "Content-Type: " + contentType + "\r\n";
-
- if (fields == null || fields.size() == 0)
- {
- String headers = contentDisposition;
- headers += contentType;
- headers += "\r\n";
- return ByteBuffer.wrap(headers.getBytes(StandardCharsets.UTF_8));
- }
-
- ByteArrayOutputStream buffer = new ByteArrayOutputStream((fields.size() + 1) * contentDisposition.length());
- buffer.write(contentDisposition.getBytes(StandardCharsets.UTF_8));
- buffer.write(contentType.getBytes(StandardCharsets.UTF_8));
- for (HttpField field : fields)
- {
- if (HttpHeader.CONTENT_TYPE.equals(field.getHeader()))
- continue;
- buffer.write(field.getName().getBytes(StandardCharsets.US_ASCII));
- buffer.write(COLON_SPACE_BYTES);
- String value = field.getValue();
- if (value != null)
- buffer.write(value.getBytes(StandardCharsets.UTF_8));
- buffer.write(CR_LF_BYTES);
- }
- buffer.write(CR_LF_BYTES);
- return ByteBuffer.wrap(buffer.toByteArray());
- }
- catch (IOException x)
- {
- throw new RuntimeIOException(x);
- }
- }
-
- @Override
- public String toString()
- {
- return String.format("%s@%x[name=%s,fileName=%s,length=%d,headers=%s]",
- getClass().getSimpleName(),
- hashCode(),
- name,
- fileName,
- content.getLength(),
- fields);
- }
- }
-
- private class MultiPartIterator implements Iterator, Synchronizable, Callback, Closeable
- {
- private Iterator iterator;
- private int index;
- private State state = State.FIRST_BOUNDARY;
-
- @Override
- public boolean hasNext()
- {
- return state != State.COMPLETE;
- }
-
- @Override
- public ByteBuffer next()
- {
- while (true)
- {
- switch (state)
- {
- case FIRST_BOUNDARY:
- {
- if (parts.isEmpty())
- {
- state = State.COMPLETE;
- return onlyBoundary.slice();
- }
- else
- {
- state = State.HEADERS;
- return firstBoundary.slice();
- }
- }
- case HEADERS:
- {
- Part part = parts.get(index);
- ContentProvider content = part.content;
- if (content instanceof AsyncContentProvider)
- ((AsyncContentProvider)content).setListener(listener);
- iterator = content.iterator();
- state = State.CONTENT;
- return part.headers.slice();
- }
- case CONTENT:
- {
- if (iterator.hasNext())
- return iterator.next();
- ++index;
- if (index < parts.size())
- {
- state = State.MIDDLE_BOUNDARY;
- if (iterator instanceof Closeable)
- IO.close((Closeable)iterator);
- }
- else
- {
- state = State.LAST_BOUNDARY;
- }
- break;
- }
- case MIDDLE_BOUNDARY:
- {
- state = State.HEADERS;
- return middleBoundary.slice();
- }
- case LAST_BOUNDARY:
- {
- state = State.COMPLETE;
- return lastBoundary.slice();
- }
- case COMPLETE:
- {
- throw new NoSuchElementException();
- }
-
- default:
- throw new IllegalStateException(state.toString());
- }
- }
- }
-
- @Override
- public Object getLock()
- {
- if (iterator instanceof Synchronizable)
- return ((Synchronizable)iterator).getLock();
- return this;
- }
-
- @Override
- public void succeeded()
- {
- if (state == State.CONTENT && iterator instanceof Callback)
- ((Callback)iterator).succeeded();
- }
-
- @Override
- public void failed(Throwable x)
- {
- if (state == State.CONTENT && iterator instanceof Callback)
- ((Callback)iterator).failed(x);
- }
-
- @Override
- public void close() throws IOException
- {
- if (iterator instanceof Closeable)
- ((Closeable)iterator).close();
- }
- }
-
- private enum State
- {
- FIRST_BOUNDARY, HEADERS, CONTENT, MIDDLE_BOUNDARY, LAST_BOUNDARY, COMPLETE
- }
-}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/OutputStreamContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/OutputStreamContentProvider.java
deleted file mode 100644
index fa1fcf384b8..00000000000
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/OutputStreamContentProvider.java
+++ /dev/null
@@ -1,158 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License v. 2.0 which is available at
-// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-// ========================================================================
-//
-
-package org.eclipse.jetty.client.util;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.util.Iterator;
-
-import org.eclipse.jetty.client.AsyncContentProvider;
-import org.eclipse.jetty.client.api.ContentProvider;
-import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.client.api.Response;
-import org.eclipse.jetty.util.Callback;
-
-/**
- * A {@link ContentProvider} that provides content asynchronously through an {@link OutputStream}
- * similar to {@link DeferredContentProvider}.
- *
- * {@link OutputStreamContentProvider} can only be used in conjunction with
- * {@link Request#send(Response.CompleteListener)} (and not with its blocking counterpart {@link Request#send()})
- * because it provides content asynchronously.
- *
- * The deferred content is provided once by writing to the {@link #getOutputStream() output stream}
- * and then fully consumed.
- * Invocations to the {@link #iterator()} method after the first will return an "empty" iterator
- * because the stream has been consumed on the first invocation.
- * However, it is possible for subclasses to support multiple invocations of {@link #iterator()}
- * by overriding {@link #write(ByteBuffer)} and {@link #close()}, copying the bytes and making them
- * available for subsequent invocations.
- *
- * Content must be provided by writing to the {@link #getOutputStream() output stream}, that must be
- * {@link OutputStream#close() closed} when all content has been provided.
- *
- * Example usage:
- *
- * HttpClient httpClient = ...;
- *
- * // Use try-with-resources to autoclose the output stream
- * OutputStreamContentProvider content = new OutputStreamContentProvider();
- * try (OutputStream output = content.getOutputStream())
- * {
- * httpClient.newRequest("localhost", 8080)
- * .content(content)
- * .send(new Response.CompleteListener()
- * {
- * @Override
- * public void onComplete(Result result)
- * {
- * // Your logic here
- * }
- * });
- *
- * // At a later time...
- * output.write("some content".getBytes());
- * }
- *
- *
- * @deprecated use {@link OutputStreamRequestContent} instead
- */
-@Deprecated
-public class OutputStreamContentProvider implements AsyncContentProvider, Callback, Closeable
-{
- private final DeferredContentProvider deferred = new DeferredContentProvider();
- private final OutputStream output = new DeferredOutputStream();
-
- @Override
- public InvocationType getInvocationType()
- {
- return deferred.getInvocationType();
- }
-
- @Override
- public long getLength()
- {
- return deferred.getLength();
- }
-
- @Override
- public Iterator iterator()
- {
- return deferred.iterator();
- }
-
- @Override
- public void setListener(Listener listener)
- {
- deferred.setListener(listener);
- }
-
- public OutputStream getOutputStream()
- {
- return output;
- }
-
- protected void write(ByteBuffer buffer)
- {
- deferred.offer(buffer);
- }
-
- @Override
- public void close()
- {
- deferred.close();
- }
-
- @Override
- public void succeeded()
- {
- deferred.succeeded();
- }
-
- @Override
- public void failed(Throwable failure)
- {
- deferred.failed(failure);
- }
-
- private class DeferredOutputStream extends OutputStream
- {
- @Override
- public void write(int b) throws IOException
- {
- write(new byte[]{(byte)b}, 0, 1);
- }
-
- @Override
- public void write(byte[] b, int off, int len) throws IOException
- {
- OutputStreamContentProvider.this.write(ByteBuffer.wrap(b, off, len));
- flush();
- }
-
- @Override
- public void flush() throws IOException
- {
- deferred.flush();
- }
-
- @Override
- public void close() throws IOException
- {
- OutputStreamContentProvider.this.close();
- }
- }
-}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/PathContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/PathContentProvider.java
deleted file mode 100644
index d13ae2e7f31..00000000000
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/PathContentProvider.java
+++ /dev/null
@@ -1,188 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License v. 2.0 which is available at
-// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-// ========================================================================
-//
-
-package org.eclipse.jetty.client.util;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.channels.SeekableByteChannel;
-import java.nio.file.AccessDeniedException;
-import java.nio.file.Files;
-import java.nio.file.NoSuchFileException;
-import java.nio.file.Path;
-import java.nio.file.StandardOpenOption;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.jetty.client.api.ContentProvider;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.util.BufferUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
A {@link ContentProvider} for files using JDK 7's {@code java.nio.file} APIs.
- *
It is possible to specify, at the constructor, a buffer size used to read
- * content from the stream, by default 4096 bytes.
- * If a {@link ByteBufferPool} is provided via {@link #setByteBufferPool(ByteBufferPool)},
- * the buffer will be allocated from that pool, otherwise one buffer will be
- * allocated and used to read the file.
- *
- * @deprecated use {@link PathRequestContent} instead.
- */
-@Deprecated
-public class PathContentProvider extends AbstractTypedContentProvider
-{
- private static final Logger LOG = LoggerFactory.getLogger(PathContentProvider.class);
-
- private final Path filePath;
- private final long fileSize;
- private final int bufferSize;
- private ByteBufferPool bufferPool;
- private boolean useDirectByteBuffers = true;
-
- public PathContentProvider(Path filePath) throws IOException
- {
- this(filePath, 4096);
- }
-
- public PathContentProvider(Path filePath, int bufferSize) throws IOException
- {
- this("application/octet-stream", filePath, bufferSize);
- }
-
- public PathContentProvider(String contentType, Path filePath) throws IOException
- {
- this(contentType, filePath, 4096);
- }
-
- public PathContentProvider(String contentType, Path filePath, int bufferSize) throws IOException
- {
- super(contentType);
- if (!Files.isRegularFile(filePath))
- throw new NoSuchFileException(filePath.toString());
- if (!Files.isReadable(filePath))
- throw new AccessDeniedException(filePath.toString());
- this.filePath = filePath;
- this.fileSize = Files.size(filePath);
- this.bufferSize = bufferSize;
- }
-
- @Override
- public long getLength()
- {
- return fileSize;
- }
-
- @Override
- public boolean isReproducible()
- {
- return true;
- }
-
- public ByteBufferPool getByteBufferPool()
- {
- return bufferPool;
- }
-
- public void setByteBufferPool(ByteBufferPool byteBufferPool)
- {
- this.bufferPool = byteBufferPool;
- }
-
- public boolean isUseDirectByteBuffers()
- {
- return useDirectByteBuffers;
- }
-
- public void setUseDirectByteBuffers(boolean useDirectByteBuffers)
- {
- this.useDirectByteBuffers = useDirectByteBuffers;
- }
-
- @Override
- public Iterator iterator()
- {
- return new PathIterator();
- }
-
- private class PathIterator implements Iterator, Closeable
- {
- private ByteBuffer buffer;
- private SeekableByteChannel channel;
- private long position;
-
- @Override
- public boolean hasNext()
- {
- return position < getLength();
- }
-
- @Override
- public ByteBuffer next()
- {
- try
- {
- if (channel == null)
- {
- buffer = bufferPool == null
- ? BufferUtil.allocate(bufferSize, isUseDirectByteBuffers())
- : bufferPool.acquire(bufferSize, isUseDirectByteBuffers());
- channel = Files.newByteChannel(filePath, StandardOpenOption.READ);
- if (LOG.isDebugEnabled())
- LOG.debug("Opened file {}", filePath);
- }
-
- buffer.clear();
- int read = channel.read(buffer);
- if (read < 0)
- throw new NoSuchElementException();
-
- if (LOG.isDebugEnabled())
- LOG.debug("Read {} bytes from {}", read, filePath);
-
- position += read;
-
- buffer.flip();
- return buffer;
- }
- catch (NoSuchElementException x)
- {
- close();
- throw x;
- }
- catch (Throwable x)
- {
- close();
- throw (NoSuchElementException)new NoSuchElementException().initCause(x);
- }
- }
-
- @Override
- public void close()
- {
- try
- {
- if (bufferPool != null && buffer != null)
- bufferPool.release(buffer);
- if (channel != null)
- channel.close();
- }
- catch (Throwable x)
- {
- LOG.trace("IGNORED", x);
- }
- }
- }
-}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/StringContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/StringContentProvider.java
deleted file mode 100644
index 2d5c8e81589..00000000000
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/StringContentProvider.java
+++ /dev/null
@@ -1,51 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License v. 2.0 which is available at
-// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-// ========================================================================
-//
-
-package org.eclipse.jetty.client.util;
-
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-
-import org.eclipse.jetty.client.api.ContentProvider;
-
-/**
- * A {@link ContentProvider} for strings.
- *
- * It is possible to specify, at the constructor, an encoding used to convert
- * the string into bytes, by default UTF-8.
- *
- * @deprecated use {@link StringRequestContent} instead.
- */
-@Deprecated
-public class StringContentProvider extends BytesContentProvider
-{
- public StringContentProvider(String content)
- {
- this(content, StandardCharsets.UTF_8);
- }
-
- public StringContentProvider(String content, String encoding)
- {
- this(content, Charset.forName(encoding));
- }
-
- public StringContentProvider(String content, Charset charset)
- {
- this("text/plain;charset=" + charset.name(), content, charset);
- }
-
- public StringContentProvider(String contentType, String content, Charset charset)
- {
- super(contentType, content.getBytes(charset));
- }
-}
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesServerTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesServerTest.java
deleted file mode 100644
index cb7ed303813..00000000000
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesServerTest.java
+++ /dev/null
@@ -1,1950 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License v. 2.0 which is available at
-// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-// ========================================================================
-//
-
-package org.eclipse.jetty.client.ssl;
-
-import java.io.BufferedReader;
-import java.io.EOFException;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.net.SocketTimeoutException;
-import java.nio.ByteBuffer;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.SocketChannel;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLSocket;
-
-import jakarta.servlet.ServletInputStream;
-import jakarta.servlet.ServletOutputStream;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.client.ssl.SslBytesTest.TLSRecord.Type;
-import org.eclipse.jetty.http.HttpCompliance;
-import org.eclipse.jetty.http.HttpParser;
-import org.eclipse.jetty.io.Connection;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.io.ManagedSelector;
-import org.eclipse.jetty.io.SocketChannelEndPoint;
-import org.eclipse.jetty.io.ssl.SslConnection;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.HttpConnection;
-import org.eclipse.jetty.server.HttpConnectionFactory;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.SecureRequestCustomizer;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.server.SslConnectionFactory;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
-import org.eclipse.jetty.util.component.Dumpable;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.hamcrest.Matchers;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Assumptions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.EnabledOnJre;
-import org.junit.jupiter.api.condition.EnabledOnOs;
-import org.junit.jupiter.api.condition.JRE;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-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;
-import static org.junit.jupiter.api.Assertions.fail;
-import static org.junit.jupiter.api.condition.OS.LINUX;
-
-// Other JREs have slight differences in how TLS work
-// and this test expects a very specific TLS behavior.
-@EnabledOnJre(JRE.JAVA_11)
-public class SslBytesServerTest extends SslBytesTest
-{
- private final AtomicInteger sslFills = new AtomicInteger();
- private final AtomicInteger sslFlushes = new AtomicInteger();
- private final AtomicInteger httpParses = new AtomicInteger();
- private final AtomicReference serverEndPoint = new AtomicReference<>();
- private final int idleTimeout = 2000;
- private ExecutorService threadPool;
- private Server server;
- private SslContextFactory.Server sslContextFactory;
- private int serverPort;
- private SSLContext sslContext;
- private SimpleProxy proxy;
- private Runnable idleHook;
-
- @BeforeEach
- public void init() throws Exception
- {
- QueuedThreadPool serverThreads = new QueuedThreadPool();
- serverThreads.setName("server");
- server = new Server(serverThreads);
-
- sslFills.set(0);
- sslFlushes.set(0);
- httpParses.set(0);
- serverEndPoint.set(null);
-
- File keyStore = MavenTestingUtils.getTestResourceFile("keystore.p12");
- sslContextFactory = new SslContextFactory.Server();
- // This whole test is very specific to how TLS < 1.3 works.
- sslContextFactory.setIncludeProtocols("TLSv1.2");
- sslContextFactory.setKeyStorePath(keyStore.getAbsolutePath());
- sslContextFactory.setKeyStorePassword("storepwd");
-
- HttpConnectionFactory httpFactory = new HttpConnectionFactory()
- {
- @Override
- public Connection newConnection(Connector connector, EndPoint endPoint)
- {
- return configure(new HttpConnection(getHttpConfiguration(), connector, endPoint, isRecordHttpComplianceViolations())
- {
- @Override
- protected HttpParser newHttpParser(HttpCompliance compliance)
- {
- return new HttpParser(newRequestHandler(), getHttpConfiguration().getRequestHeaderSize(), compliance)
- {
- @Override
- public boolean parseNext(ByteBuffer buffer)
- {
- httpParses.incrementAndGet();
- return super.parseNext(buffer);
- }
- };
- }
-
- @Override
- protected boolean onReadTimeout(Throwable timeout)
- {
- final Runnable idleHook = SslBytesServerTest.this.idleHook;
- if (idleHook != null)
- idleHook.run();
- return super.onReadTimeout(timeout);
- }
- }, connector, endPoint);
- }
- };
- httpFactory.getHttpConfiguration().addCustomizer(new SecureRequestCustomizer());
- SslConnectionFactory sslFactory = new SslConnectionFactory(sslContextFactory, httpFactory.getProtocol())
- {
- @Override
- protected SslConnection newSslConnection(Connector connector, EndPoint endPoint, SSLEngine engine)
- {
- return new SslConnection(connector.getByteBufferPool(), connector.getExecutor(), endPoint, engine)
- {
- @Override
- protected DecryptedEndPoint newDecryptedEndPoint()
- {
- return new DecryptedEndPoint()
- {
- @Override
- public int fill(ByteBuffer buffer) throws IOException
- {
- sslFills.incrementAndGet();
- return super.fill(buffer);
- }
-
- @Override
- public boolean flush(ByteBuffer... appOuts) throws IOException
- {
- sslFlushes.incrementAndGet();
- return super.flush(appOuts);
- }
- };
- }
- };
- }
- };
-
- ServerConnector connector = new ServerConnector(server, null, null, null, 1, 1, sslFactory, httpFactory)
- {
- @Override
- protected SocketChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException
- {
- SocketChannelEndPoint endPoint = super.newEndPoint(channel, selectSet, key);
- serverEndPoint.set(endPoint);
- return endPoint;
- }
- };
- connector.setIdleTimeout(idleTimeout);
- connector.setPort(0);
-
- server.addConnector(connector);
- server.setHandler(new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException
- {
- try
- {
- request.setHandled(true);
- String contentLength = request.getHeader("Content-Length");
- if (contentLength != null)
- {
- int length = Integer.parseInt(contentLength);
- ServletInputStream input = httpRequest.getInputStream();
- ServletOutputStream output = httpResponse.getOutputStream();
- byte[] buffer = new byte[32 * 1024];
- while (length > 0)
- {
- int read = input.read(buffer);
- if (read < 0)
- throw new EOFException();
- length -= read;
- if (target.startsWith("/echo"))
- output.write(buffer, 0, read);
- }
- }
- }
- catch (IOException x)
- {
- if (!(target.endsWith("suppress_exception")))
- throw x;
- }
- }
- });
- server.start();
- serverPort = connector.getLocalPort();
-
- sslContext = sslContextFactory.getSslContext();
-
- threadPool = Executors.newCachedThreadPool();
- proxy = new SimpleProxy(threadPool, "localhost", serverPort);
- proxy.start();
- logger.info("proxy:{} <==> server:{}", proxy.getPort(), serverPort);
- }
-
- @AfterEach
- public void destroy() throws Exception
- {
- if (proxy != null)
- proxy.stop();
- if (server != null)
- server.stop();
- if (threadPool != null)
- threadPool.shutdownNow();
- }
-
- @Test
- public void testHandshake() throws Exception
- {
- final SSLSocket client = newClient();
-
- Future
-
-
- org.eclipse.jetty.toolchain
- jetty-jakarta-servlet-api
- test
- org.eclipse.jettyjetty-servertest
-
- org.eclipse.jetty
- jetty-security
- test
- org.awaitilityawaitility
@@ -151,10 +140,5 @@
jetty-slf4j-impltest
-
- org.eclipse.jetty.toolchain
- jetty-test-helper
- test
-
diff --git a/jetty-client/src/main/java/module-info.java b/jetty-core/jetty-client/src/main/java/module-info.java
similarity index 100%
rename from jetty-client/src/main/java/module-info.java
rename to jetty-core/jetty-client/src/main/java/module-info.java
diff --git a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java
index 1515986a26f..7f400c93853 100644
--- a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java
+++ b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java
@@ -40,12 +40,10 @@ import java.util.function.Consumer;
import java.util.function.LongConsumer;
import java.util.function.Supplier;
-import org.eclipse.jetty.client.api.ContentProvider;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.api.Result;
-import org.eclipse.jetty.client.internal.RequestContentAdapter;
import org.eclipse.jetty.client.util.FutureResponseListener;
import org.eclipse.jetty.client.util.PathRequestContent;
import org.eclipse.jetty.http.HttpField;
@@ -672,28 +670,6 @@ public class HttpRequest implements Request
return this;
}
- @Override
- public ContentProvider getContent()
- {
- if (content instanceof RequestContentAdapter)
- return ((RequestContentAdapter)content).getContentProvider();
- return null;
- }
-
- @Override
- public Request content(ContentProvider content)
- {
- return content(content, null);
- }
-
- @Override
- public Request content(ContentProvider content, String contentType)
- {
- if (contentType != null)
- headers.put(HttpHeader.CONTENT_TYPE, contentType);
- return body(ContentProvider.toRequestContent(content));
- }
-
@Override
public Content getBody()
{
diff --git a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/api/Request.java b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/api/Request.java
index efae0d57a98..79a412093e7 100644
--- a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/api/Request.java
+++ b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/api/Request.java
@@ -242,30 +242,6 @@ public interface Request
*/
Map getAttributes();
- /**
- * @return the content provider of this request
- * @deprecated use {@link #getBody()} instead
- */
- @Deprecated
- ContentProvider getContent();
-
- /**
- * @param content the content provider of this request
- * @return this request object
- * @deprecated use {@link #body(Content)} instead
- */
- @Deprecated
- Request content(ContentProvider content);
-
- /**
- * @param content the content provider of this request
- * @param contentType the content type
- * @return this request object
- * @deprecated use {@link #body(Content)} instead
- */
- @Deprecated
- Request content(ContentProvider content, String contentType);
-
/**
* @return the request content of this request
*/
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/api/package-info.java b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/api/package-info.java
similarity index 100%
rename from jetty-client/src/main/java/org/eclipse/jetty/client/api/package-info.java
rename to jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/api/package-info.java
diff --git a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/dynamic/HttpClientTransportDynamic.java b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/dynamic/HttpClientTransportDynamic.java
index 62955ab24bd..26a07e00f92 100644
--- a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/dynamic/HttpClientTransportDynamic.java
+++ b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/dynamic/HttpClientTransportDynamic.java
@@ -55,9 +55,9 @@ import org.slf4j.LoggerFactory;
* // Configure the clientConnector.
*
* // Prepare the application protocols.
- * ClientConnectionFactory.Info h1 = HttpClientConnectionFactory.HTTP11;
+ * ClientConnectionFactory.Info h1 = HttpClientConnectionFactory.HTTP;
* HTTP2Client http2Client = new HTTP2Client(clientConnector);
- * ClientConnectionFactory.Info h2 = new ClientConnectionFactoryOverHTTP2.HTTP2(http2Client);
+ * ClientConnectionFactory.Info h2 = new ClientConnectionFactoryOverHTTP2.H2(http2Client);
*
* // Create the HttpClientTransportDynamic, preferring h2 over h1.
* HttpClientTransport transport = new HttpClientTransportDynamic(clientConnector, h2, h1);
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/package-info.java b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/package-info.java
similarity index 100%
rename from jetty-client/src/main/java/org/eclipse/jetty/client/package-info.java
rename to jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/package-info.java
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/package-info.java b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/util/package-info.java
similarity index 100%
rename from jetty-client/src/main/java/org/eclipse/jetty/client/util/package-info.java
rename to jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/util/package-info.java
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ClientConnectionCloseTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ClientConnectionCloseTest.java
index eed27ad1d92..f2663a54043 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ClientConnectionCloseTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ClientConnectionCloseTest.java
@@ -13,15 +13,11 @@
package org.eclipse.jetty.client;
-import java.io.IOException;
import java.io.InterruptedIOException;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import jakarta.servlet.ServletInputStream;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.http.HttpConnectionOverHTTP;
import org.eclipse.jetty.client.util.AsyncRequestContent;
@@ -29,8 +25,13 @@ import org.eclipse.jetty.client.util.StringRequestContent;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.server.Content;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Blocking;
+import org.eclipse.jetty.util.Callback;
+import org.eclipse.jetty.util.thread.Invocable.InvocationType;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
@@ -46,23 +47,15 @@ public class ClientConnectionCloseTest extends AbstractHttpClientServerTest
public void testClientConnectionCloseServerConnectionCloseClientClosesAfterExchange(Scenario scenario) throws Exception
{
byte[] data = new byte[128 * 1024];
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor(InvocationType.BLOCKING)
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
- baseRequest.setHandled(true);
-
- ServletInputStream input = request.getInputStream();
- while (true)
- {
- int read = input.read();
- if (read < 0)
- break;
- }
+ Content.consumeAll(request);
response.setContentLength(data.length);
- response.getOutputStream().write(data);
+ response.write(true, callback, ByteBuffer.wrap(data));
try
{
@@ -103,13 +96,11 @@ public class ClientConnectionCloseTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testClientConnectionCloseServerDoesNotRespondClientIdleTimeout(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, Response response, Callback callback)
{
- baseRequest.setHandled(true);
- request.startAsync();
// Do not respond.
}
});
@@ -147,24 +138,19 @@ public class ClientConnectionCloseTest extends AbstractHttpClientServerTest
public void testClientConnectionCloseServerPartialResponseClientIdleTimeout(Scenario scenario) throws Exception
{
long idleTimeout = 1000;
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor(InvocationType.BLOCKING)
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
- baseRequest.setHandled(true);
+ Content.consumeAll(request);
- ServletInputStream input = request.getInputStream();
- while (true)
+ try (Blocking.Callback block = Blocking.callback())
{
- int read = input.read();
- if (read < 0)
- break;
+ response.write(false, block, "Hello");
+ block.block();
}
- response.getOutputStream().print("Hello");
- response.flushBuffer();
-
try
{
Thread.sleep(2 * idleTimeout);
@@ -173,6 +159,8 @@ public class ClientConnectionCloseTest extends AbstractHttpClientServerTest
{
throw new InterruptedIOException();
}
+
+ callback.succeeded();
}
});
@@ -211,14 +199,17 @@ public class ClientConnectionCloseTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testClientConnectionCloseServerNoConnectionCloseClientCloses(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor(InvocationType.BLOCKING)
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
- baseRequest.setHandled(true);
response.setContentLength(0);
- response.flushBuffer();
+ try (Blocking.Callback block = Blocking.callback())
+ {
+ response.write(false, block);
+ block.block();
+ }
try
{
@@ -229,6 +220,7 @@ public class ClientConnectionCloseTest extends AbstractHttpClientServerTest
{
throw new InterruptedIOException();
}
+ callback.succeeded();
}
});
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionPoolTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionPoolTest.java
index f1650106a44..f65390db1c0 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionPoolTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionPoolTest.java
@@ -13,7 +13,6 @@
package org.eclipse.jetty.client;
-import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -25,9 +24,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
import java.util.stream.Stream;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.Connection;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Destination;
@@ -40,15 +36,19 @@ import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.io.ClientConnector;
+import org.eclipse.jetty.server.Content;
import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.Blocking;
+import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.SocketAddressResolver;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
@@ -134,41 +134,67 @@ public class ConnectionPoolTest
@ParameterizedTest
@MethodSource("pools")
+ @Disabled("fix this test")
public void test(ConnectionPoolFactory factory) throws Exception
{
start(factory.factory, new EmptyServerHandler()
{
@Override
- protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(org.eclipse.jetty.server.Request request, Response response) throws Throwable
{
switch (HttpMethod.fromString(request.getMethod()))
{
- case GET:
+ case GET ->
{
- int contentLength = request.getIntHeader("X-Download");
+ long contentLength = request.getHeaders().getLongField("X-Download");
if (contentLength > 0)
{
response.setContentLength(contentLength);
- response.getOutputStream().write(new byte[contentLength]);
+ try (Blocking.Callback callback = _blocking.callback())
+ {
+ response.write(true, callback, BufferUtil.allocate((int)contentLength));
+ callback.block();
+ }
}
- break;
}
- case POST:
+ case POST ->
{
- int contentLength = request.getContentLength();
+ long contentLength = request.getContentLength();
if (contentLength > 0)
response.setContentLength(contentLength);
- IO.copy(request.getInputStream(), response.getOutputStream());
- break;
- }
- default:
- {
- throw new IllegalStateException();
+ while (true)
+ {
+ Content content = request.readContent();
+ if (content == null)
+ {
+ try (Blocking.Runnable block = _blocking.runnable())
+ {
+ request.demandContent(block);
+ block.block();
+ continue;
+ }
+ }
+ if (content instanceof Content.Error error)
+ throw error.getCause();
+
+ if (content.hasRemaining())
+ {
+ try (Blocking.Callback callback = _blocking.callback())
+ {
+ response.write(true, callback, content.getByteBuffer());
+ callback.block();
+ }
+ }
+ content.release();
+ if (content.isLast())
+ break;
+ }
}
+ default -> throw new IllegalStateException();
}
- if (Boolean.parseBoolean(request.getHeader("X-Close")))
- response.setHeader("Connection", "close");
+ if (Boolean.parseBoolean(request.getHeaders().get("X-Close")))
+ response.getHeaders().put("Connection", "close");
}
});
@@ -204,12 +230,8 @@ public class ConnectionPoolTest
HttpMethod method = random.nextBoolean() ? HttpMethod.GET : HttpMethod.POST;
// Choose randomly whether to close the connection on the client or on the server.
- boolean clientClose = false;
- if (random.nextInt(100) < 1)
- clientClose = true;
- boolean serverClose = false;
- if (random.nextInt(100) < 1)
- serverClose = true;
+ boolean clientClose = random.nextInt(100) < 1;
+ boolean serverClose = random.nextInt(100) < 1;
int maxContentLength = 64 * 1024;
int contentLength = random.nextInt(maxContentLength) + 1;
@@ -230,15 +252,13 @@ public class ConnectionPoolTest
switch (method)
{
- case GET:
- request.headers(fields -> fields.put("X-Download", String.valueOf(contentLength)));
- break;
- case POST:
+ case GET -> request.headers(fields -> fields.put("X-Download", String.valueOf(contentLength)));
+ case POST ->
+ {
request.headers(fields -> fields.put(HttpHeader.CONTENT_LENGTH, String.valueOf(contentLength)));
request.body(new BytesRequestContent(new byte[contentLength]));
- break;
- default:
- throw new IllegalStateException();
+ }
+ default -> throw new IllegalStateException();
}
FutureResponseListener listener = new FutureResponseListener(request, contentLength);
@@ -403,16 +423,9 @@ public class ConnectionPoolTest
server.setHandler(new EmptyServerHandler()
{
@Override
- protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response) throws Exception
{
- try
- {
- barrier.await();
- }
- catch (Exception x)
- {
- throw new ServletException(x);
- }
+ barrier.await();
}
});
server.start();
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ContentResponseTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ContentResponseTest.java
index 8d209723c7a..cf7a593ec82 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ContentResponseTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ContentResponseTest.java
@@ -13,17 +13,17 @@
package org.eclipse.jetty.client;
-import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
import java.util.Random;
import java.util.concurrent.TimeUnit;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
@@ -39,13 +39,12 @@ public class ContentResponseTest extends AbstractHttpClientServerTest
{
final byte[] content = new byte[1024];
new Random().nextBytes(content);
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ public void process(Request request, Response response, Callback callback)
{
- baseRequest.setHandled(true);
- response.getOutputStream().write(content);
+ response.write(true, callback, ByteBuffer.wrap(content));
}
});
@@ -66,14 +65,13 @@ public class ContentResponseTest extends AbstractHttpClientServerTest
{
final String content = "The quick brown fox jumped over the lazy dog";
final String mediaType = "text/plain";
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ public void process(Request request, Response response, Callback callback)
{
- baseRequest.setHandled(true);
- response.setHeader(HttpHeader.CONTENT_TYPE.asString(), mediaType);
- response.getOutputStream().write(content.getBytes("UTF-8"));
+ response.getHeaders().put(HttpHeader.CONTENT_TYPE, mediaType);
+ response.write(true, callback, ByteBuffer.wrap(content.getBytes(StandardCharsets.UTF_8)));
}
});
@@ -96,14 +94,13 @@ public class ContentResponseTest extends AbstractHttpClientServerTest
final String mediaType = "text/plain";
final String encoding = "UTF-8";
final String contentType = mediaType + "; charset=" + encoding;
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
- baseRequest.setHandled(true);
- response.setHeader(HttpHeader.CONTENT_TYPE.asString(), contentType);
- response.getOutputStream().write(content.getBytes(encoding));
+ response.getHeaders().put(HttpHeader.CONTENT_TYPE, contentType);
+ response.write(true, callback, ByteBuffer.wrap(content.getBytes(encoding)));
}
});
@@ -126,14 +123,13 @@ public class ContentResponseTest extends AbstractHttpClientServerTest
final String mediaType = "text/plain";
final String encoding = "UTF-8";
final String contentType = mediaType + "; charset=\"" + encoding + "\"";
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
- baseRequest.setHandled(true);
- response.setHeader(HttpHeader.CONTENT_TYPE.asString(), contentType);
- response.getOutputStream().write(content.getBytes(encoding));
+ response.getHeaders().put(HttpHeader.CONTENT_TYPE, contentType);
+ response.write(true, callback, ByteBuffer.wrap(content.getBytes(encoding)));
}
});
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/EmptyServerHandler.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/EmptyServerHandler.java
index 32d71ee755c..effda3f800c 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/EmptyServerHandler.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/EmptyServerHandler.java
@@ -13,24 +13,36 @@
package org.eclipse.jetty.client;
-import java.io.IOException;
-
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Blocking;
+import org.eclipse.jetty.util.Callback;
-public class EmptyServerHandler extends AbstractHandler
+public class EmptyServerHandler extends Handler.Processor
{
- @Override
- public final void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected Blocking.Shared _blocking = new Blocking.Shared();
+
+ public EmptyServerHandler()
{
- jettyRequest.setHandled(true);
- service(target, jettyRequest, request, response);
+ super(InvocationType.BLOCKING);
}
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ @Override
+ public void process(Request request, Response response, Callback callback) throws Exception
+ {
+ try
+ {
+ service(request, response);
+ callback.succeeded();
+ }
+ catch (Throwable t)
+ {
+ callback.failed(t);
+ }
+ }
+
+ protected void service(Request request, Response response) throws Throwable
{
}
}
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HostnameVerificationTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HostnameVerificationTest.java
index 8615adccabe..4aee54de58f 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HostnameVerificationTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HostnameVerificationTest.java
@@ -13,24 +13,24 @@
package org.eclipse.jetty.client;
-import java.io.IOException;
import java.security.cert.CertificateException;
import java.util.concurrent.ExecutionException;
import javax.net.ssl.SSLHandshakeException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
import org.eclipse.jetty.io.ClientConnector;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
-import org.eclipse.jetty.server.handler.DefaultHandler;
+import org.eclipse.jetty.util.Blocking;
+import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.hamcrest.Matchers;
@@ -71,13 +71,15 @@ public class HostnameVerificationTest
SslConnectionFactory ssl = new SslConnectionFactory(serverSslContextFactory, http.getProtocol());
connector = new ServerConnector(server, 1, 1, ssl, http);
server.addConnector(connector);
- server.setHandler(new DefaultHandler()
+ server.setHandler(new Handler.Processor()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
- baseRequest.setHandled(true);
- response.getWriter().write("foobar");
+ try (Blocking.Callback blocker = Blocking.callback())
+ {
+ response.write(true, blocker, "foobar");
+ }
}
});
server.start();
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpAuthenticationStoreTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpAuthenticationStoreTest.java
index 70eb6fdbe0b..d038deec0a6 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpAuthenticationStoreTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpAuthenticationStoreTest.java
@@ -27,7 +27,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
public class HttpAuthenticationStoreTest
{
@Test
- public void testFindAuthenticationWithDefaultHTTPPort() throws Exception
+ public void testFindAuthenticationWithDefaultHTTPPort()
{
AuthenticationStore store = new HttpAuthenticationStore();
@@ -50,7 +50,7 @@ public class HttpAuthenticationStoreTest
}
@Test
- public void testFindAuthenticationResultWithDefaultHTTPPort() throws Exception
+ public void testFindAuthenticationResultWithDefaultHTTPPort()
{
AuthenticationStore store = new HttpAuthenticationStore();
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAsyncContentTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAsyncContentTest.java
index ab13f5a2fb2..0e0ef86bc85 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAsyncContentTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAsyncContentTest.java
@@ -13,11 +13,8 @@
package org.eclipse.jetty.client;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
+import java.io.OutputStream;
import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@@ -25,18 +22,10 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.function.LongConsumer;
import java.util.zip.GZIPOutputStream;
-import jakarta.servlet.AsyncContext;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.ServletOutputStream;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.Response;
-import org.eclipse.jetty.client.http.HttpChannelOverHTTP;
-import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
-import org.eclipse.jetty.client.http.HttpConnectionOverHTTP;
-import org.eclipse.jetty.client.http.HttpReceiverOverHTTP;
-import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.Blocking;
import org.eclipse.jetty.util.Callback;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
@@ -53,12 +42,16 @@ public class HttpClientAsyncContentTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(Request request, org.eclipse.jetty.server.Response response) throws Exception
{
- ServletOutputStream output = response.getOutputStream();
- output.write(65);
- output.flush();
- output.write(66);
+ try (Blocking.Callback blocker = _blocking.callback())
+ {
+ response.write(false, blocker, "A");
+ }
+ try (Blocking.Callback blocker = _blocking.callback())
+ {
+ response.write(false, blocker, "A");
+ }
}
});
@@ -107,6 +100,8 @@ public class HttpClientAsyncContentTest extends AbstractHttpClientServerTest
assertEquals(2, contentCount.get());
}
+ // TODO
+/*
@ParameterizedTest
@ArgumentsSource(ScenarioProvider.class)
public void testConcurrentAsyncContent(Scenario scenario) throws Exception
@@ -115,7 +110,7 @@ public class HttpClientAsyncContentTest extends AbstractHttpClientServerTest
startServer(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(Request request, org.eclipse.jetty.server.Response response) throws Exception
{
ServletOutputStream output = response.getOutputStream();
output.write(new byte[1024]);
@@ -201,17 +196,17 @@ public class HttpClientAsyncContentTest extends AbstractHttpClientServerTest
assertTrue(latch.await(5, TimeUnit.SECONDS));
}
-
+*/
@ParameterizedTest
@ArgumentsSource(ScenarioProvider.class)
public void testAsyncContentAbort(Scenario scenario) throws Exception
{
- start(scenario, new EmptyServerHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- response.getOutputStream().write(new byte[1024]);
+ response.write(true, callback, ByteBuffer.wrap(new byte[1024]));
}
});
@@ -235,10 +230,11 @@ public class HttpClientAsyncContentTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(Request request, org.eclipse.jetty.server.Response response) throws Exception
{
- response.setHeader("Content-Encoding", "gzip");
- GZIPOutputStream gzip = new GZIPOutputStream(response.getOutputStream());
+ response.getHeaders().put("Content-Encoding", "gzip");
+ OutputStream outputStream = org.eclipse.jetty.server.Response.asOutputStream(response);
+ GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
gzip.write(new byte[1024]);
gzip.finish();
}
@@ -268,10 +264,11 @@ public class HttpClientAsyncContentTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(Request request, org.eclipse.jetty.server.Response response) throws Exception
{
- response.setHeader("Content-Encoding", "gzip");
- try (GZIPOutputStream gzip = new GZIPOutputStream(response.getOutputStream()))
+ response.getHeaders().put("Content-Encoding", "gzip");
+ OutputStream outputStream = org.eclipse.jetty.server.Response.asOutputStream(response);
+ try (GZIPOutputStream gzip = new GZIPOutputStream(outputStream))
{
gzip.write(new byte[1024]);
}
@@ -313,6 +310,8 @@ public class HttpClientAsyncContentTest extends AbstractHttpClientServerTest
assertTrue(resultLatch.await(5, TimeUnit.SECONDS));
}
+ // TODO
+/*
@ParameterizedTest
@ArgumentsSource(ScenarioProvider.class)
public void testAsyncGzipContentAbortWhileDecodingWithDelayedDemand(Scenario scenario) throws Exception
@@ -333,13 +332,13 @@ public class HttpClientAsyncContentTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(Request request, org.eclipse.jetty.server.Response response) throws Exception
{
AsyncContext asyncContext = request.startAsync();
asyncContext.setTimeout(0);
asyncContextRef.set(asyncContext);
- response.setHeader("Content-Encoding", "gzip");
+ response.getHeaders().put("Content-Encoding", "gzip");
ServletOutputStream output = response.getOutputStream();
output.write(gzip1);
output.flush();
@@ -396,4 +395,5 @@ public class HttpClientAsyncContentTest extends AbstractHttpClientServerTest
assertTrue(resultLatch.await(555, TimeUnit.SECONDS));
}
+*/
}
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java
index f0d6a4eb178..397bb4672a3 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java
@@ -13,67 +13,21 @@
package org.eclipse.jetty.client;
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.IntFunction;
-
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.client.api.Authentication;
-import org.eclipse.jetty.client.api.Authentication.HeaderInfo;
-import org.eclipse.jetty.client.api.AuthenticationStore;
-import org.eclipse.jetty.client.api.ContentResponse;
-import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.client.api.Response;
-import org.eclipse.jetty.client.api.Response.Listener;
-import org.eclipse.jetty.client.api.Result;
-import org.eclipse.jetty.client.util.AbstractAuthentication;
-import org.eclipse.jetty.client.util.AbstractRequestContent;
-import org.eclipse.jetty.client.util.AsyncRequestContent;
-import org.eclipse.jetty.client.util.BasicAuthentication;
-import org.eclipse.jetty.client.util.DigestAuthentication;
-import org.eclipse.jetty.http.HttpHeader;
-import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.security.Authenticator;
-import org.eclipse.jetty.security.ConstraintMapping;
-import org.eclipse.jetty.security.ConstraintSecurityHandler;
-import org.eclipse.jetty.security.HashLoginService;
-import org.eclipse.jetty.security.LoginService;
-import org.eclipse.jetty.security.authentication.BasicAuthenticator;
-import org.eclipse.jetty.security.authentication.DigestAuthenticator;
-import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
-import org.eclipse.jetty.util.Attributes;
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.IO;
-import org.eclipse.jetty.util.URIUtil;
-import org.eclipse.jetty.util.security.Constraint;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.ArgumentsSource;
-import static org.eclipse.jetty.client.api.Authentication.ANY_REALM;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.equalToIgnoringCase;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+// TODO
+@Disabled
public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
{
+ @Test
+ public void testNeedToUpdateThisTest()
+ {
+ fail("This test needs to be updated to use Core version of Basic Auth (when available)");
+ }
+ /*
private String realm = "TestRealm";
public void startBasic(Scenario scenario, Handler handler) throws Exception
@@ -601,7 +555,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
// Always reply with a 401 to see if the client
// can handle an infinite authentication loop.
response.setStatus(HttpStatus.UNAUTHORIZED_401);
- response.setHeader(HttpHeader.WWW_AUTHENTICATE.asString(), authType);
+ response.getHeaders().put(HttpHeader.WWW_AUTHENTICATE, authType);
}
});
@@ -862,4 +816,5 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
}
}
}
+ */
}
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientChunkedContentTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientChunkedContentTest.java
index 61ee9cbdf5b..6e34696ab4f 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientChunkedContentTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientChunkedContentTest.java
@@ -19,7 +19,6 @@ import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
-import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -70,14 +69,10 @@ public class HttpClientChunkedContentTest
final CountDownLatch completeLatch = new CountDownLatch(1);
client.newRequest("localhost", server.getLocalPort())
.timeout(5, TimeUnit.SECONDS)
- .send(new Response.CompleteListener()
+ .send(result ->
{
- @Override
- public void onComplete(Result result)
- {
- resultRef.set(result);
- completeLatch.countDown();
- }
+ resultRef.set(result);
+ completeLatch.countDown();
});
try (Socket socket = server.accept())
@@ -123,26 +118,18 @@ public class HttpClientChunkedContentTest
final AtomicReference resultRef = new AtomicReference<>();
final CountDownLatch completeLatch = new CountDownLatch(1);
client.newRequest("localhost", server.getLocalPort())
- .onResponseContentAsync(new Response.AsyncContentListener()
+ .onResponseContentAsync((response, content, callback) ->
{
- @Override
- public void onContent(Response response, ByteBuffer content, Callback callback)
- {
- if (callbackRef.compareAndSet(null, callback))
- firstContentLatch.countDown();
- else
- callback.succeeded();
- }
+ if (callbackRef.compareAndSet(null, callback))
+ firstContentLatch.countDown();
+ else
+ callback.succeeded();
})
.timeout(5, TimeUnit.SECONDS)
- .send(new Response.CompleteListener()
+ .send(result ->
{
- @Override
- public void onComplete(Result result)
- {
- resultRef.set(result);
- completeLatch.countDown();
- }
+ resultRef.set(result);
+ completeLatch.countDown();
});
try (Socket socket = server.accept())
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientCorrelationDataTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientCorrelationDataTest.java
index f6a5ff8e6f9..b3c643ce386 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientCorrelationDataTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientCorrelationDataTest.java
@@ -13,14 +13,11 @@
package org.eclipse.jetty.client;
-import java.io.IOException;
import java.util.concurrent.TimeUnit;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
+import org.eclipse.jetty.server.Response;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
@@ -39,9 +36,9 @@ public class HttpClientCorrelationDataTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response)
{
- assertEquals(correlationData, request.getHeader(correlationName));
+ assertEquals(correlationData, request.getHeaders().get(correlationName));
}
});
client.getRequestListeners().add(new Request.Listener.Adapter()
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientCustomProxyTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientCustomProxyTest.java
index 96dd0b056a2..4321165ff5b 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientCustomProxyTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientCustomProxyTest.java
@@ -19,9 +19,6 @@ import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.Connection;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.http.HttpStatus;
@@ -32,9 +29,10 @@ import org.eclipse.jetty.server.AbstractConnectionFactory;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Promise;
@@ -82,16 +80,15 @@ public class HttpClientCustomProxyTest
{
final String serverHost = "server";
final int status = HttpStatus.NO_CONTENT_204;
- prepare(new AbstractHandler()
+ prepare(new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(Request request, Response response)
{
- baseRequest.setHandled(true);
- if (serverHost.equals(request.getServerName()))
+ if (serverHost.equals(Request.getServerName(request)))
response.setStatus(status);
else
- response.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE);
+ response.setStatus(HttpStatus.NOT_ACCEPTABLE_406);
}
});
@@ -107,7 +104,7 @@ public class HttpClientCustomProxyTest
assertEquals(status, response.getStatus());
}
- private class CAFEBABEProxy extends ProxyConfiguration.Proxy
+ private static class CAFEBABEProxy extends ProxyConfiguration.Proxy
{
private CAFEBABEProxy(Origin.Address address, boolean secure)
{
@@ -121,7 +118,7 @@ public class HttpClientCustomProxyTest
}
}
- private class CAFEBABEClientConnectionFactory implements ClientConnectionFactory
+ private static class CAFEBABEClientConnectionFactory implements ClientConnectionFactory
{
private final ClientConnectionFactory connectionFactory;
@@ -140,7 +137,7 @@ public class HttpClientCustomProxyTest
}
}
- private class CAFEBABEConnection extends AbstractConnection implements Callback
+ private static class CAFEBABEConnection extends AbstractConnection implements Callback
{
private final ClientConnectionFactory connectionFactory;
private final Map context;
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientGZIPTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientGZIPTest.java
index c9015a1f597..7509f510ae5 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientGZIPTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientGZIPTest.java
@@ -17,6 +17,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
+import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Random;
@@ -24,9 +25,6 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.zip.GZIPOutputStream;
-import jakarta.servlet.ServletOutputStream;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.util.InputStreamResponseListener;
@@ -34,7 +32,9 @@ import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.IO;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
@@ -56,10 +56,11 @@ public class HttpClientGZIPTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(Request request, org.eclipse.jetty.server.Response response) throws Exception
{
- response.setHeader("Content-Encoding", "gzip");
- GZIPOutputStream gzipOutput = new GZIPOutputStream(response.getOutputStream());
+ response.getHeaders().put("Content-Encoding", "gzip");
+
+ GZIPOutputStream gzipOutput = new GZIPOutputStream(org.eclipse.jetty.server.Response.asOutputStream(response));
gzipOutput.write(data);
gzipOutput.finish();
}
@@ -82,21 +83,19 @@ public class HttpClientGZIPTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(Request request, org.eclipse.jetty.server.Response response) throws Exception
{
- response.setHeader("Content-Encoding", "gzip");
+ response.getHeaders().put("Content-Encoding", "gzip");
ByteArrayOutputStream gzipData = new ByteArrayOutputStream();
GZIPOutputStream gzipOutput = new GZIPOutputStream(gzipData);
gzipOutput.write(data);
gzipOutput.finish();
- ServletOutputStream output = response.getOutputStream();
byte[] gzipBytes = gzipData.toByteArray();
for (byte gzipByte : gzipBytes)
{
- output.write(gzipByte);
- output.flush();
+ org.eclipse.jetty.server.Response.write(response, false, ByteBuffer.wrap(new byte[]{gzipByte}));
sleep(100);
}
}
@@ -115,12 +114,12 @@ public class HttpClientGZIPTest extends AbstractHttpClientServerTest
public void testGZIPContentSentTwiceInOneWrite(Scenario scenario) throws Exception
{
final byte[] data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- start(scenario, new EmptyServerHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, org.eclipse.jetty.server.Response response, Callback callback) throws Exception
{
- response.setHeader("Content-Encoding", "gzip");
+ response.getHeaders().put("Content-Encoding", "gzip");
ByteArrayOutputStream gzipData = new ByteArrayOutputStream();
GZIPOutputStream gzipOutput = new GZIPOutputStream(gzipData);
@@ -131,8 +130,7 @@ public class HttpClientGZIPTest extends AbstractHttpClientServerTest
byte[] content = Arrays.copyOf(gzipBytes, 2 * gzipBytes.length);
System.arraycopy(gzipBytes, 0, content, gzipBytes.length, gzipBytes.length);
- ServletOutputStream output = response.getOutputStream();
- output.write(content);
+ response.write(true, callback, ByteBuffer.wrap(content));
}
});
@@ -169,9 +167,9 @@ public class HttpClientGZIPTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(Request request, org.eclipse.jetty.server.Response response) throws Exception
{
- response.setHeader("Content-Encoding", "gzip");
+ response.getHeaders().put("Content-Encoding", "gzip");
ByteArrayOutputStream gzipData = new ByteArrayOutputStream();
GZIPOutputStream gzipOutput = new GZIPOutputStream(gzipData);
@@ -182,14 +180,11 @@ public class HttpClientGZIPTest extends AbstractHttpClientServerTest
byte[] chunk1 = Arrays.copyOfRange(gzipBytes, 0, gzipBytes.length - fragment);
byte[] chunk2 = Arrays.copyOfRange(gzipBytes, gzipBytes.length - fragment, gzipBytes.length);
- ServletOutputStream output = response.getOutputStream();
- output.write(chunk1);
- output.flush();
+ org.eclipse.jetty.server.Response.write(response, false, ByteBuffer.wrap(chunk1));
sleep(500);
- output.write(chunk2);
- output.flush();
+ org.eclipse.jetty.server.Response.write(response, true, ByteBuffer.wrap(chunk2));
}
});
@@ -205,14 +200,14 @@ public class HttpClientGZIPTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testGZIPContentCorrupted(Scenario scenario) throws Exception
{
- start(scenario, new EmptyServerHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- response.setHeader("Content-Encoding", "gzip");
+ response.getHeaders().put("Content-Encoding", "gzip");
// Not gzipped, will cause the client to blow up.
- response.getOutputStream().print("0123456789");
+ response.write(true, callback, "0123456789");
}
});
@@ -237,11 +232,11 @@ public class HttpClientGZIPTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(Request request, org.eclipse.jetty.server.Response response) throws Exception
{
response.setContentType("text/plain;charset=" + StandardCharsets.US_ASCII.name());
- response.setHeader(HttpHeader.CONTENT_ENCODING.asString(), "gzip");
- GZIPOutputStream gzip = new GZIPOutputStream(response.getOutputStream());
+ response.getHeaders().put(HttpHeader.CONTENT_ENCODING, "gzip");
+ GZIPOutputStream gzip = new GZIPOutputStream(org.eclipse.jetty.server.Response.asOutputStream(response));
gzip.write(content);
gzip.finish();
}
@@ -279,11 +274,11 @@ public class HttpClientGZIPTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(Request request, org.eclipse.jetty.server.Response response) throws Exception
{
response.setContentType("text/plain;charset=" + StandardCharsets.US_ASCII.name());
- response.setHeader(HttpHeader.CONTENT_ENCODING.asString(), "gzip");
- GZIPOutputStream gzip = new GZIPOutputStream(response.getOutputStream());
+ response.getHeaders().put(HttpHeader.CONTENT_ENCODING, "gzip");
+ GZIPOutputStream gzip = new GZIPOutputStream(org.eclipse.jetty.server.Response.asOutputStream(response));
gzip.write(content);
gzip.finish();
}
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientIdleTimeoutTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientIdleTimeoutTest.java
index feff9462a66..2884f191dc5 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientIdleTimeoutTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientIdleTimeoutTest.java
@@ -13,20 +13,20 @@
package org.eclipse.jetty.client;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import jakarta.servlet.http.Cookie;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
import org.eclipse.jetty.client.http.HttpConnectionOverHTTP;
+import org.eclipse.jetty.http.HttpCookie;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
@@ -68,19 +68,19 @@ public class HttpClientIdleTimeoutTest
start(new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, Response response)
{
- Cookie[] cookies = request.getCookies();
- if (cookies == null || cookies.length == 0)
+ List cookies = Request.getCookies(request);
+ if (cookies == null || cookies.size() == 0)
{
// Send a cookie in the first response.
- response.addCookie(new Cookie("name", "value"));
+ Response.addCookie(response, new HttpCookie("name", "value"));
}
else
{
// Verify that there is only one cookie, i.e.
// that the request has not been normalized twice.
- assertEquals(1, cookies.length);
+ assertEquals(1, cookies.size());
}
}
});
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientProxyProtocolTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientProxyProtocolTest.java
index 52b3819c234..b26c9b25218 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientProxyProtocolTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientProxyProtocolTest.java
@@ -13,14 +13,11 @@
package org.eclipse.jetty.client;
-import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Destination;
import org.eclipse.jetty.http.HttpHeader;
@@ -32,8 +29,10 @@ import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.ProxyConnectionFactory;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
@@ -86,13 +85,13 @@ public class HttpClientProxyProtocolTest
@Test
public void testClientProxyProtocolV1() throws Exception
{
- startServer(new EmptyServerHandler()
+ startServer(new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
response.setContentType(MimeTypes.Type.TEXT_PLAIN.asString());
- response.getOutputStream().print(request.getRemotePort());
+ response.write(true, callback, String.valueOf(Request.getRemotePort(request)));
}
});
startClient();
@@ -124,13 +123,13 @@ public class HttpClientProxyProtocolTest
@Test
public void testClientProxyProtocolV2() throws Exception
{
- startServer(new EmptyServerHandler()
+ startServer(new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
response.setContentType(MimeTypes.Type.TEXT_PLAIN.asString());
- response.getOutputStream().print(request.getRemotePort());
+ response.write(true, callback, String.valueOf(Request.getRemotePort(request)));
}
});
startClient();
@@ -165,21 +164,21 @@ public class HttpClientProxyProtocolTest
int typeTLS = 0x20;
String tlsVersion = "TLSv1.3";
byte[] tlsVersionBytes = tlsVersion.getBytes(StandardCharsets.US_ASCII);
- startServer(new EmptyServerHandler()
+ startServer(new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
- EndPoint endPoint = jettyRequest.getHttpChannel().getEndPoint();
+ EndPoint endPoint = request.getConnectionMetaData().getConnection().getEndPoint();
assertTrue(endPoint instanceof ProxyConnectionFactory.ProxyEndPoint);
ProxyConnectionFactory.ProxyEndPoint proxyEndPoint = (ProxyConnectionFactory.ProxyEndPoint)endPoint;
- if (target.equals("/tls_version"))
+ if (request.getPathInContext().equals("/tls_version"))
{
assertNotNull(proxyEndPoint.getTLV(typeTLS));
assertEquals(tlsVersion, proxyEndPoint.getAttribute(ProxyConnectionFactory.TLS_VERSION));
}
response.setContentType(MimeTypes.Type.TEXT_PLAIN.asString());
- response.getOutputStream().print(request.getRemotePort());
+ response.write(true, callback, String.valueOf(Request.getRemotePort(request)));
}
});
startClient();
@@ -219,13 +218,13 @@ public class HttpClientProxyProtocolTest
@Test
public void testProxyProtocolWrappingHTTPProxy() throws Exception
{
- startServer(new EmptyServerHandler()
+ startServer(new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
response.setContentType(MimeTypes.Type.TEXT_PLAIN.asString());
- response.getOutputStream().print(request.getRemotePort());
+ response.write(true, callback, String.valueOf(Request.getRemotePort(request)));
}
});
startClient();
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientProxyTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientProxyTest.java
index d8ab7707a3b..fefe462df57 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientProxyTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientProxyTest.java
@@ -13,23 +13,21 @@
package org.eclipse.jetty.client;
-import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.util.BasicAuthentication;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
@@ -43,18 +41,17 @@ public class HttpClientProxyTest extends AbstractHttpClientServerTest
{
final String serverHost = "server";
final int status = HttpStatus.NO_CONTENT_204;
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response)
{
- baseRequest.setHandled(true);
- if (!URI.create(baseRequest.getHttpURI().toString()).isAbsolute())
- response.setStatus(HttpServletResponse.SC_USE_PROXY);
- else if (serverHost.equals(request.getServerName()))
+ if (!URI.create(request.getHttpURI().toString()).isAbsolute())
+ response.setStatus(HttpStatus.USE_PROXY_305);
+ else if (serverHost.equals(org.eclipse.jetty.server.Request.getServerName(request)))
response.setStatus(status);
else
- response.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE);
+ response.setStatus(HttpStatus.NOT_ACCEPTABLE_406);
}
});
@@ -80,17 +77,16 @@ public class HttpClientProxyTest extends AbstractHttpClientServerTest
final String serverHost = "server";
final String realm = "test_realm";
final int status = HttpStatus.NO_CONTENT_204;
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response)
{
- baseRequest.setHandled(true);
- String authorization = request.getHeader(HttpHeader.PROXY_AUTHORIZATION.asString());
+ String authorization = request.getHeaders().get(HttpHeader.PROXY_AUTHORIZATION.asString());
if (authorization == null)
{
response.setStatus(HttpStatus.PROXY_AUTHENTICATION_REQUIRED_407);
- response.setHeader(HttpHeader.PROXY_AUTHENTICATE.asString(), "Basic realm=\"" + realm + "\"");
+ response.getHeaders().put(HttpHeader.PROXY_AUTHENTICATE, "Basic realm=\"" + realm + "\"");
}
else
{
@@ -162,19 +158,20 @@ public class HttpClientProxyTest extends AbstractHttpClientServerTest
int serverPort = HttpScheme.HTTP.is(scenario.getScheme()) ? 80 : 443;
String realm = "test_realm";
int status = HttpStatus.NO_CONTENT_204;
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ public void process(org.eclipse.jetty.server.Request request, Response response, Callback callback)
{
- baseRequest.setHandled(true);
+ String target = request.getPathInContext();
if (target.startsWith("/proxy"))
{
- String authorization = request.getHeader(HttpHeader.PROXY_AUTHORIZATION.asString());
+ String authorization = request.getHeaders().get(HttpHeader.PROXY_AUTHORIZATION.asString());
if (authorization == null)
{
response.setStatus(HttpStatus.PROXY_AUTHENTICATION_REQUIRED_407);
- response.setHeader(HttpHeader.PROXY_AUTHENTICATE.asString(), "Basic realm=\"" + realm + "\"");
+ response.getHeaders().put(HttpHeader.PROXY_AUTHENTICATE, "Basic realm=\"" + realm + "\"");
+ callback.succeeded();
}
else
{
@@ -185,18 +182,21 @@ public class HttpClientProxyTest extends AbstractHttpClientServerTest
if (credentials.equals(attempt))
{
// Change also the host, to verify that proxy authentication works in this case too.
- response.sendRedirect(scenario.getScheme() + "://127.0.0.1:" + serverPort + "/server");
+ Response.sendRedirect(request, response, callback, scenario.getScheme() + "://127.0.0.1:" + serverPort + "/server");
+ return;
}
}
+ callback.succeeded();
}
}
else if (target.startsWith("/server"))
{
response.setStatus(status);
+ callback.succeeded();
}
else
{
- response.sendError(HttpStatus.INTERNAL_SERVER_ERROR_500);
+ Response.writeError(request, response, callback, HttpStatus.INTERNAL_SERVER_ERROR_500);
}
}
});
@@ -254,25 +254,24 @@ public class HttpClientProxyTest extends AbstractHttpClientServerTest
String proxyRealm = "proxyRealm";
String serverRealm = "serverRealm";
int status = HttpStatus.NO_CONTENT_204;
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response)
{
- baseRequest.setHandled(true);
- String authorization = request.getHeader(HttpHeader.PROXY_AUTHORIZATION.asString());
+ String authorization = request.getHeaders().get(HttpHeader.PROXY_AUTHORIZATION.asString());
if (authorization == null)
{
response.setStatus(HttpStatus.PROXY_AUTHENTICATION_REQUIRED_407);
- response.setHeader(HttpHeader.PROXY_AUTHENTICATE.asString(), "Basic realm=\"" + proxyRealm + "\"");
+ response.getHeaders().put(HttpHeader.PROXY_AUTHENTICATE, "Basic realm=\"" + proxyRealm + "\"");
}
else
{
- authorization = request.getHeader(HttpHeader.AUTHORIZATION.asString());
+ authorization = request.getHeaders().get(HttpHeader.AUTHORIZATION.asString());
if (authorization == null)
{
response.setStatus(HttpStatus.UNAUTHORIZED_401);
- response.setHeader(HttpHeader.WWW_AUTHENTICATE.asString(), "Basic realm=\"" + serverRealm + "\"");
+ response.getHeaders().put(HttpHeader.WWW_AUTHENTICATE, "Basic realm=\"" + serverRealm + "\"");
}
else
{
@@ -327,25 +326,24 @@ public class HttpClientProxyTest extends AbstractHttpClientServerTest
String proxyRealm = "proxyRealm";
String serverRealm = "serverRealm";
int status = HttpStatus.NO_CONTENT_204;
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response)
{
- baseRequest.setHandled(true);
- String authorization = request.getHeader(HttpHeader.PROXY_AUTHORIZATION.asString());
+ String authorization = request.getHeaders().get(HttpHeader.PROXY_AUTHORIZATION.asString());
if (authorization == null)
{
response.setStatus(HttpStatus.PROXY_AUTHENTICATION_REQUIRED_407);
- response.setHeader(HttpHeader.PROXY_AUTHENTICATE.asString(), "Basic realm=\"" + proxyRealm + "\"");
+ response.getHeaders().put(HttpHeader.PROXY_AUTHENTICATE, "Basic realm=\"" + proxyRealm + "\"");
}
else
{
- authorization = request.getHeader(HttpHeader.AUTHORIZATION.asString());
+ authorization = request.getHeaders().get(HttpHeader.AUTHORIZATION.asString());
if (authorization == null)
{
response.setStatus(HttpStatus.UNAUTHORIZED_401);
- response.setHeader(HttpHeader.WWW_AUTHENTICATE.asString(), "Basic realm=\"" + serverRealm + "\"");
+ response.getHeaders().put(HttpHeader.WWW_AUTHENTICATE, "Basic realm=\"" + serverRealm + "\"");
}
else
{
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientRedirectTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientRedirectTest.java
index 3bf406a5878..17262dd73ac 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientRedirectTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientRedirectTest.java
@@ -13,7 +13,8 @@
package org.eclipse.jetty.client;
-import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.net.InetAddress;
import java.net.URLDecoder;
import java.net.UnknownHostException;
@@ -27,9 +28,6 @@ import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.api.Result;
@@ -37,8 +35,11 @@ import org.eclipse.jetty.client.util.ByteBufferRequestContent;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.toolchain.test.IO;
+import org.eclipse.jetty.util.Callback;
+import org.eclipse.jetty.util.Fields;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.params.ParameterizedTest;
@@ -271,10 +272,10 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, org.eclipse.jetty.server.Response response) throws Exception
{
response.setStatus(303);
- response.setHeader("Location", "ssh://localhost:" + connector.getLocalPort() + "/path");
+ response.getHeaders().put("Location", "ssh://localhost:" + connector.getLocalPort() + "/path");
}
});
@@ -439,23 +440,23 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest
public void testRedirectWithCorruptedBody(Scenario scenario) throws Exception
{
byte[] bytes = "ok".getBytes(StandardCharsets.UTF_8);
- start(scenario, new EmptyServerHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, org.eclipse.jetty.server.Response response, Callback callback) throws Exception
{
- if (target.startsWith("/redirect"))
+ if (request.getPathInContext().startsWith("/redirect"))
{
response.setStatus(HttpStatus.SEE_OTHER_303);
- response.setHeader(HttpHeader.LOCATION.asString(), scenario.getScheme() + "://localhost:" + connector.getLocalPort() + "/ok");
+ response.getHeaders().put(HttpHeader.LOCATION, scenario.getScheme() + "://localhost:" + connector.getLocalPort() + "/ok");
// Say that we send gzipped content, but actually don't.
- response.setHeader(HttpHeader.CONTENT_ENCODING.asString(), "gzip");
- response.getOutputStream().write("redirect".getBytes(StandardCharsets.UTF_8));
+ response.getHeaders().put(HttpHeader.CONTENT_ENCODING, "gzip");
+ response.write(true, callback, ByteBuffer.wrap("redirect".getBytes(StandardCharsets.UTF_8)));
}
else
{
response.setStatus(HttpStatus.OK_200);
- response.getOutputStream().write(bytes);
+ response.write(true, callback, ByteBuffer.wrap(bytes));
}
}
});
@@ -477,10 +478,10 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, org.eclipse.jetty.server.Response response) throws Exception
{
response.setStatus(HttpStatus.SEE_OTHER_303);
- response.setHeader(HttpHeader.LOCATION.asString(), request.getRequestURI());
+ response.getHeaders().put(HttpHeader.LOCATION, request.getHttpURI().asString());
}
});
@@ -499,13 +500,13 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, org.eclipse.jetty.server.Response response) throws Exception
{
try
{
Thread.sleep(200);
response.setStatus(HttpStatus.SEE_OTHER_303);
- response.setHeader(HttpHeader.LOCATION.asString(), "/" + counter.getAndIncrement());
+ response.getHeaders().put(HttpHeader.LOCATION, "/" + counter.getAndIncrement());
}
catch (InterruptedException x)
{
@@ -534,48 +535,35 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException
+ protected void service(Request request, org.eclipse.jetty.server.Response response) throws Exception
{
+ String target = request.getPathInContext();
if ("/one".equals(target))
{
response.setStatus(HttpStatus.SEE_OTHER_303);
- response.setHeader(HttpHeader.LOCATION.asString(), scenario.getScheme() + "://127.0.0.1:" + connector.getLocalPort() + "/two");
+ response.getHeaders().put(HttpHeader.LOCATION, scenario.getScheme() + "://127.0.0.1:" + connector.getLocalPort() + "/two");
}
else if ("/two".equals(target))
{
- try
- {
- // Send another request to "localhost", therefore reusing the
- // connection used for the first request, it must timeout.
- CountDownLatch latch = new CountDownLatch(1);
- client.newRequest("localhost", connector.getLocalPort())
- .scheme(scenario.getScheme())
- .path("/three")
- .timeout(timeout, TimeUnit.MILLISECONDS)
- .send(result ->
- {
- if (result.getFailure() instanceof TimeoutException)
- latch.countDown();
- });
- // Wait for the request to fail as it should.
- assertTrue(latch.await(2 * timeout, TimeUnit.MILLISECONDS));
- }
- catch (Throwable x)
- {
- throw new ServletException(x);
- }
+ // Send another request to "localhost", therefore reusing the
+ // connection used for the first request, it must timeout.
+ CountDownLatch latch = new CountDownLatch(1);
+ client.newRequest("localhost", connector.getLocalPort())
+ .scheme(scenario.getScheme())
+ .path("/three")
+ .timeout(timeout, TimeUnit.MILLISECONDS)
+ .send(result ->
+ {
+ if (result.getFailure() instanceof TimeoutException)
+ latch.countDown();
+ });
+ // Wait for the request to fail as it should.
+ assertTrue(latch.await(2 * timeout, TimeUnit.MILLISECONDS));
}
else if ("/three".equals(target))
{
- try
- {
- // The third request must timeout.
- Thread.sleep(2 * timeout);
- }
- catch (InterruptedException x)
- {
- throw new ServletException(x);
- }
+ // The third request must timeout.
+ Thread.sleep(2 * timeout);
}
}
});
@@ -597,31 +585,25 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException
+ protected void service(Request request, org.eclipse.jetty.server.Response response) throws Exception
{
- try
+ String serverURI = scenario.getScheme() + "://localhost:" + connector.getLocalPort();
+ String target = request.getPathInContext();
+ if ("/one".equals(target))
{
- String serverURI = scenario.getScheme() + "://localhost:" + connector.getLocalPort();
- if ("/one".equals(target))
- {
- Thread.sleep(timeout);
- response.setStatus(HttpStatus.SEE_OTHER_303);
- response.setHeader(HttpHeader.LOCATION.asString(), serverURI + "/two");
- }
- else if ("/two".equals(target))
- {
- Thread.sleep(timeout);
- response.setStatus(HttpStatus.SEE_OTHER_303);
- response.setHeader(HttpHeader.LOCATION.asString(), serverURI + "/three");
- }
- else if ("/three".equals(target))
- {
- Thread.sleep(2 * timeout);
- }
+ Thread.sleep(timeout);
+ response.setStatus(HttpStatus.SEE_OTHER_303);
+ response.getHeaders().put(HttpHeader.LOCATION, serverURI + "/two");
}
- catch (InterruptedException x)
+ else if ("/two".equals(target))
{
- throw new ServletException(x);
+ Thread.sleep(timeout);
+ response.setStatus(HttpStatus.SEE_OTHER_303);
+ response.getHeaders().put(HttpHeader.LOCATION, serverURI + "/three");
+ }
+ else if ("/three".equals(target))
+ {
+ Thread.sleep(2 * timeout);
}
}
});
@@ -688,34 +670,38 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest
private static class RedirectHandler extends EmptyServerHandler
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(Request request, org.eclipse.jetty.server.Response response) throws Exception
{
try
{
- String[] paths = target.split("/", 4);
+ Fields fields = Request.extractQueryParameters(request);
+
+ String[] paths = request.getPathInContext().split("/", 4);
int status = Integer.parseInt(paths[1]);
response.setStatus(status);
String host = paths[2];
String path = paths[3];
- boolean relative = Boolean.parseBoolean(request.getParameter("relative"));
- String location = relative ? "" : request.getScheme() + "://" + host + ":" + request.getServerPort();
+ boolean relative = Boolean.parseBoolean(fields.getValue("relative"));
+ String location = relative ? "" : request.getHttpURI().getScheme() + "://" + host + ":" + Request.getServerPort(request);
location += "/" + path;
- if (Boolean.parseBoolean(request.getParameter("decode")))
- location = URLDecoder.decode(location, "UTF-8");
+ if (Boolean.parseBoolean(fields.getValue("decode")))
+ location = URLDecoder.decode(location, StandardCharsets.UTF_8);
- response.setHeader("Location", location);
+ response.getHeaders().put("Location", location);
- if (Boolean.parseBoolean(request.getParameter("close")))
- response.setHeader("Connection", "close");
+ if (Boolean.parseBoolean(fields.getValue("close")))
+ response.getHeaders().put("Connection", "close");
}
catch (NumberFormatException x)
{
response.setStatus(200);
// Echo content back
- IO.copy(request.getInputStream(), response.getOutputStream());
+ InputStream inputStream = Request.asInputStream(request);
+ OutputStream outputStream = org.eclipse.jetty.server.Response.asOutputStream(response);
+ IO.copy(inputStream, outputStream);
}
}
}
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java
index d8ad678c430..0f05974306a 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java
@@ -68,6 +68,7 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;
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;
@@ -1065,6 +1066,7 @@ public class HttpClientTLSTest
}
@Test
+ @Disabled("fix this test: investigate the difference between client and server bytes")
public void testBytesInBytesOut() throws Exception
{
// Two connections will be closed: SslConnection and HttpConnection.
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java
index 9f852407399..c0576b903ff 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java
@@ -25,14 +25,11 @@ import java.net.URI;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Random;
@@ -46,13 +43,6 @@ import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.LongConsumer;
-import jakarta.servlet.AsyncContext;
-import jakarta.servlet.DispatcherType;
-import jakarta.servlet.ReadListener;
-import jakarta.servlet.ServletInputStream;
-import jakarta.servlet.ServletOutputStream;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.Connection;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Destination;
@@ -78,12 +68,15 @@ import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.io.ClientConnector;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.logging.StacklessLogging;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.Content;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.internal.HttpChannelState;
import org.eclipse.jetty.toolchain.test.Net;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
+import org.eclipse.jetty.util.Fields;
import org.eclipse.jetty.util.FuturePromise;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.Promise;
@@ -94,6 +87,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.instanceOf;
@@ -183,13 +177,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest
public void testGETResponseWithContent(Scenario scenario) throws Exception
{
byte[] data = new byte[]{0, 1, 2, 3, 4, 5, 6, 7};
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- response.getOutputStream().write(data);
- baseRequest.setHandled(true);
+ response.write(true, callback, ByteBuffer.wrap(data));
}
});
@@ -208,30 +201,29 @@ public class HttpClientTest extends AbstractHttpClientServerTest
{
String paramName1 = "a";
String paramName2 = "b";
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response) throws Throwable
{
- response.setCharacterEncoding("UTF-8");
- ServletOutputStream output = response.getOutputStream();
- String paramValue1 = request.getParameter(paramName1);
- output.write(paramValue1.getBytes(StandardCharsets.UTF_8));
- String paramValue2 = request.getParameter(paramName2);
+ response.setContentType("text/plain;charset=UTF-8");
+ Fields fields = org.eclipse.jetty.server.Request.extractQueryParameters(request);
+ String paramValue1 = fields.getValue(paramName1);
+ org.eclipse.jetty.server.Response.write(response, false, UTF_8.encode(paramValue1));
+ String paramValue2 = fields.getValue(paramName2);
assertEquals("", paramValue2);
- output.write("empty".getBytes(StandardCharsets.UTF_8));
- baseRequest.setHandled(true);
+ org.eclipse.jetty.server.Response.write(response, true, UTF_8.encode("empty"));
}
});
String value1 = "\u20AC";
- String paramValue1 = URLEncoder.encode(value1, StandardCharsets.UTF_8);
+ String paramValue1 = URLEncoder.encode(value1, UTF_8);
String query = paramName1 + "=" + paramValue1 + "&" + paramName2;
ContentResponse response = client.GET(scenario.getScheme() + "://localhost:" + connector.getLocalPort() + "/?" + query);
assertNotNull(response);
assertEquals(200, response.getStatus());
- String content = new String(response.getContent(), StandardCharsets.UTF_8);
+ String content = new String(response.getContent(), UTF_8);
assertEquals(value1 + "empty", content);
}
@@ -241,36 +233,36 @@ public class HttpClientTest extends AbstractHttpClientServerTest
{
String paramName1 = "a";
String paramName2 = "b";
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response) throws Throwable
{
- response.setCharacterEncoding("UTF-8");
- ServletOutputStream output = response.getOutputStream();
- String[] paramValues1 = request.getParameterValues(paramName1);
+ response.setContentType("text/plain;charset=UTF-8");
+ Fields fields = org.eclipse.jetty.server.Request.extractQueryParameters(request);
+
+ List paramValues1 = fields.getValues(paramName1);
for (String paramValue : paramValues1)
{
- output.write(paramValue.getBytes(StandardCharsets.UTF_8));
+ org.eclipse.jetty.server.Response.write(response, false, UTF_8.encode(paramValue));
}
- String paramValue2 = request.getParameter(paramName2);
- output.write(paramValue2.getBytes(StandardCharsets.UTF_8));
- baseRequest.setHandled(true);
+ String paramValue2 = fields.getValue(paramName2);
+ org.eclipse.jetty.server.Response.write(response, true, UTF_8.encode(paramValue2));
}
});
String value11 = "\u20AC";
String value12 = "\u20AA";
String value2 = "&";
- String paramValue11 = URLEncoder.encode(value11, StandardCharsets.UTF_8);
- String paramValue12 = URLEncoder.encode(value12, StandardCharsets.UTF_8);
- String paramValue2 = URLEncoder.encode(value2, StandardCharsets.UTF_8);
+ String paramValue11 = URLEncoder.encode(value11, UTF_8);
+ String paramValue12 = URLEncoder.encode(value12, UTF_8);
+ String paramValue2 = URLEncoder.encode(value2, UTF_8);
String query = paramName1 + "=" + paramValue11 + "&" + paramName1 + "=" + paramValue12 + "&" + paramName2 + "=" + paramValue2;
ContentResponse response = client.GET(scenario.getScheme() + "://localhost:" + connector.getLocalPort() + "/?" + query);
assertNotNull(response);
assertEquals(200, response.getStatus());
- String content = new String(response.getContent(), StandardCharsets.UTF_8);
+ String content = new String(response.getContent(), UTF_8);
assertEquals(value11 + value12 + value2, content);
}
@@ -280,18 +272,17 @@ public class HttpClientTest extends AbstractHttpClientServerTest
{
String paramName = "a";
String paramValue = "\u20AC";
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- baseRequest.setHandled(true);
- String value = request.getParameter(paramName);
+ Fields fields = org.eclipse.jetty.server.Request.extractQueryParameters(request);
+ String value = fields.getValue(paramName);
if (paramValue.equals(value))
{
- response.setCharacterEncoding("UTF-8");
- response.setContentType("text/plain");
- response.getOutputStream().print(value);
+ response.setContentType("text/plain;charset=UTF-8");
+ response.write(true, callback, value);
}
}
});
@@ -303,7 +294,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
assertNotNull(response);
assertEquals(200, response.getStatus());
- assertEquals(paramValue, new String(response.getContent(), StandardCharsets.UTF_8));
+ assertEquals(paramValue, new String(response.getContent(), UTF_8));
}
@ParameterizedTest
@@ -312,19 +303,18 @@ public class HttpClientTest extends AbstractHttpClientServerTest
{
String paramName = "a";
String paramValue = "\u20AC";
- String encodedParamValue = URLEncoder.encode(paramValue, StandardCharsets.UTF_8);
- start(scenario, new AbstractHandler()
+ String encodedParamValue = URLEncoder.encode(paramValue, UTF_8);
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- baseRequest.setHandled(true);
- String value = request.getParameter(paramName);
+ Fields fields = org.eclipse.jetty.server.Request.extractQueryParameters(request);
+ String value = fields.getValue(paramName);
if (paramValue.equals(value))
{
- response.setCharacterEncoding("UTF-8");
- response.setContentType("text/plain");
- response.getOutputStream().print(value);
+ response.setContentType("text/plain;charset=UTF-8");
+ response.write(true, callback, value);
}
}
});
@@ -337,7 +327,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
assertNotNull(response);
assertEquals(200, response.getStatus());
- assertEquals(paramValue, new String(response.getContent(), StandardCharsets.UTF_8));
+ assertEquals(paramValue, new String(response.getContent(), UTF_8));
}
@ParameterizedTest
@@ -347,19 +337,18 @@ public class HttpClientTest extends AbstractHttpClientServerTest
byte[] content = {0, 1, 2, 3};
String paramName = "a";
String paramValue = "\u20AC";
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback) throws Exception
{
- baseRequest.setHandled(true);
- consume(request.getInputStream(), true);
- String value = request.getParameter(paramName);
+ Content.consumeAll(request);
+ Fields fields = org.eclipse.jetty.server.Request.extractQueryParameters(request);
+ String value = fields.getValue(paramName);
if (paramValue.equals(value))
{
- response.setCharacterEncoding("UTF-8");
- response.setContentType("text/plain");
- response.getOutputStream().write(content);
+ response.setContentType("text/plain;charset=UTF-8");
+ response.write(true, callback, ByteBuffer.wrap(content));
}
}
});
@@ -379,13 +368,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testPOSTWithContentNotifiesRequestContentListener(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response) throws Throwable
{
- baseRequest.setHandled(true);
- consume(request.getInputStream(), true);
+ Content.consumeAll(request);
}
});
@@ -410,13 +398,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testPOSTWithContentTracksProgress(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response) throws Throwable
{
- baseRequest.setHandled(true);
- consume(request.getInputStream(), true);
+ Content.consumeAll(request);
}
});
@@ -491,21 +478,19 @@ public class HttpClientTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testQueuedRequestIsSentWhenPreviousRequestClosedConnection(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response)
{
- if (target.endsWith("/one"))
- baseRequest.getHttpChannel().getEndPoint().close();
- else
- baseRequest.setHandled(true);
+ if (request.getPathInContext().endsWith("/one"))
+ request.getConnectionMetaData().getConnection().getEndPoint().close();
}
});
client.setMaxConnectionsPerDestination(1);
- try (StacklessLogging ignored = new StacklessLogging(org.eclipse.jetty.server.HttpChannel.class))
+ try (StacklessLogging ignored = new StacklessLogging(HttpChannelState.class))
{
CountDownLatch latch = new CountDownLatch(2);
client.newRequest("localhost", connector.getLocalPort())
@@ -532,24 +517,15 @@ public class HttpClientTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testExchangeIsCompleteOnlyWhenBothRequestAndResponseAreComplete(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response) throws Throwable
{
- baseRequest.setHandled(true);
response.setContentLength(0);
- response.setStatus(200);
- response.flushBuffer();
-
- byte[] buffer = new byte[1024];
- InputStream in = request.getInputStream();
- while (true)
- {
- int read = in.read(buffer);
- if (read < 0)
- break;
- }
+ response.setStatus(HttpStatus.OK_200);
+ org.eclipse.jetty.server.Response.write(response, true);
+ Content.consumeAll(request);
}
});
@@ -611,13 +587,15 @@ public class HttpClientTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testExchangeIsCompleteWhenRequestFailsMidwayWithResponse(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response) throws Throwable
{
// Echo back
- IO.copy(request.getInputStream(), response.getOutputStream());
+ InputStream inputStream = org.eclipse.jetty.server.Request.asInputStream(request);
+ OutputStream outputStream = org.eclipse.jetty.server.Response.asOutputStream(response);
+ IO.copy(inputStream, outputStream);
}
});
@@ -707,13 +685,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest
public void testHeaderProcessing(Scenario scenario) throws Exception
{
String headerName = "X-Header-Test";
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response)
{
- baseRequest.setHandled(true);
- response.setHeader(headerName, "X");
+ response.getHeaders().put(headerName, "X");
}
});
@@ -765,13 +742,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest
public void testHEADWithResponseContentLength(Scenario scenario) throws Exception
{
int length = 1024;
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- baseRequest.setHandled(true);
- response.getOutputStream().write(new byte[length]);
+ response.write(true, callback, ByteBuffer.wrap(new byte[length]));
}
});
@@ -870,13 +846,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest
public void testCustomUserAgent(Scenario scenario) throws Exception
{
String userAgent = "Test/1.0";
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response)
{
- baseRequest.setHandled(true);
- ArrayList userAgents = Collections.list(request.getHeaders("User-Agent"));
+ List userAgents = request.getHeaders().getValuesList(HttpHeader.USER_AGENT);
assertEquals(1, userAgents.size());
assertEquals(userAgent, userAgents.get(0));
}
@@ -903,14 +878,13 @@ public class HttpClientTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testUserAgentCanBeRemoved(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response)
{
- baseRequest.setHandled(true);
- ArrayList userAgents = Collections.list(request.getHeaders("User-Agent"));
- if ("/ua".equals(target))
+ List userAgents = request.getHeaders().getValuesList(HttpHeader.USER_AGENT);
+ if ("/ua".equals(request.getPathInContext()))
assertEquals(1, userAgents.size());
else
assertEquals(0, userAgents.size());
@@ -1112,13 +1086,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest
{
byte[] content = new byte[512];
new Random().nextBytes(content);
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- baseRequest.setHandled(true);
- response.getOutputStream().write(content);
+ response.write(true, callback, ByteBuffer.wrap(content));
}
});
@@ -1154,13 +1127,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest
public void testCustomHostHeader(Scenario scenario) throws Exception
{
String host = "localhost";
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response)
{
- baseRequest.setHandled(true);
- assertEquals(host, request.getServerName());
+ assertEquals(host, org.eclipse.jetty.server.Request.getServerName(request));
}
});
@@ -1176,16 +1148,16 @@ public class HttpClientTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testHTTP10WithKeepAliveAndContentLength(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback) throws Exception
{
- // Send the headers at this point, then write the content
- byte[] content = "TEST".getBytes(StandardCharsets.UTF_8);
+ // Send the headers at this point, then write the content.
+ byte[] content = "TEST".getBytes(UTF_8);
response.setContentLength(content.length);
- response.flushBuffer();
- response.getOutputStream().write(content);
+ org.eclipse.jetty.server.Response.write(response, false);
+ response.write(true, callback, ByteBuffer.wrap(content));
}
});
@@ -1204,14 +1176,14 @@ public class HttpClientTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testHTTP10WithKeepAliveAndNoContentLength(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback) throws Exception
{
// Send the headers at this point, then write the content
- response.flushBuffer();
- response.getOutputStream().print("TEST");
+ org.eclipse.jetty.server.Response.write(response, false);
+ response.write(true, callback, "TEST");
}
});
@@ -1261,13 +1233,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest
public void testLongPollIsAbortedWhenClientIsStopped(Scenario scenario) throws Exception
{
CountDownLatch latch = new CountDownLatch(1);
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- baseRequest.setHandled(true);
- request.startAsync();
+ // Do not complete the callback.
latch.countDown();
}
});
@@ -1338,16 +1309,15 @@ public class HttpClientTest extends AbstractHttpClientServerTest
byte[] data = new byte[length];
new Random().nextBytes(data);
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- baseRequest.setHandled(true);
// Send Connection: close to avoid that the server chunks the content with HTTP 1.1.
if (version.compareTo(HttpVersion.HTTP_1_0) > 0)
- response.setHeader("Connection", "close");
- response.getOutputStream().write(data);
+ response.getHeaders().put("Connection", "close");
+ response.write(true, callback, ByteBuffer.wrap(data));
}
});
@@ -1374,19 +1344,22 @@ public class HttpClientTest extends AbstractHttpClientServerTest
{
int maxRetries = 3;
AtomicInteger requests = new AtomicInteger();
- start(scenario, new AbstractHandler()
+ CountDownLatch latch = new CountDownLatch(2);
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback) throws Exception
{
+ Content.consumeAll(request);
int count = requests.incrementAndGet();
if (count == maxRetries)
- baseRequest.setHandled(true);
- consume(request.getInputStream(), true);
+ latch.countDown();
+ else
+ response.setStatus(HttpStatus.NOT_FOUND_404);
+ callback.succeeded();
}
});
- CountDownLatch latch = new CountDownLatch(1);
new RetryListener(client, scenario.getScheme(), "localhost", connector.getLocalPort(), maxRetries)
{
@Override
@@ -1403,14 +1376,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testCompleteNotInvokedUntilContentConsumed(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- baseRequest.setHandled(true);
- ServletOutputStream output = response.getOutputStream();
- output.write(new byte[1024]);
+ response.write(true, callback, ByteBuffer.allocate(1024));
}
});
@@ -1453,14 +1424,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testRequestSentOnlyAfterConnectionOpen(Scenario scenario) throws Exception
{
- startServer(scenario, new AbstractHandler()
- {
- @Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
- {
- baseRequest.setHandled(true);
- }
- });
+ startServer(scenario, new EmptyServerHandler());
AtomicBoolean open = new AtomicBoolean();
ClientConnector clientConnector = new ClientConnector();
@@ -1530,7 +1494,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
"HTTP/1.0 200 OK\r\n" +
"\r\n";
OutputStream output = socket.getOutputStream();
- output.write(httpResponse.getBytes(StandardCharsets.UTF_8));
+ output.write(httpResponse.getBytes(UTF_8));
output.flush();
ContentResponse response = listener.get(5, TimeUnit.SECONDS);
@@ -1557,7 +1521,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
"HTTP/1.1 200 OK\r\n" +
"Content-Length: 0\r\n" +
"\r\n";
- output.write(httpResponse.getBytes(StandardCharsets.UTF_8));
+ output.write(httpResponse.getBytes(UTF_8));
output.flush();
listener.get(5, TimeUnit.SECONDS);
@@ -1570,13 +1534,13 @@ public class HttpClientTest extends AbstractHttpClientServerTest
public void testIPv6HostWithHTTP10(Scenario scenario) throws Exception
{
Assumptions.assumeTrue(Net.isIpv6InterfaceAvailable());
- start(scenario, new EmptyServerHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
response.setContentType("text/plain");
- response.getOutputStream().print(request.getServerName());
+ response.write(true, callback, org.eclipse.jetty.server.Request.getServerName(request));
}
});
@@ -1648,13 +1612,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testHostWithHTTP10(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response)
{
- baseRequest.setHandled(true);
- assertThat(request.getHeader("Host"), Matchers.notNullValue());
+ assertThat(request.getHeaders().get("Host"), Matchers.notNullValue());
}
});
@@ -1702,7 +1665,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
"\r\n" +
"No Content";
OutputStream output = socket.getOutputStream();
- output.write(httpResponse.getBytes(StandardCharsets.UTF_8));
+ output.write(httpResponse.getBytes(UTF_8));
output.flush();
ContentResponse response = listener.get(5, TimeUnit.SECONDS);
@@ -1725,7 +1688,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
"HTTP/1.1 200 OK\r\n" +
"Content-Length: 0\r\n" +
"\r\n";
- output.write(httpResponse.getBytes(StandardCharsets.UTF_8));
+ output.write(httpResponse.getBytes(UTF_8));
output.flush();
response = listener.get(5, TimeUnit.SECONDS);
@@ -1740,14 +1703,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest
{
byte[] bytes = new byte[1024];
new Random().nextBytes(bytes);
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- baseRequest.setHandled(true);
- ServletOutputStream output = response.getOutputStream();
- output.write(bytes);
+ response.write(true, callback, ByteBuffer.wrap(bytes));
}
});
@@ -1832,7 +1793,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
try (Socket socket = server.accept())
{
OutputStream output = socket.getOutputStream();
- output.write(bytesFromServer.getBytes(StandardCharsets.UTF_8));
+ output.write(bytesFromServer.getBytes(UTF_8));
output.flush();
}
@@ -1844,6 +1805,8 @@ public class HttpClientTest extends AbstractHttpClientServerTest
}
}
+ // TODO: move this test to Servlet tests.
+/*
@ParameterizedTest
@ArgumentsSource(ScenarioProvider.class)
public void testHttpParserCloseWithAsyncReads(Scenario scenario) throws Exception
@@ -1919,7 +1882,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
assertTrue(clientResultLatch.await(5, TimeUnit.SECONDS), "clientResultLatch didn't finish");
assertTrue(serverOnErrorLatch.await(5, TimeUnit.SECONDS), "serverOnErrorLatch didn't finish");
}
-
+*/
@ParameterizedTest
@ArgumentsSource(ScenarioProvider.class)
public void testBindAddress(Scenario scenario) throws Exception
@@ -1928,9 +1891,9 @@ public class HttpClientTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response)
{
- assertEquals(bindAddress, request.getRemoteAddr());
+ assertEquals(bindAddress, org.eclipse.jetty.server.Request.getRemoteAddr(request));
}
});
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientURITest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientURITest.java
index 4ffa3ce06ce..3879d9b7afb 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientURITest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientURITest.java
@@ -14,7 +14,6 @@
package org.eclipse.jetty.client;
import java.io.BufferedReader;
-import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
@@ -27,16 +26,13 @@ import java.util.Locale;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.toolchain.test.Net;
import org.eclipse.jetty.util.Fields;
import org.eclipse.jetty.util.StringUtil;
@@ -153,13 +149,12 @@ public class HttpClientURITest extends AbstractHttpClientServerTest
public void testPath(Scenario scenario) throws Exception
{
final String path = "/path";
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response)
{
- baseRequest.setHandled(true);
- assertEquals(path, request.getRequestURI());
+ assertEquals(path, request.getPathInContext());
}
});
@@ -187,14 +182,13 @@ public class HttpClientURITest extends AbstractHttpClientServerTest
String value = "1";
final String query = name + "=" + value;
final String path = "/path";
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response)
{
- baseRequest.setHandled(true);
- assertEquals(path, request.getRequestURI());
- assertEquals(query, request.getQueryString());
+ assertEquals(path, request.getPathInContext());
+ assertEquals(query, request.getHttpURI().getQuery());
}
});
@@ -225,14 +219,13 @@ public class HttpClientURITest extends AbstractHttpClientServerTest
final String query = name + "=" + value;
final String path = "/path";
String pathQuery = path + "?" + query;
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response)
{
- baseRequest.setHandled(true);
- assertEquals(path, request.getRequestURI());
- assertEquals(query, request.getQueryString());
+ assertEquals(path, request.getPathInContext());
+ assertEquals(query, request.getHttpURI().getQuery());
}
});
@@ -265,14 +258,13 @@ public class HttpClientURITest extends AbstractHttpClientServerTest
final String query = name1 + "=" + value1 + "&" + name2 + "=" + value2;
final String path = "/path";
String pathQuery = path + "?" + query;
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response)
{
- baseRequest.setHandled(true);
- assertEquals(path, request.getRequestURI());
- assertEquals(query, request.getQueryString());
+ assertEquals(path, request.getPathInContext());
+ assertEquals(query, request.getHttpURI().getQuery());
}
});
@@ -301,23 +293,23 @@ public class HttpClientURITest extends AbstractHttpClientServerTest
{
final String name1 = "a";
final String value1 = "\u20AC";
- final String encodedValue1 = URLEncoder.encode(value1, "UTF-8");
+ final String encodedValue1 = URLEncoder.encode(value1, StandardCharsets.UTF_8);
final String name2 = "b";
final String value2 = "\u00A5";
- String encodedValue2 = URLEncoder.encode(value2, "UTF-8");
+ String encodedValue2 = URLEncoder.encode(value2, StandardCharsets.UTF_8);
final String query = name1 + "=" + encodedValue1 + "&" + name2 + "=" + encodedValue2;
final String path = "/path";
String pathQuery = path + "?" + query;
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response)
{
- baseRequest.setHandled(true);
- assertEquals(path, request.getRequestURI());
- assertEquals(query, request.getQueryString());
- assertEquals(value1, request.getParameter(name1));
- assertEquals(value2, request.getParameter(name2));
+ assertEquals(path, request.getPathInContext());
+ assertEquals(query, request.getHttpURI().getQuery());
+ Fields fields = org.eclipse.jetty.server.Request.extractQueryParameters(request);
+ assertEquals(value1, fields.getValue(name1));
+ assertEquals(value2, fields.getValue(name2));
}
});
@@ -347,14 +339,13 @@ public class HttpClientURITest extends AbstractHttpClientServerTest
final String path = "/path";
final String query = "="; // Bogus query
String pathQuery = path + "?" + query;
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response)
{
- baseRequest.setHandled(true);
- assertEquals(path, request.getRequestURI());
- assertEquals(query, request.getQueryString());
+ assertEquals(path, request.getPathInContext());
+ assertEquals(query, request.getHttpURI().getQuery());
}
});
@@ -381,14 +372,13 @@ public class HttpClientURITest extends AbstractHttpClientServerTest
final String path = "/path";
final String query = "=1"; // Bogus query
String pathQuery = path + "?" + query;
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response)
{
- baseRequest.setHandled(true);
- assertEquals(path, request.getRequestURI());
- assertEquals(query, request.getQueryString());
+ assertEquals(path, request.getPathInContext());
+ assertEquals(query, request.getHttpURI().getQuery());
}
});
@@ -414,14 +404,14 @@ public class HttpClientURITest extends AbstractHttpClientServerTest
{
final String name1 = "a";
final String name2 = "A";
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response)
{
- baseRequest.setHandled(true);
- assertEquals(name1, request.getParameter(name1));
- assertEquals(name2, request.getParameter(name2));
+ Fields fields = org.eclipse.jetty.server.Request.extractQueryParameters(request);
+ assertEquals(name1, fields.getValue(name1));
+ assertEquals(name2, fields.getValue(name2));
}
});
@@ -443,14 +433,14 @@ public class HttpClientURITest extends AbstractHttpClientServerTest
final String rawValue = "Hello%20World";
final String rawQuery = name + "=" + rawValue;
final String value = "Hello World";
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response)
{
- baseRequest.setHandled(true);
- assertEquals(rawQuery, request.getQueryString());
- assertEquals(value, request.getParameter(name));
+ assertEquals(rawQuery, request.getHttpURI().getQuery());
+ Fields fields = org.eclipse.jetty.server.Request.extractQueryParameters(request);
+ assertEquals(value, fields.getValue(name));
}
});
@@ -472,14 +462,14 @@ public class HttpClientURITest extends AbstractHttpClientServerTest
final String rawValue = "Hello%20World";
final String rawQuery = name + "=" + rawValue;
final String value = "Hello World";
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response)
{
- baseRequest.setHandled(true);
- assertEquals(rawQuery, request.getQueryString());
- assertEquals(value, request.getParameter(name));
+ assertEquals(rawQuery, request.getHttpURI().getQuery());
+ Fields fields = org.eclipse.jetty.server.Request.extractQueryParameters(request);
+ assertEquals(value, fields.getValue(name));
}
});
@@ -504,17 +494,17 @@ public class HttpClientURITest extends AbstractHttpClientServerTest
final String rawQuery1 = name1 + "=" + rawValue1;
final String value1 = "Hello World";
final String value2 = "alfa omega";
- final String encodedQuery2 = name2 + "=" + URLEncoder.encode(value2, "UTF-8");
+ final String encodedQuery2 = name2 + "=" + URLEncoder.encode(value2, StandardCharsets.UTF_8);
final String query = rawQuery1 + "&" + encodedQuery2;
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response)
{
- baseRequest.setHandled(true);
- assertEquals(query, request.getQueryString());
- assertEquals(value1, request.getParameter(name1));
- assertEquals(value2, request.getParameter(name2));
+ assertEquals(query, request.getHttpURI().getQuery());
+ Fields fields = org.eclipse.jetty.server.Request.extractQueryParameters(request);
+ assertEquals(value1, fields.getValue(name1));
+ assertEquals(value2, fields.getValue(name2));
}
});
@@ -534,14 +524,7 @@ public class HttpClientURITest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testSchemeIsCaseInsensitive(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
- {
- @Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- baseRequest.setHandled(true);
- }
- });
+ start(scenario, new EmptyServerHandler());
ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
.scheme(scenario.getScheme().toUpperCase(Locale.ENGLISH))
@@ -555,14 +538,7 @@ public class HttpClientURITest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testHostIsCaseInsensitive(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
- {
- @Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- baseRequest.setHandled(true);
- }
- });
+ start(scenario, new EmptyServerHandler());
ContentResponse response = client.newRequest("LOCALHOST", connector.getLocalPort())
.scheme(scenario.getScheme())
@@ -576,14 +552,13 @@ public class HttpClientURITest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testAsteriskFormTarget(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response)
{
- baseRequest.setHandled(true);
- assertEquals("*", target);
- assertEquals("*", request.getPathInfo());
+ assertEquals("*", request.getHttpURI().getPath());
+ assertEquals("*", request.getPathInContext());
}
});
@@ -610,7 +585,7 @@ public class HttpClientURITest extends AbstractHttpClientServerTest
private ServerSocket serverSocket;
private int port;
- private IDNRedirectServer(final String location) throws IOException
+ private IDNRedirectServer(final String location)
{
this.location = location;
}
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientUploadDuringServerShutdownTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientUploadDuringServerShutdownTest.java
index c5adf88b7cf..c34d4181a78 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientUploadDuringServerShutdownTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientUploadDuringServerShutdownTest.java
@@ -13,8 +13,6 @@
package org.eclipse.jetty.client;
-import java.io.IOException;
-import java.io.InputStream;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
@@ -22,17 +20,17 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.http.HttpChannelOverHTTP;
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
import org.eclipse.jetty.client.http.HttpConnectionOverHTTP;
import org.eclipse.jetty.client.util.BytesRequestContent;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.server.Content;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.util.Blocking;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.junit.jupiter.api.Test;
@@ -54,24 +52,33 @@ public class HttpClientUploadDuringServerShutdownTest
ServerConnector connector = new ServerConnector(server);
connector.setPort(8888);
server.addConnector(connector);
- server.setHandler(new AbstractHandler()
+ server.setHandler(new EmptyServerHandler()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(Request request, Response response) throws Throwable
{
- baseRequest.setHandled(true);
- byte[] buffer = new byte[1024];
- InputStream input = request.getInputStream();
while (true)
{
- int read = input.read(buffer);
- if (read < 0)
- break;
- long now = System.nanoTime();
- long sleep = TimeUnit.MICROSECONDS.toNanos(1);
- while (System.nanoTime() < now + sleep)
+ Content content = request.readContent();
+ if (content == null)
{
- // Wait.
+ try (Blocking.Runnable blocker = _blocking.runnable())
+ {
+ request.demandContent(blocker);
+ }
+ }
+ else
+ {
+ if (content.hasRemaining())
+ content.release();
+ if (content.isLast())
+ break;
+ long now = System.nanoTime();
+ long sleep = TimeUnit.MICROSECONDS.toNanos(1);
+ while (System.nanoTime() < now + sleep)
+ {
+ Thread.onSpinWait();
+ }
}
}
}
@@ -131,13 +138,12 @@ public class HttpClientUploadDuringServerShutdownTest
Server server = new Server(serverThreads);
ServerConnector connector = new ServerConnector(server);
server.addConnector(connector);
- server.setHandler(new AbstractHandler()
+ server.setHandler(new EmptyServerHandler()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, Response response)
{
- baseRequest.setHandled(true);
- endPointRef.set(baseRequest.getHttpChannel().getEndPoint());
+ endPointRef.set(request.getConnectionMetaData().getConnection().getEndPoint());
serverLatch.countDown();
}
});
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpConnectionLifecycleTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpConnectionLifecycleTest.java
index 6bdb1ab21ab..646f7712e8a 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpConnectionLifecycleTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpConnectionLifecycleTest.java
@@ -20,8 +20,6 @@ import java.util.Queue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.Connection;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
@@ -31,7 +29,6 @@ import org.eclipse.jetty.client.util.ByteBufferRequestContent;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.logging.StacklessLogging;
-import org.eclipse.jetty.server.handler.AbstractHandler;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
import org.slf4j.Logger;
@@ -321,13 +318,12 @@ public class HttpConnectionLifecycleTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testResponseWithConnectionCloseHeaderRemovesConnection(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response)
{
- response.setHeader("Connection", "close");
- baseRequest.setHandled(true);
+ response.getHeaders().put("Connection", "close");
}
});
@@ -368,13 +364,12 @@ public class HttpConnectionLifecycleTest extends AbstractHttpClientServerTest
{
try (StacklessLogging ignore = new StacklessLogging(HttpConnection.class))
{
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response)
{
- response.setHeader("Connection", "close");
- baseRequest.setHandled(true);
+ response.getHeaders().put("Connection", "close");
// Don't read request content; this causes the server parser to be closed
}
});
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpCookieTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpCookieTest.java
index e6d53a2fcc2..d63d110a1cf 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpCookieTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpCookieTest.java
@@ -19,18 +19,15 @@ import java.net.URI;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
-import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
-import jakarta.servlet.http.Cookie;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.HttpCookieStore;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
@@ -41,10 +38,9 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
+@Disabled("fix this test. the problem is on the server side, which caches the cookies so different requests return the same cookies")
public class HttpCookieTest extends AbstractHttpClientServerTest
{
- private static final Cookie[] EMPTY_COOKIES = new Cookie[0];
-
@ParameterizedTest
@ArgumentsSource(ScenarioProvider.class)
public void testCookieIsStored(Scenario scenario) throws Exception
@@ -54,9 +50,9 @@ public class HttpCookieTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, org.eclipse.jetty.server.Response response)
{
- response.addCookie(new Cookie(name, value));
+ org.eclipse.jetty.server.Response.addCookie(response, new org.eclipse.jetty.http.HttpCookie(name, value));
}
});
@@ -84,12 +80,12 @@ public class HttpCookieTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, org.eclipse.jetty.server.Response response)
{
- Cookie[] cookies = request.getCookies();
+ List cookies = Request.getCookies(request);
assertNotNull(cookies);
- assertEquals(1, cookies.length);
- Cookie cookie = cookies[0];
+ assertEquals(1, cookies.size());
+ org.eclipse.jetty.http.HttpCookie cookie = cookies.get(0);
assertEquals(name, cookie.getName());
assertEquals(value, cookie.getValue());
}
@@ -113,7 +109,7 @@ public class HttpCookieTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, org.eclipse.jetty.server.Response response)
{
response.addHeader("Set-Cookie", "");
}
@@ -147,12 +143,12 @@ public class HttpCookieTest extends AbstractHttpClientServerTest
startServer(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, org.eclipse.jetty.server.Response response)
{
- Cookie[] cookies = request.getCookies();
+ List cookies = Request.getCookies(request);
assertNotNull(cookies);
- assertEquals(1, cookies.length);
- Cookie cookie = cookies[0];
+ assertEquals(1, cookies.size());
+ org.eclipse.jetty.http.HttpCookie cookie = cookies.get(0);
assertEquals(name, cookie.getName());
assertEquals(value, cookie.getValue());
}
@@ -181,29 +177,28 @@ public class HttpCookieTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, org.eclipse.jetty.server.Response response)
{
- int r = request.getIntHeader(headerName);
+ String target = request.getPathInContext();
+ int r = (int)request.getHeaders().getLongField(headerName);
if ("/foo".equals(target) && r == 0)
{
- Cookie cookie = new Cookie(cookieName, cookieValue);
- response.addCookie(cookie);
+ org.eclipse.jetty.http.HttpCookie cookie = new org.eclipse.jetty.http.HttpCookie(cookieName, cookieValue);
+ org.eclipse.jetty.server.Response.addCookie(response, cookie);
}
else
{
- Cookie[] cookies = Optional.ofNullable(request.getCookies()).orElse(EMPTY_COOKIES);
+ List cookies = Request.getCookies(request);
switch (target)
{
- case "/":
- case "/foo":
- case "/foo/bar":
- assertEquals(1, cookies.length, target);
- Cookie cookie = cookies[0];
+ case "/", "/foo", "/foo/bar" ->
+ {
+ assertEquals(1, cookies.size(), target);
+ org.eclipse.jetty.http.HttpCookie cookie = cookies.get(0);
assertEquals(cookieName, cookie.getName(), target);
assertEquals(cookieValue, cookie.getValue(), target);
- break;
- default:
- fail("Unrecognized target: " + target);
+ }
+ default -> fail("Unrecognized target: " + target);
}
}
}
@@ -237,34 +232,29 @@ public class HttpCookieTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, org.eclipse.jetty.server.Response response)
{
- int r = request.getIntHeader(headerName);
+ String target = request.getPathInContext();
+ int r = (int)request.getHeaders().getLongField(headerName);
if ("/foo/bar".equals(target) && r == 0)
{
- Cookie cookie = new Cookie(cookieName, cookieValue);
- response.addCookie(cookie);
+ org.eclipse.jetty.http.HttpCookie cookie = new org.eclipse.jetty.http.HttpCookie(cookieName, cookieValue);
+ org.eclipse.jetty.server.Response.addCookie(response, cookie);
}
else
{
- Cookie[] cookies = Optional.ofNullable(request.getCookies()).orElse(EMPTY_COOKIES);
+ List cookies = Request.getCookies(request);
switch (target)
{
- case "/":
- case "/foo":
- case "/foobar":
- assertEquals(0, cookies.length, target);
- break;
- case "/foo/":
- case "/foo/bar":
- case "/foo/bar/baz":
- assertEquals(1, cookies.length, target);
- Cookie cookie = cookies[0];
+ case "/", "/foo", "/foobar" -> assertEquals(0, cookies.size(), target);
+ case "/foo/", "/foo/bar", "/foo/bar/baz" ->
+ {
+ assertEquals(1, cookies.size(), target);
+ org.eclipse.jetty.http.HttpCookie cookie = cookies.get(0);
assertEquals(cookieName, cookie.getName(), target);
assertEquals(cookieValue, cookie.getValue(), target);
- break;
- default:
- fail("Unrecognized Target: " + target);
+ }
+ default -> fail("Unrecognized Target: " + target);
}
}
}
@@ -298,34 +288,29 @@ public class HttpCookieTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, org.eclipse.jetty.server.Response response)
{
- int r = request.getIntHeader(headerName);
+ String target = request.getPathInContext();
+ int r = (int)request.getHeaders().getLongField(headerName);
if ("/foo".equals(target) && r == 0)
{
- Cookie cookie = new Cookie(cookieName, cookieValue);
- cookie.setPath("/foo/bar");
- response.addCookie(cookie);
+ org.eclipse.jetty.http.HttpCookie cookie = new org.eclipse.jetty.http.HttpCookie(cookieName, cookieValue, null, "/foo/bar");
+ org.eclipse.jetty.server.Response.addCookie(response, cookie);
}
else
{
- Cookie[] cookies = Optional.ofNullable(request.getCookies()).orElse(EMPTY_COOKIES);
+ List cookies = Request.getCookies(request);
switch (target)
{
- case "/":
- case "/foo":
- case "/foo/barbaz":
- assertEquals(0, cookies.length, target);
- break;
- case "/foo/bar":
- case "/foo/bar/":
- assertEquals(1, cookies.length, target);
- Cookie cookie = cookies[0];
+ case "/", "/foo", "/foo/barbaz" -> assertEquals(0, cookies.size(), target);
+ case "/foo/bar", "/foo/bar/" ->
+ {
+ assertEquals(1, cookies.size(), target);
+ org.eclipse.jetty.http.HttpCookie cookie = cookies.get(0);
assertEquals(cookieName, cookie.getName(), target);
assertEquals(cookieValue, cookie.getValue(), target);
- break;
- default:
- fail("Unrecognized Target: " + target);
+ }
+ default -> fail("Unrecognized Target: " + target);
}
}
}
@@ -359,34 +344,29 @@ public class HttpCookieTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, org.eclipse.jetty.server.Response response)
{
- int r = request.getIntHeader(headerName);
+ String target = request.getPathInContext();
+ int r = (int)request.getHeaders().getLongField(headerName);
if ("/foo/bar".equals(target) && r == 0)
{
- Cookie cookie = new Cookie(cookieName, cookieValue);
- cookie.setPath("/foo");
- response.addCookie(cookie);
+ org.eclipse.jetty.http.HttpCookie cookie = new org.eclipse.jetty.http.HttpCookie(cookieName, cookieValue, null, "/foo");
+ org.eclipse.jetty.server.Response.addCookie(response, cookie);
}
else
{
- Cookie[] cookies = Optional.ofNullable(request.getCookies()).orElse(EMPTY_COOKIES);
+ List cookies = Request.getCookies(request);
switch (target)
{
- case "/":
- case "/foobar":
- assertEquals(0, cookies.length, target);
- break;
- case "/foo":
- case "/foo/":
- case "/foo/bar":
- assertEquals(1, cookies.length, target);
- Cookie cookie = cookies[0];
+ case "/", "/foobar" -> assertEquals(0, cookies.size(), target);
+ case "/foo", "/foo/", "/foo/bar" ->
+ {
+ assertEquals(1, cookies.size(), target);
+ org.eclipse.jetty.http.HttpCookie cookie = cookies.get(0);
assertEquals(cookieName, cookie.getName(), target);
assertEquals(cookieValue, cookie.getValue(), target);
- break;
- default:
- fail("Unrecognized Target: " + target);
+ }
+ default -> fail("Unrecognized Target: " + target);
}
}
}
@@ -421,35 +401,31 @@ public class HttpCookieTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, org.eclipse.jetty.server.Response response)
{
- int r = request.getIntHeader(headerName);
+ String target = request.getPathInContext();
+ int r = (int)request.getHeaders().getLongField(headerName);
if ("/foo".equals(target) && r == 0)
{
- Cookie cookie = new Cookie(cookieName, cookieValue1);
- cookie.setPath("/foo");
- response.addCookie(cookie);
- cookie = new Cookie(cookieName, cookieValue2);
- cookie.setPath("/foo");
- response.addCookie(cookie);
+ org.eclipse.jetty.http.HttpCookie cookie = new org.eclipse.jetty.http.HttpCookie(cookieName, cookieValue1, null, "/foo");
+ org.eclipse.jetty.server.Response.addCookie(response, cookie);
+ cookie = new org.eclipse.jetty.http.HttpCookie(cookieName, cookieValue2, null, "/foo");
+ org.eclipse.jetty.server.Response.addCookie(response, cookie);
}
else
{
- Cookie[] cookies = Optional.ofNullable(request.getCookies()).orElse(EMPTY_COOKIES);
+ List cookies = Request.getCookies(request);
switch (target)
{
- case "/":
- assertEquals(0, cookies.length, target);
- break;
- case "/foo":
- case "/foo/bar":
- assertEquals(1, cookies.length, target);
- Cookie cookie = cookies[0];
+ case "/" -> assertEquals(0, cookies.size(), target);
+ case "/foo", "/foo/bar" ->
+ {
+ assertEquals(1, cookies.size(), target);
+ org.eclipse.jetty.http.HttpCookie cookie = cookies.get(0);
assertEquals(cookieName, cookie.getName(), target);
assertEquals(cookieValue2, cookie.getValue(), target);
- break;
- default:
- fail("Unrecognized Target: " + target);
+ }
+ default -> fail("Unrecognized Target: " + target);
}
}
}
@@ -484,42 +460,38 @@ public class HttpCookieTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, org.eclipse.jetty.server.Response response)
{
- int r = request.getIntHeader(headerName);
+ String target = request.getPathInContext();
+ int r = (int)request.getHeaders().getLongField(headerName);
if ("/foo".equals(target) && r == 0)
{
- Cookie cookie = new Cookie(cookieName, cookieValue1);
- cookie.setPath("/foo");
- response.addCookie(cookie);
- cookie = new Cookie(cookieName, cookieValue2);
- cookie.setPath("/bar");
- response.addCookie(cookie);
+ org.eclipse.jetty.http.HttpCookie cookie = new org.eclipse.jetty.http.HttpCookie(cookieName, cookieValue1, null, "/foo");
+ org.eclipse.jetty.server.Response.addCookie(response, cookie);
+ cookie = new org.eclipse.jetty.http.HttpCookie(cookieName, cookieValue2, null, "/bar");
+ org.eclipse.jetty.server.Response.addCookie(response, cookie);
}
else
{
- Cookie[] cookies = Optional.ofNullable(request.getCookies()).orElse(EMPTY_COOKIES);
+ List cookies = Request.getCookies(request);
switch (target)
{
- case "/":
- assertEquals(0, cookies.length, target);
- break;
- case "/foo":
- case "/foo/bar":
- assertEquals(1, cookies.length, target);
- Cookie cookie1 = cookies[0];
+ case "/" -> assertEquals(0, cookies.size(), target);
+ case "/foo", "/foo/bar" ->
+ {
+ assertEquals(1, cookies.size(), target);
+ org.eclipse.jetty.http.HttpCookie cookie1 = cookies.get(0);
assertEquals(cookieName, cookie1.getName(), target);
assertEquals(cookieValue1, cookie1.getValue(), target);
- break;
- case "/bar":
- case "/bar/foo":
- assertEquals(1, cookies.length, target);
- Cookie cookie2 = cookies[0];
+ }
+ case "/bar", "/bar/foo" ->
+ {
+ assertEquals(1, cookies.size(), target);
+ org.eclipse.jetty.http.HttpCookie cookie2 = cookies.get(0);
assertEquals(cookieName, cookie2.getName(), target);
assertEquals(cookieValue2, cookie2.getValue(), target);
- break;
- default:
- fail("Unrecognized Target: " + target);
+ }
+ default -> fail("Unrecognized Target: " + target);
}
}
}
@@ -554,45 +526,43 @@ public class HttpCookieTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, org.eclipse.jetty.server.Response response)
{
- int r = request.getIntHeader(headerName);
+ String target = request.getPathInContext();
+ int r = (int)request.getHeaders().getLongField(headerName);
if ("/foo".equals(target) && r == 0)
{
- Cookie cookie = new Cookie(cookieName, cookieValue1);
- cookie.setPath("/foo");
- response.addCookie(cookie);
- cookie = new Cookie(cookieName, cookieValue2);
- cookie.setPath("/foo/bar");
- response.addCookie(cookie);
+ org.eclipse.jetty.http.HttpCookie cookie = new org.eclipse.jetty.http.HttpCookie(cookieName, cookieValue1, null, "/foo");
+ org.eclipse.jetty.server.Response.addCookie(response, cookie);
+ cookie = new org.eclipse.jetty.http.HttpCookie(cookieName, cookieValue2, null, "/foo/bar");
+ org.eclipse.jetty.server.Response.addCookie(response, cookie);
}
else
{
- Cookie[] cookies = Optional.ofNullable(request.getCookies()).orElse(EMPTY_COOKIES);
+ List cookies = Request.getCookies(request);
switch (target)
{
- case "/":
- assertEquals(0, cookies.length, target);
- break;
- case "/foo":
- assertEquals(1, cookies.length, target);
- Cookie cookie = cookies[0];
+ case "/" -> assertEquals(0, cookies.size(), target);
+ case "/foo" ->
+ {
+ assertEquals(1, cookies.size(), target);
+ org.eclipse.jetty.http.HttpCookie cookie = cookies.get(0);
assertEquals(cookieName, cookie.getName(), target);
assertEquals(cookieValue1, cookie.getValue(), target);
- break;
- case "/foo/bar":
- assertEquals(2, cookies.length, target);
- Cookie cookie1 = cookies[0];
- Cookie cookie2 = cookies[1];
+ }
+ case "/foo/bar" ->
+ {
+ assertEquals(2, cookies.size(), target);
+ org.eclipse.jetty.http.HttpCookie cookie1 = cookies.get(0);
+ org.eclipse.jetty.http.HttpCookie cookie2 = cookies.get(1);
assertEquals(cookieName, cookie1.getName(), target);
assertEquals(cookieName, cookie2.getName(), target);
Set values = new HashSet<>();
values.add(cookie1.getValue());
values.add(cookie2.getValue());
assertThat(target, values, containsInAnyOrder(cookieValue1, cookieValue2));
- break;
- default:
- fail("Unrecognized Target: " + target);
+ }
+ default -> fail("Unrecognized Target: " + target);
}
}
}
@@ -626,34 +596,29 @@ public class HttpCookieTest extends AbstractHttpClientServerTest
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, org.eclipse.jetty.server.Response response)
{
- int r = request.getIntHeader(headerName);
+ String target = request.getPathInContext();
+ int r = (int)request.getHeaders().getLongField(headerName);
if ("/foo/bar".equals(target) && r == 0)
{
- Cookie cookie = new Cookie(cookieName, cookieValue);
- cookie.setPath("/foo/");
- response.addCookie(cookie);
+ org.eclipse.jetty.http.HttpCookie cookie = new org.eclipse.jetty.http.HttpCookie(cookieName, cookieValue, null, "/foo/");
+ org.eclipse.jetty.server.Response.addCookie(response, cookie);
}
else
{
- Cookie[] cookies = Optional.ofNullable(request.getCookies()).orElse(EMPTY_COOKIES);
+ List cookies = Request.getCookies(request);
switch (target)
{
- case "/":
- case "/foo":
- case "/foobar":
- assertEquals(0, cookies.length, target);
- break;
- case "/foo/":
- case "/foo/bar":
- assertEquals(1, cookies.length, target);
- Cookie cookie = cookies[0];
+ case "/", "/foo", "/foobar" -> assertEquals(0, cookies.size(), target);
+ case "/foo/", "/foo/bar" ->
+ {
+ assertEquals(1, cookies.size(), target);
+ org.eclipse.jetty.http.HttpCookie cookie = cookies.get(0);
assertEquals(cookieName, cookie.getName(), target);
assertEquals(cookieValue, cookie.getValue(), target);
- break;
- default:
- fail("Unrecognized Target: " + target);
+ }
+ default -> fail("Unrecognized Target: " + target);
}
}
}
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpRequestAbortTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpRequestAbortTest.java
index 11de6a247a5..2d951541239 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpRequestAbortTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpRequestAbortTest.java
@@ -14,22 +14,22 @@
package org.eclipse.jetty.client;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-import jakarta.servlet.DispatcherType;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Result;
import org.eclipse.jetty.client.util.ByteBufferRequestContent;
import org.eclipse.jetty.logging.StacklessLogging;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.server.internal.HttpChannelState;
+import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.IO;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
@@ -232,23 +232,14 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testAbortOnCommitWithContent(Scenario scenario) throws Exception
{
- AtomicReference failure = new AtomicReference<>();
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(org.eclipse.jetty.server.Request request, Response response) throws IOException
{
- try
- {
- baseRequest.setHandled(true);
- if (request.getDispatcherType() != DispatcherType.ERROR)
- IO.copy(request.getInputStream(), response.getOutputStream());
- }
- catch (IOException x)
- {
- failure.set(x);
- throw x;
- }
+ InputStream inputStream = org.eclipse.jetty.server.Request.asInputStream(request);
+ OutputStream outputStream = Response.asOutputStream(response);
+ IO.copy(inputStream, outputStream);
}
});
@@ -287,18 +278,19 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testAbortOnContent(Scenario scenario) throws Exception
{
- try (StacklessLogging ignore = new StacklessLogging(org.eclipse.jetty.server.HttpChannel.class))
+ try (StacklessLogging ignore = new StacklessLogging(HttpChannelState.class))
{
CountDownLatch serverLatch = new CountDownLatch(1);
start(scenario, new EmptyServerHandler()
{
@Override
- protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(org.eclipse.jetty.server.Request request, Response response) throws Exception
{
try
{
- if (request.getDispatcherType() != DispatcherType.ERROR)
- IO.copy(request.getInputStream(), response.getOutputStream());
+ InputStream inputStream = org.eclipse.jetty.server.Request.asInputStream(request);
+ OutputStream outputStream = Response.asOutputStream(response);
+ IO.copy(inputStream, outputStream);
}
finally
{
@@ -346,21 +338,12 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest
public void testInterrupt(Scenario scenario) throws Exception
{
long delay = 1000;
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response) throws Exception
{
- try
- {
- baseRequest.setHandled(true);
- if (request.getDispatcherType() != DispatcherType.ERROR)
- TimeUnit.MILLISECONDS.sleep(2 * delay);
- }
- catch (InterruptedException x)
- {
- throw new ServletException(x);
- }
+ TimeUnit.MILLISECONDS.sleep(2 * delay);
}
});
@@ -390,21 +373,12 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest
public void testAbortLongPoll(Scenario scenario) throws Exception
{
final long delay = 1000;
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response) throws Exception
{
- try
- {
- baseRequest.setHandled(true);
- if (request.getDispatcherType() != DispatcherType.ERROR)
- TimeUnit.MILLISECONDS.sleep(2 * delay);
- }
- catch (InterruptedException x)
- {
- throw new ServletException(x);
- }
+ TimeUnit.MILLISECONDS.sleep(2 * delay);
}
});
@@ -452,21 +426,12 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest
public void testAbortLongPollAsync(Scenario scenario) throws Exception
{
final long delay = 1000;
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response) throws Throwable
{
- try
- {
- baseRequest.setHandled(true);
- if (request.getDispatcherType() != DispatcherType.ERROR)
- TimeUnit.MILLISECONDS.sleep(2 * delay);
- }
- catch (InterruptedException x)
- {
- throw new ServletException(x);
- }
+ TimeUnit.MILLISECONDS.sleep(2 * delay);
}
});
@@ -493,14 +458,15 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testAbortConversation(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
+ start(scenario, new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, Response response, Callback callback)
{
- baseRequest.setHandled(true);
- if (!"/done".equals(request.getRequestURI()))
- response.sendRedirect("/done");
+ if ("/done".equals(request.getPathInContext()))
+ callback.succeeded();
+ else
+ Response.sendRedirect(request, response, callback, "/done");
}
});
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseAbortTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseAbortTest.java
index 9cbc37d8faf..65ed06d0296 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseAbortTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseAbortTest.java
@@ -14,17 +14,14 @@
package org.eclipse.jetty.client;
import java.io.IOException;
-import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.util.AsyncRequestContent;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.Response;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
@@ -95,19 +92,15 @@ public class HttpResponseAbortTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testAbortOnContent(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, Response response)
{
try
{
- baseRequest.setHandled(true);
- OutputStream output = response.getOutputStream();
- output.write(1);
- output.flush();
- output.write(2);
- output.flush();
+ Response.write(response, false, ByteBuffer.wrap(new byte[]{1}));
+ Response.write(response, false, ByteBuffer.wrap(new byte[]{2}));
}
catch (IOException ignored)
{
@@ -132,19 +125,15 @@ public class HttpResponseAbortTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testAbortOnContentBeforeRequestTermination(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, Response response)
{
try
{
- baseRequest.setHandled(true);
- OutputStream output = response.getOutputStream();
- output.write(1);
- output.flush();
- output.write(2);
- output.flush();
+ Response.write(response, false, ByteBuffer.wrap(new byte[]{1}));
+ Response.write(response, false, ByteBuffer.wrap(new byte[]{2}));
}
catch (IOException ignored)
{
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseConcurrentAbortTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseConcurrentAbortTest.java
index 6b4840f8dfe..29d39449223 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseConcurrentAbortTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseConcurrentAbortTest.java
@@ -13,21 +13,14 @@
package org.eclipse.jetty.client;
-import java.io.IOException;
-import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.api.Result;
-import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
@@ -49,14 +42,7 @@ public class HttpResponseConcurrentAbortTest extends AbstractHttpClientServerTes
client.newRequest("localhost", connector.getLocalPort())
.scheme(scenario.getScheme())
- .onResponseBegin(new Response.BeginListener()
- {
- @Override
- public void onBegin(Response response)
- {
- abort(response);
- }
- })
+ .onResponseBegin(this::abort)
.send(new TestResponseListener());
assertTrue(callbackLatch.await(5, TimeUnit.SECONDS));
assertTrue(completeLatch.await(5, TimeUnit.SECONDS));
@@ -72,14 +58,10 @@ public class HttpResponseConcurrentAbortTest extends AbstractHttpClientServerTes
client.newRequest("localhost", connector.getLocalPort())
.scheme(scenario.getScheme())
- .onResponseHeader(new Response.HeaderListener()
+ .onResponseHeader((response, field) ->
{
- @Override
- public boolean onHeader(Response response, HttpField field)
- {
- abort(response);
- return true;
- }
+ abort(response);
+ return true;
})
.send(new TestResponseListener());
assertTrue(callbackLatch.await(5, TimeUnit.SECONDS));
@@ -96,14 +78,7 @@ public class HttpResponseConcurrentAbortTest extends AbstractHttpClientServerTes
client.newRequest("localhost", connector.getLocalPort())
.scheme(scenario.getScheme())
- .onResponseHeaders(new Response.HeadersListener()
- {
- @Override
- public void onHeaders(Response response)
- {
- abort(response);
- }
- })
+ .onResponseHeaders(this::abort)
.send(new TestResponseListener());
assertTrue(callbackLatch.await(5, TimeUnit.SECONDS));
assertTrue(completeLatch.await(5, TimeUnit.SECONDS));
@@ -115,28 +90,18 @@ public class HttpResponseConcurrentAbortTest extends AbstractHttpClientServerTes
@ArgumentsSource(ScenarioProvider.class)
public void testAbortOnContent(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(Request request, org.eclipse.jetty.server.Response response) throws Throwable
{
- baseRequest.setHandled(true);
- OutputStream output = response.getOutputStream();
- output.write(1);
- output.flush();
+ org.eclipse.jetty.server.Response.write(response, false, ByteBuffer.wrap(new byte[]{1}));
}
});
client.newRequest("localhost", connector.getLocalPort())
.scheme(scenario.getScheme())
- .onResponseContent(new Response.ContentListener()
- {
- @Override
- public void onContent(Response response, ByteBuffer content)
- {
- abort(response);
- }
- })
+ .onResponseContent((response, content) -> abort(response))
.send(new TestResponseListener());
assertTrue(callbackLatch.await(5, TimeUnit.SECONDS));
assertTrue(completeLatch.await(5, TimeUnit.SECONDS));
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/NetworkTrafficListenerTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/NetworkTrafficListenerTest.java
index c6a6e8415db..82e7fc86b40 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/NetworkTrafficListenerTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/NetworkTrafficListenerTest.java
@@ -13,21 +13,15 @@
package org.eclipse.jetty.client;
-import java.io.IOException;
-import java.io.InputStream;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
-import java.nio.charset.StandardCharsets;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
-import jakarta.servlet.ServletOutputStream;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
import org.eclipse.jetty.client.util.FormRequestContent;
@@ -40,17 +34,20 @@ import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.ManagedSelector;
import org.eclipse.jetty.io.NetworkTrafficListener;
import org.eclipse.jetty.io.NetworkTrafficSocketChannelEndPoint;
+import org.eclipse.jetty.server.Content;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.NetworkTrafficServerConnector;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.BufferUtil;
+import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Fields;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -132,14 +129,7 @@ public class NetworkTrafficListenerTest
@Test
public void testTrafficWithNoResponseContentOnNonPersistentConnection() throws Exception
{
- start(new AbstractHandler()
- {
- @Override
- public void handle(String uri, Request request, HttpServletRequest servletRequest, HttpServletResponse servletResponse)
- {
- request.setHandled(true);
- }
- });
+ start(new EmptyServerHandler());
AtomicReference serverIncoming = new AtomicReference<>("");
CountDownLatch serverIncomingLatch = new CountDownLatch(1);
@@ -150,14 +140,14 @@ public class NetworkTrafficListenerTest
@Override
public void incoming(Socket socket, ByteBuffer bytes)
{
- serverIncoming.set(serverIncoming.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ serverIncoming.set(serverIncoming.get() + BufferUtil.toString(bytes, UTF_8));
serverIncomingLatch.countDown();
}
@Override
public void outgoing(Socket socket, ByteBuffer bytes)
{
- serverOutgoing.set(serverOutgoing.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ serverOutgoing.set(serverOutgoing.get() + BufferUtil.toString(bytes, UTF_8));
serverOutgoingLatch.countDown();
}
});
@@ -171,14 +161,14 @@ public class NetworkTrafficListenerTest
@Override
public void outgoing(Socket socket, ByteBuffer bytes)
{
- clientOutgoing.set(clientOutgoing.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ clientOutgoing.set(clientOutgoing.get() + BufferUtil.toString(bytes, UTF_8));
clientOutgoingLatch.countDown();
}
@Override
public void incoming(Socket socket, ByteBuffer bytes)
{
- clientIncoming.set(clientIncoming.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ clientIncoming.set(clientIncoming.get() + BufferUtil.toString(bytes, UTF_8));
clientIncomingLatch.countDown();
}
});
@@ -200,14 +190,12 @@ public class NetworkTrafficListenerTest
public void testTrafficWithResponseContentOnPersistentConnection() throws Exception
{
String responseContent = "response_content" + END_OF_CONTENT;
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String uri, Request request, HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
- request.setHandled(true);
- ServletOutputStream output = servletResponse.getOutputStream();
- output.write(responseContent.getBytes(StandardCharsets.UTF_8));
+ response.write(true, callback, UTF_8.encode(responseContent));
}
});
@@ -220,14 +208,14 @@ public class NetworkTrafficListenerTest
@Override
public void incoming(Socket socket, ByteBuffer bytes)
{
- serverIncoming.set(serverIncoming.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ serverIncoming.set(serverIncoming.get() + BufferUtil.toString(bytes, UTF_8));
serverIncomingLatch.countDown();
}
@Override
public void outgoing(Socket socket, ByteBuffer bytes)
{
- serverOutgoing.set(serverOutgoing.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ serverOutgoing.set(serverOutgoing.get() + BufferUtil.toString(bytes, UTF_8));
serverOutgoingLatch.countDown();
}
});
@@ -241,14 +229,14 @@ public class NetworkTrafficListenerTest
@Override
public void outgoing(Socket socket, ByteBuffer bytes)
{
- clientOutgoing.set(clientOutgoing.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ clientOutgoing.set(clientOutgoing.get() + BufferUtil.toString(bytes, UTF_8));
clientOutgoingLatch.countDown();
}
@Override
public void incoming(Socket socket, ByteBuffer bytes)
{
- clientIncoming.set(clientIncoming.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ clientIncoming.set(clientIncoming.get() + BufferUtil.toString(bytes, UTF_8));
clientIncomingLatch.countDown();
}
});
@@ -271,17 +259,13 @@ public class NetworkTrafficListenerTest
String responseContent = "response_content";
String responseChunk1 = responseContent.substring(0, responseContent.length() / 2);
String responseChunk2 = responseContent.substring(responseContent.length() / 2);
- start(new AbstractHandler()
+ start(new EmptyServerHandler()
{
@Override
- public void handle(String uri, Request request, HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws IOException
+ protected void service(Request request, Response response) throws Throwable
{
- request.setHandled(true);
- ServletOutputStream output = servletResponse.getOutputStream();
- output.write(responseChunk1.getBytes(StandardCharsets.UTF_8));
- output.flush();
- output.write(responseChunk2.getBytes(StandardCharsets.UTF_8));
- output.flush();
+ Response.write(response, false, UTF_8.encode(responseChunk1));
+ Response.write(response, false, UTF_8.encode(responseChunk2));
}
});
@@ -294,14 +278,14 @@ public class NetworkTrafficListenerTest
@Override
public void incoming(Socket socket, ByteBuffer bytes)
{
- serverIncoming.set(serverIncoming.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ serverIncoming.set(serverIncoming.get() + BufferUtil.toString(bytes, UTF_8));
serverIncomingLatch.countDown();
}
@Override
public void outgoing(Socket socket, ByteBuffer bytes)
{
- serverOutgoing.set(serverOutgoing.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ serverOutgoing.set(serverOutgoing.get() + BufferUtil.toString(bytes, UTF_8));
if (serverOutgoing.get().endsWith("\r\n0\r\n\r\n"))
serverOutgoingLatch.countDown();
}
@@ -316,14 +300,14 @@ public class NetworkTrafficListenerTest
@Override
public void outgoing(Socket socket, ByteBuffer bytes)
{
- clientOutgoing.set(clientOutgoing.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ clientOutgoing.set(clientOutgoing.get() + BufferUtil.toString(bytes, UTF_8));
clientOutgoingLatch.countDown();
}
@Override
public void incoming(Socket socket, ByteBuffer bytes)
{
- clientIncoming.set(clientIncoming.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ clientIncoming.set(clientIncoming.get() + BufferUtil.toString(bytes, UTF_8));
if (clientIncoming.get().endsWith("\r\n0\r\n\r\n"))
clientIncomingLatch.countDown();
}
@@ -344,13 +328,12 @@ public class NetworkTrafficListenerTest
public void testTrafficWithRequestContentWithResponseRedirectOnPersistentConnection() throws Exception
{
String location = "/redirect";
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String uri, Request request, HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
- request.setHandled(true);
- servletResponse.sendRedirect(location);
+ Response.sendRedirect(request, response, callback, location);
}
});
@@ -363,14 +346,14 @@ public class NetworkTrafficListenerTest
@Override
public void incoming(Socket socket, ByteBuffer bytes)
{
- serverIncoming.set(serverIncoming.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ serverIncoming.set(serverIncoming.get() + BufferUtil.toString(bytes, UTF_8));
serverIncomingLatch.countDown();
}
@Override
public void outgoing(Socket socket, ByteBuffer bytes)
{
- serverOutgoing.set(serverOutgoing.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ serverOutgoing.set(serverOutgoing.get() + BufferUtil.toString(bytes, UTF_8));
serverOutgoingLatch.countDown();
}
});
@@ -384,14 +367,14 @@ public class NetworkTrafficListenerTest
@Override
public void outgoing(Socket socket, ByteBuffer bytes)
{
- clientOutgoing.set(clientOutgoing.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ clientOutgoing.set(clientOutgoing.get() + BufferUtil.toString(bytes, UTF_8));
clientOutgoingLatch.countDown();
}
@Override
public void incoming(Socket socket, ByteBuffer bytes)
{
- clientIncoming.set(clientIncoming.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ clientIncoming.set(clientIncoming.get() + BufferUtil.toString(bytes, UTF_8));
clientIncomingLatch.countDown();
}
});
@@ -416,23 +399,15 @@ public class NetworkTrafficListenerTest
@Test
public void testTrafficWithBigRequestContentOnPersistentConnection() throws Exception
{
- start(new AbstractHandler()
+ start(new EmptyServerHandler()
{
@Override
- public void handle(String uri, Request request, HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws IOException
+ protected void service(Request request, Response response) throws Throwable
{
// Read and discard the request body to make the test more
// reliable, otherwise there is a race between request body
// upload and response download
- InputStream input = servletRequest.getInputStream();
- byte[] buffer = new byte[4096];
- while (true)
- {
- int read = input.read(buffer);
- if (read < 0)
- break;
- }
- request.setHandled(true);
+ Content.consumeAll(request);
}
});
@@ -444,13 +419,13 @@ public class NetworkTrafficListenerTest
@Override
public void incoming(Socket socket, ByteBuffer bytes)
{
- serverIncoming.set(serverIncoming.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ serverIncoming.set(serverIncoming.get() + BufferUtil.toString(bytes, UTF_8));
}
@Override
public void outgoing(Socket socket, ByteBuffer bytes)
{
- serverOutgoing.set(serverOutgoing.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ serverOutgoing.set(serverOutgoing.get() + BufferUtil.toString(bytes, UTF_8));
serverOutgoingLatch.countDown();
}
});
@@ -463,13 +438,13 @@ public class NetworkTrafficListenerTest
@Override
public void outgoing(Socket socket, ByteBuffer bytes)
{
- clientOutgoing.set(clientOutgoing.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ clientOutgoing.set(clientOutgoing.get() + BufferUtil.toString(bytes, UTF_8));
}
@Override
public void incoming(Socket socket, ByteBuffer bytes)
{
- clientIncoming.set(clientIncoming.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
+ clientIncoming.set(clientIncoming.get() + BufferUtil.toString(bytes, UTF_8));
clientIncomingLatch.countDown();
}
});
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ProxyConfigurationTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ProxyConfigurationTest.java
index c10f045d046..39fb2e84cb9 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ProxyConfigurationTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ProxyConfigurationTest.java
@@ -23,14 +23,14 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class ProxyConfigurationTest
{
@Test
- public void testProxyMatchesWithoutIncludesWithoutExcludes() throws Exception
+ public void testProxyMatchesWithoutIncludesWithoutExcludes()
{
HttpProxy proxy = new HttpProxy("host", 0);
assertTrue(proxy.matches(new Origin("http", "any", 0)));
}
@Test
- public void testProxyMatchesWithOnlyExcludes() throws Exception
+ public void testProxyMatchesWithOnlyExcludes()
{
HttpProxy proxy = new HttpProxy("host", 0);
proxy.getExcludedAddresses().add("1.2.3.4:5");
@@ -41,7 +41,7 @@ public class ProxyConfigurationTest
}
@Test
- public void testProxyMatchesWithOnlyIncludes() throws Exception
+ public void testProxyMatchesWithOnlyIncludes()
{
HttpProxy proxy = new HttpProxy("host", 0);
proxy.getIncludedAddresses().add("1.2.3.4:5");
@@ -52,7 +52,7 @@ public class ProxyConfigurationTest
}
@Test
- public void testProxyMatchesWithIncludesAndExcludes() throws Exception
+ public void testProxyMatchesWithIncludesAndExcludes()
{
HttpProxy proxy = new HttpProxy("host", 0);
proxy.getIncludedAddresses().add("1.2.3.4");
@@ -64,7 +64,7 @@ public class ProxyConfigurationTest
}
@Test
- public void testProxyMatchesWithIncludesAndExcludesIPv6() throws Exception
+ public void testProxyMatchesWithIncludesAndExcludesIPv6()
{
Assumptions.assumeTrue(Net.isIpv6InterfaceAvailable());
HttpProxy proxy = new HttpProxy("host", 0);
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ServerConnectionCloseTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ServerConnectionCloseTest.java
index f28995e2693..818ae143acb 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ServerConnectionCloseTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ServerConnectionCloseTest.java
@@ -18,6 +18,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
+import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.client.api.ContentResponse;
@@ -130,7 +131,7 @@ public class ServerConnectionCloseTest
serverResponse += content;
}
- output.write(serverResponse.getBytes("UTF-8"));
+ output.write(serverResponse.getBytes(StandardCharsets.UTF_8));
output.flush();
if (shutdownOutput)
socket.shutdownOutput();
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java
index 783c2ddf16e..d05e61a21d1 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java
@@ -18,6 +18,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
+import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
@@ -135,7 +136,7 @@ public class TLSServerConnectionCloseTest
serverResponse += content;
}
- output.write(serverResponse.getBytes("UTF-8"));
+ output.write(serverResponse.getBytes(StandardCharsets.UTF_8));
output.flush();
switch (closeMode)
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ValidatingConnectionPoolTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ValidatingConnectionPoolTest.java
index e5343845e57..6dc75609771 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ValidatingConnectionPoolTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ValidatingConnectionPoolTest.java
@@ -13,13 +13,9 @@
package org.eclipse.jetty.client;
-import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.util.FutureResponseListener;
@@ -27,7 +23,7 @@ import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.Response;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
@@ -71,25 +67,24 @@ public class ValidatingConnectionPoolTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testServerClosesConnectionAfterRedirectWithoutConnectionCloseHeader(Scenario scenario) throws Exception
{
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response) throws Throwable
{
- baseRequest.setHandled(true);
- if (target.endsWith("/redirect"))
+ if (request.getPathInContext().endsWith("/redirect"))
{
response.setStatus(HttpStatus.TEMPORARY_REDIRECT_307);
response.setContentLength(0);
- response.setHeader(HttpHeader.LOCATION.asString(), scenario.getScheme() + "://localhost:" + connector.getLocalPort() + "/");
- response.flushBuffer();
- baseRequest.getHttpChannel().getEndPoint().shutdownOutput();
+ response.getHeaders().put(HttpHeader.LOCATION, scenario.getScheme() + "://localhost:" + connector.getLocalPort() + "/");
+ Response.write(response, false);
+ request.getConnectionMetaData().getConnection().getEndPoint().shutdownOutput();
}
else
{
response.setStatus(HttpStatus.OK_200);
response.setContentLength(0);
- response.setHeader(HttpHeader.CONNECTION.asString(), HttpHeaderValue.CLOSE.asString());
+ response.getHeaders().put(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString());
}
}
});
@@ -106,15 +101,14 @@ public class ValidatingConnectionPoolTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testServerClosesConnectionAfterResponseWithQueuedRequestWithMaxConnectionsWithConnectionCloseHeader(Scenario scenario) throws Exception
{
- testServerClosesConnectionAfterResponseWithQueuedRequestWithMaxConnections(scenario, new AbstractHandler()
+ testServerClosesConnectionAfterResponseWithQueuedRequestWithMaxConnections(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response)
{
- baseRequest.setHandled(true);
response.setStatus(HttpStatus.OK_200);
response.setContentLength(0);
- response.setHeader(HttpHeader.CONNECTION.asString(), HttpHeaderValue.CLOSE.asString());
+ response.getHeaders().put(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString());
}
});
}
@@ -123,16 +117,15 @@ public class ValidatingConnectionPoolTest extends AbstractHttpClientServerTest
@ArgumentsSource(ScenarioProvider.class)
public void testServerClosesConnectionAfterResponseWithQueuedRequestWithMaxConnectionsWithoutConnectionCloseHeader(Scenario scenario) throws Exception
{
- testServerClosesConnectionAfterResponseWithQueuedRequestWithMaxConnections(scenario, new AbstractHandler()
+ testServerClosesConnectionAfterResponseWithQueuedRequestWithMaxConnections(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response) throws Throwable
{
- baseRequest.setHandled(true);
response.setStatus(HttpStatus.OK_200);
response.setContentLength(0);
- response.flushBuffer();
- baseRequest.getHttpChannel().getEndPoint().shutdownOutput();
+ Response.write(response, false);
+ request.getConnectionMetaData().getConnection().getEndPoint().shutdownOutput();
}
});
}
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesTest.java
index 3618d26a34c..88392be70ee 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesTest.java
@@ -331,7 +331,7 @@ public abstract class SslBytesTest
}
});
assertTrue(startLatch.await(5, TimeUnit.SECONDS));
- return new SslBytesServerTest.SimpleProxy.AutomaticFlow(stopLatch, clientToServer, serverToClient);
+ return new SslBytesTest.SimpleProxy.AutomaticFlow(stopLatch, clientToServer, serverToClient);
}
public boolean awaitClient(int time, TimeUnit unit) throws InterruptedException
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/InputStreamContentTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/InputStreamContentTest.java
index a4a351575ec..f03e540a5e2 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/InputStreamContentTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/InputStreamContentTest.java
@@ -16,24 +16,23 @@ package org.eclipse.jetty.client.util;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.ByteBuffer;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.EmptyServerHandler;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.server.Content;
import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.params.ParameterizedTest;
@@ -103,10 +102,10 @@ public class InputStreamContentTest
start(new EmptyServerHandler()
{
@Override
- protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(org.eclipse.jetty.server.Request request, Response response) throws Exception
{
serverLatch.countDown();
- if (request.getInputStream().read() >= 0)
+ if (Content.readAllBytes(request).hasRemaining())
throw new IOException();
}
});
@@ -178,9 +177,11 @@ public class InputStreamContentTest
start(new EmptyServerHandler()
{
@Override
- protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response) throws Exception
{
- assertEquals(singleByteContent, request.getInputStream().read());
+ ByteBuffer buffer = Content.readAllBytes(request);
+ assertTrue(buffer.hasRemaining());
+ assertEquals(singleByteContent, buffer.get());
serverLatch.countDown();
}
});
@@ -234,10 +235,10 @@ public class InputStreamContentTest
start(new EmptyServerHandler()
{
@Override
- protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void service(org.eclipse.jetty.server.Request request, Response response) throws Exception
{
serverLatch.countDown();
- IO.copy(request.getInputStream(), IO.getNullStream());
+ Content.consumeAll(request);
}
});
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartContentTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartContentTest.java
index 008501889c2..423845564c7 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartContentTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartContentTest.java
@@ -13,50 +13,23 @@
package org.eclipse.jetty.client.util;
-import java.io.BufferedWriter;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardOpenOption;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Random;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import jakarta.servlet.MultipartConfigElement;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.servlet.http.Part;
import org.eclipse.jetty.client.AbstractHttpClientServerTest;
-import org.eclipse.jetty.client.api.ContentResponse;
-import org.eclipse.jetty.http.HttpFields;
-import org.eclipse.jetty.http.HttpHeader;
-import org.eclipse.jetty.http.HttpMethod;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
-import org.eclipse.jetty.util.IO;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.ArgumentsSource;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
-import static org.eclipse.jetty.toolchain.test.StackUtils.supply;
-import static org.junit.jupiter.api.Assertions.assertArrayEquals;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+// TODO
// @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck
+@Disabled
public class MultiPartContentTest extends AbstractHttpClientServerTest
{
+ @Test
+ public void testNeedToUpdateThisTest()
+ {
+ fail("This test needs to be updated to use Core version of multipart (when available)");
+ }
+/*
@ParameterizedTest
@ArgumentsSource(ScenarioProvider.class)
public void testEmptyMultiPart(Scenario scenario) throws Exception
@@ -445,4 +418,5 @@ public class MultiPartContentTest extends AbstractHttpClientServerTest
protected abstract void handle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}
+*/
}
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java
index 918a41d762a..2563f0723bb 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java
@@ -13,53 +13,23 @@
package org.eclipse.jetty.client.util;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.net.URI;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.time.Duration;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
-
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.apache.kerby.kerberos.kerb.server.SimpleKdcServer;
import org.eclipse.jetty.client.AbstractHttpClientServerTest;
-import org.eclipse.jetty.client.EmptyServerHandler;
-import org.eclipse.jetty.client.api.Authentication;
-import org.eclipse.jetty.client.api.AuthenticationStore;
-import org.eclipse.jetty.client.api.ContentResponse;
-import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.client.api.Response;
-import org.eclipse.jetty.security.ConfigurableSpnegoLoginService;
-import org.eclipse.jetty.security.ConstraintMapping;
-import org.eclipse.jetty.security.ConstraintSecurityHandler;
-import org.eclipse.jetty.security.HashLoginService;
-import org.eclipse.jetty.security.authentication.AuthorizationService;
-import org.eclipse.jetty.security.authentication.ConfigurableSpnegoAuthenticator;
-import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.session.DefaultSessionIdManager;
-import org.eclipse.jetty.server.session.SessionHandler;
-import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
-import org.eclipse.jetty.util.IO;
-import org.eclipse.jetty.util.security.Constraint;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.ArgumentsSource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.fail;
+// TODO
+@Disabled
public class SPNEGOAuthenticationTest extends AbstractHttpClientServerTest
{
+ @Test
+ public void testNeedToUpdateThisTest()
+ {
+ fail("This test needs to be updated to use Core version of SPNEGO (when available)");
+ }
+
+ /*
private static final Logger LOG = LoggerFactory.getLogger(SPNEGOAuthenticationTest.class);
static
@@ -286,4 +256,5 @@ public class SPNEGOAuthenticationTest extends AbstractHttpClientServerTest
// Authentication expired, but POSTs are allowed.
assertEquals(1, requests.get());
}
+ */
}
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/TypedContentProviderTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/TypedContentProviderTest.java
index 3111be179fe..09681220af8 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/TypedContentProviderTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/TypedContentProviderTest.java
@@ -13,25 +13,25 @@
package org.eclipse.jetty.client.util;
-import java.io.IOException;
import java.nio.charset.StandardCharsets;
+import java.util.List;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.AbstractHttpClientServerTest;
+import org.eclipse.jetty.client.EmptyServerHandler;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.server.Content;
+import org.eclipse.jetty.server.FutureFormFields;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.IO;
-import org.hamcrest.Matchers;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -48,19 +48,20 @@ public class TypedContentProviderTest extends AbstractHttpClientServerTest
// @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck
final String value3 = "\u20AC";
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
+ protected void service(Request request, Response response)
{
- baseRequest.setHandled(true);
assertEquals("POST", request.getMethod());
- assertEquals(MimeTypes.Type.FORM_ENCODED.asString(), request.getContentType());
- assertEquals(value1, request.getParameter(name1));
- String[] values = request.getParameterValues(name2);
- assertNotNull(values);
- assertEquals(2, values.length);
- assertThat(values, Matchers.arrayContainingInAnyOrder(value2, value3));
+ assertEquals(MimeTypes.Type.FORM_ENCODED.asString(), request.getHeaders().get(HttpHeader.CONTENT_TYPE));
+ new FutureFormFields(request).whenComplete((fields, failure) ->
+ {
+ assertEquals(value1, fields.get(name1).getValue());
+ List values = fields.get(name2).getValues();
+ assertEquals(2, values.size());
+ assertThat(values, containsInAnyOrder(value2, value3));
+ });
}
});
@@ -87,15 +88,14 @@ public class TypedContentProviderTest extends AbstractHttpClientServerTest
final String content = FormRequestContent.convert(fields);
final String contentType = "text/plain;charset=UTF-8";
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(Request request, Response response) throws Throwable
{
- baseRequest.setHandled(true);
assertEquals("POST", request.getMethod());
- assertEquals(contentType, request.getContentType());
- assertEquals(content, IO.toString(request.getInputStream()));
+ assertEquals(contentType, request.getHeaders().get(HttpHeader.CONTENT_TYPE));
+ assertEquals(content, Content.readAll(request));
}
});
@@ -115,15 +115,14 @@ public class TypedContentProviderTest extends AbstractHttpClientServerTest
{
final String content = "data";
- start(scenario, new AbstractHandler()
+ start(scenario, new EmptyServerHandler()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void service(Request request, Response response) throws Throwable
{
- baseRequest.setHandled(true);
assertEquals("GET", request.getMethod());
- assertNotNull(request.getContentType());
- assertEquals(content, IO.toString(request.getInputStream()));
+ assertNotNull(request.getHeaders().get(HttpHeader.CONTENT_TYPE));
+ assertEquals(content, Content.readAll(request));
}
});
diff --git a/jetty-core/jetty-deploy/pom.xml b/jetty-core/jetty-deploy/pom.xml
index c2ae4057fd6..c672ea39940 100644
--- a/jetty-core/jetty-deploy/pom.xml
+++ b/jetty-core/jetty-deploy/pom.xml
@@ -1,13 +1,13 @@
org.eclipse.jetty
- jetty-project
- 11.0.10-SNAPSHOT
+ jetty-core
+ 12.0.0-SNAPSHOT4.0.0jetty-deploy
- Jetty :: Deployers
+ Jetty Core :: DeployersJetty deployers
@@ -21,7 +21,7 @@
maven-surefire-plugin
- @{argLine} ${jetty.surefire.argLine} --add-modules org.eclipse.jetty.jmx --add-reads org.eclipse.jetty.deploy=org.eclipse.jetty.http,jetty.servlet.api
+ @{argLine} ${jetty.surefire.argLine} --add-modules org.eclipse.jetty.jmx --add-reads org.eclipse.jetty.deploy=org.eclipse.jetty.http
@@ -31,7 +31,7 @@
org.eclipse.jetty
- jetty-webapp
+ jetty-serverorg.eclipse.jetty
diff --git a/jetty-core/jetty-deploy/src/main/config/etc/jetty-decorate.xml b/jetty-core/jetty-deploy/src/main/config/etc/jetty-decorate.xml
index 3abfb16941b..73069bafa59 100644
--- a/jetty-core/jetty-deploy/src/main/config/etc/jetty-decorate.xml
+++ b/jetty-core/jetty-deploy/src/main/config/etc/jetty-decorate.xml
@@ -5,7 +5,7 @@
-
+ /etc/jetty-web-decorate.xml
diff --git a/jetty-core/jetty-deploy/src/main/config/etc/jetty-deploy.xml b/jetty-core/jetty-deploy/src/main/config/etc/jetty-deploy.xml
index a07afd3da92..73e8d86929f 100644
--- a/jetty-core/jetty-deploy/src/main/config/etc/jetty-deploy.xml
+++ b/jetty-core/jetty-deploy/src/main/config/etc/jetty-deploy.xml
@@ -38,7 +38,7 @@
-
+
diff --git a/jetty-core/jetty-deploy/src/main/config/etc/jetty-web-decorate.xml b/jetty-core/jetty-deploy/src/main/config/etc/jetty-web-decorate.xml
index f91048c4b73..25ff88b5f60 100644
--- a/jetty-core/jetty-deploy/src/main/config/etc/jetty-web-decorate.xml
+++ b/jetty-core/jetty-deploy/src/main/config/etc/jetty-web-decorate.xml
@@ -1,13 +1,13 @@
-
+
-
+
-
+
diff --git a/jetty-core/jetty-deploy/src/main/config/modules/decorate.mod b/jetty-core/jetty-deploy/src/main/config/modules/decorate.mod
index 3315ed0cbd3..fe95fbb3c27 100644
--- a/jetty-core/jetty-deploy/src/main/config/modules/decorate.mod
+++ b/jetty-core/jetty-deploy/src/main/config/modules/decorate.mod
@@ -4,9 +4,9 @@
Jetty setup to support Decoration of Listeners, Filters and Servlets within a deployed webapp.
This module uses DecoratingListener to register an object set as a context attribute
as a dynamic decorator.
-This module sets the "org.eclipse.jetty.webapp.DecoratingListener"
+This module sets the "org.eclipse.jetty.ee9.webapp.DecoratingListener"
context attribute with the name of the context attribute that will be listened to.
-By default the attribute is "org.eclipse.jetty.webapp.decorator".
+By default the attribute is "org.eclipse.jetty.ee9.webapp.decorator".
[depend]
deploy
diff --git a/jetty-core/jetty-deploy/src/main/config/modules/global-webapp-common.d/global-webapp-common.xml b/jetty-core/jetty-deploy/src/main/config/modules/global-webapp-common.d/global-webapp-common.xml
index 7f28fd55ca5..2a933198d95 100644
--- a/jetty-core/jetty-deploy/src/main/config/modules/global-webapp-common.d/global-webapp-common.xml
+++ b/jetty-core/jetty-deploy/src/main/config/modules/global-webapp-common.d/global-webapp-common.xml
@@ -5,7 +5,7 @@
-
+
diff --git a/jetty-core/jetty-deploy/src/main/config/modules/global-webapp-common.d/webapp-common.xml b/jetty-core/jetty-deploy/src/main/config/modules/global-webapp-common.d/webapp-common.xml
index 02e338e6c9c..a83fbd4f1e4 100644
--- a/jetty-core/jetty-deploy/src/main/config/modules/global-webapp-common.d/webapp-common.xml
+++ b/jetty-core/jetty-deploy/src/main/config/modules/global-webapp-common.d/webapp-common.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/jetty-deploy/src/main/java/module-info.java b/jetty-core/jetty-deploy/src/main/java/module-info.java
similarity index 95%
rename from jetty-deploy/src/main/java/module-info.java
rename to jetty-core/jetty-deploy/src/main/java/module-info.java
index 5e5b4dfff8b..75d5423efd5 100644
--- a/jetty-deploy/src/main/java/module-info.java
+++ b/jetty-core/jetty-deploy/src/main/java/module-info.java
@@ -15,10 +15,9 @@ module org.eclipse.jetty.deploy
{
requires java.xml;
requires org.eclipse.jetty.xml;
+ requires org.eclipse.jetty.server;
requires org.slf4j;
- requires transitive org.eclipse.jetty.webapp;
-
// Only required if using JMX.
requires static org.eclipse.jetty.jmx;
diff --git a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/App.java b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/App.java
index 65cfe23b62b..acf8a132780 100644
--- a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/App.java
+++ b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/App.java
@@ -14,7 +14,7 @@
package org.eclipse.jetty.deploy;
import org.eclipse.jetty.server.handler.ContextHandler;
-import org.eclipse.jetty.util.AttributesMap;
+import org.eclipse.jetty.util.Attributes;
/**
* The information about an App that is managed by the {@link DeploymentManager}
@@ -23,6 +23,7 @@ public class App
{
private final DeploymentManager _manager;
private final AppProvider _provider;
+ private final String _environment;
private final String _originId;
private ContextHandler _context;
@@ -31,36 +32,20 @@ public class App
*
* @param manager the deployment manager
* @param provider the app provider
+ * @param environment the name of the environment or null for the server environment.
* @param originId the origin ID (The ID that the {@link AppProvider} knows
* about)
* @see App#getOriginId()
* @see App#getContextPath()
*/
- public App(DeploymentManager manager, AppProvider provider, String originId)
+ public App(DeploymentManager manager, AppProvider provider, String environment, String originId)
{
_manager = manager;
_provider = provider;
+ _environment = environment;
_originId = originId;
}
- /**
- * Create an App with specified Origin ID and archivePath
- *
- * @param manager the deployment manager
- * @param provider the app provider
- * @param originId the origin ID (The ID that the {@link AppProvider} knows
- * about)
- * @param context Some implementations of AppProvider might have to use an
- * already created ContextHandler.
- * @see App#getOriginId()
- * @see App#getContextPath()
- */
- public App(DeploymentManager manager, AppProvider provider, String originId, ContextHandler context)
- {
- this(manager, provider, originId);
- _context = context;
- }
-
/**
* @return The deployment manager
*/
@@ -93,13 +78,14 @@ public class App
{
_context = getAppProvider().createContextHandler(this);
- AttributesMap attributes = _manager.getContextAttributes();
+ Attributes.Mapped attributes = _manager.getContextAttributes();
if (attributes != null && attributes.size() > 0)
{
// Merge the manager attributes under the existing attributes
- attributes = new AttributesMap(attributes);
- attributes.addAll(_context.getAttributes());
- _context.setAttributes(attributes);
+ for (String name : attributes.getAttributeNameSet())
+ {
+ _context.setAttribute(name, attributes.getAttribute(name));
+ }
}
}
return _context;
@@ -129,11 +115,12 @@ public class App
*/
public String getContextPath()
{
- if (this._context == null)
- {
- return null;
- }
- return this._context.getContextPath();
+ return _context == null ? null : _context.getContextPath();
+ }
+
+ public String getEnvironment()
+ {
+ return _environment;
}
/**
diff --git a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java
index 5700493b375..dd182d5e2a5 100644
--- a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java
+++ b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java
@@ -34,7 +34,7 @@ import org.eclipse.jetty.deploy.graph.Node;
import org.eclipse.jetty.deploy.graph.Path;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
-import org.eclipse.jetty.util.AttributesMap;
+import org.eclipse.jetty.util.Attributes;
import org.eclipse.jetty.util.MultiException;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
@@ -125,10 +125,11 @@ public class DeploymentManager extends ContainerLifeCycle
private final List _providers = new ArrayList();
private final AppLifeCycle _lifecycle = new AppLifeCycle();
private final Queue _apps = new ConcurrentLinkedQueue();
- private AttributesMap _contextAttributes = new AttributesMap();
+ private Attributes.Mapped _contextAttributes = new Attributes.Mapped();
private ContextHandlerCollection _contexts;
private boolean _useStandardBindings = true;
private String _defaultLifeCycleGoal = AppLifeCycle.STARTED;
+ private String _defaultEnvironment = "ee9"; // TODO null or ee10?
/**
* Receive an app for processing.
@@ -225,6 +226,16 @@ public class DeploymentManager extends ContainerLifeCycle
_lifecycle.insertNode(edge, insertedNodeName);
}
+ public String getDefaultEnvironment()
+ {
+ return _defaultEnvironment;
+ }
+
+ public void setDefaultEnvironment(String defaultEnvironment)
+ {
+ _defaultEnvironment = defaultEnvironment;
+ }
+
@Override
protected void doStart() throws Exception
{
@@ -384,7 +395,7 @@ public class DeploymentManager extends ContainerLifeCycle
return _contextAttributes.getAttribute(name);
}
- public AttributesMap getContextAttributes()
+ public Attributes.Mapped getContextAttributes()
{
return _contextAttributes;
}
@@ -582,9 +593,10 @@ public class DeploymentManager extends ContainerLifeCycle
_contextAttributes.setAttribute(name, value);
}
- public void setContextAttributes(AttributesMap contextAttributes)
+ public void setContextAttributes(Attributes contextAttributes)
{
- this._contextAttributes = contextAttributes;
+ this._contextAttributes.clearAttributes();
+ this._contextAttributes.addAll(contextAttributes);
}
public void setContexts(ContextHandlerCollection contexts)
diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/package-info.java b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/package-info.java
similarity index 100%
rename from jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/package-info.java
rename to jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/package-info.java
diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/package-info.java b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/package-info.java
similarity index 100%
rename from jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/package-info.java
rename to jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/package-info.java
diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/jmx/package-info.java b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/jmx/package-info.java
similarity index 100%
rename from jetty-deploy/src/main/java/org/eclipse/jetty/deploy/jmx/package-info.java
rename to jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/jmx/package-info.java
diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/package-info.java b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/package-info.java
similarity index 100%
rename from jetty-deploy/src/main/java/org/eclipse/jetty/deploy/package-info.java
rename to jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/package-info.java
diff --git a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java
index e252826437d..e9b332346a4 100644
--- a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java
+++ b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java
@@ -124,7 +124,10 @@ public abstract class ScanningAppProvider extends ContainerLifeCycle implements
*/
protected App createApp(String filename)
{
- return new App(_deploymentManager, this, filename);
+ // TODO otherways to work out the environment????
+ String environment = getDeploymentManager().getDefaultEnvironment();
+
+ return new App(_deploymentManager, this, environment, filename);
}
@Override
diff --git a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java
index 1dfa06730d5..e6a38eaac40 100644
--- a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java
+++ b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java
@@ -15,6 +15,7 @@ package org.eclipse.jetty.deploy.providers;
import java.io.File;
import java.io.FilenameFilter;
+import java.util.Arrays;
import java.util.Locale;
import org.eclipse.jetty.deploy.App;
@@ -26,8 +27,8 @@ import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
+import org.eclipse.jetty.util.component.Environment;
import org.eclipse.jetty.util.resource.Resource;
-import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.xml.XmlConfiguration;
import org.slf4j.LoggerFactory;
@@ -78,7 +79,7 @@ public class WebAppProvider extends ScanningAppProvider
String lowerName = name.toLowerCase(Locale.ENGLISH);
- Resource resource = Resource.newResource(new File(dir, name));
+ Resource resource = Resource.newResource(new File(dir, name)); // TODO use paths
if (getMonitoredResources().stream().anyMatch(resource::isSame))
return false;
@@ -205,7 +206,7 @@ public class WebAppProvider extends ScanningAppProvider
*/
public void setConfigurationClasses(String[] configurations)
{
- _configurationClasses = configurations == null ? null : (String[])configurations.clone();
+ _configurationClasses = configurations == null ? null : configurations.clone();
}
@ManagedAttribute("configuration classes for webapps to be processed through")
@@ -237,8 +238,9 @@ public class WebAppProvider extends ScanningAppProvider
return _tempDirectory;
}
- protected void initializeWebAppContextDefaults(WebAppContext webapp)
+ protected void initializeWebAppContextDefaults(ContextHandler webapp)
{
+ /* TODO
if (_defaultsDescriptor != null)
webapp.setDefaultsDescriptor(_defaultsDescriptor);
webapp.setExtractWAR(_extractWars);
@@ -248,76 +250,89 @@ public class WebAppProvider extends ScanningAppProvider
if (_tempDirectory != null)
{
- /* Since the Temp Dir is really a context base temp directory,
- * Lets set the Temp Directory in a way similar to how WebInfConfiguration does it,
- * instead of setting the WebAppContext.setTempDirectory(File).
- * If we used .setTempDirectory(File) all webapps will wind up in the
- * same temp / work directory, overwriting each others work.
- */
+ // Since the Temp Dir is really a context base temp directory,
+ // Lets set the Temp Directory in a way similar to how WebInfConfiguration does it,
+ // instead of setting the WebAppContext.setTempDirectory(File).
+ // If we used .setTempDirectory(File) all webapps will wind up in the
+ // same temp / work directory, overwriting each others work.
webapp.setAttribute(WebAppContext.BASETEMPDIR, _tempDirectory);
}
+ */
}
@Override
public ContextHandler createContextHandler(final App app) throws Exception
{
- Resource resource = Resource.newResource(app.getOriginId());
- File file = resource.getFile();
- if (!resource.exists())
- throw new IllegalStateException("App resource does not exist " + resource);
+ Environment environment = getDeploymentManager().getServer().getEnvironment(app.getEnvironment());
- final String contextName = file.getName();
+ if (LOG.isDebugEnabled())
+ LOG.debug("createContextHandler {} in {}", app, environment);
- // Resource aliases (after getting name) to ensure baseResource is not an alias
- if (resource.isAlias())
+ ClassLoader old = Thread.currentThread().getContextClassLoader();
+ try
{
- file = new File(resource.getAlias()).toPath().toRealPath().toFile();
- resource = Resource.newResource(file);
+ Thread.currentThread().setContextClassLoader(environment.getClassLoader());
+
+ Resource resource = Resource.newResource(app.getOriginId());
+ File file = resource.getFile();
if (!resource.exists())
throw new IllegalStateException("App resource does not exist " + resource);
- }
- // Handle a context XML file
- if (resource.exists() && FileID.isXmlFile(file))
- {
- XmlConfiguration xmlc = new XmlConfiguration(resource)
+ final String contextName = file.getName();
+
+ // Resource aliases (after getting name) to ensure baseResource is not an alias
+ if (resource.isAlias())
{
- @Override
- public void initializeDefaults(Object context)
+ file = new File(resource.getAlias()).toPath().toRealPath().toFile();
+ resource = Resource.newResource(file);
+ if (!resource.exists())
+ throw new IllegalStateException("App resource does not exist " + resource);
+ }
+
+ // Handle a context XML file
+ if (resource.exists() && FileID.isXmlFile(file))
+ {
+ XmlConfiguration xmlc = new XmlConfiguration(resource)
{
- super.initializeDefaults(context);
+ @Override
+ public void initializeDefaults(Object context)
+ {
+ super.initializeDefaults(context);
- // If the XML created object is a ContextHandler
- if (context instanceof ContextHandler)
- // Initialize the context path prior to running context XML
- initializeContextPath((ContextHandler)context, contextName, true);
+ // If the XML created object is a ContextHandler
+ if (context instanceof ContextHandler)
+ // Initialize the context path prior to running context XML
+ initializeContextPath((ContextHandler)context, contextName, true);
- // If it is a webapp
- if (context instanceof WebAppContext)
- // initialize other defaults prior to running context XML
- initializeWebAppContextDefaults((WebAppContext)context);
- }
- };
+ if (context instanceof ContextHandler contextHandler)
+ initializeWebAppContextDefaults(contextHandler);
+ }
+ };
- getDeploymentManager().scope(xmlc, resource);
+ xmlc.getIdMap().put("Environment", environment);
+ getDeploymentManager().scope(xmlc, resource);
+ if (getConfigurationManager() != null)
+ xmlc.getProperties().putAll(getConfigurationManager().getProperties());
+ return (ContextHandler)xmlc.configure();
+ }
+ // Otherwise it must be a directory or an archive
+ else if (!file.isDirectory() && !FileID.isWebArchiveFile(file))
+ {
+ throw new IllegalStateException("unable to create ContextHandler for " + app);
+ }
- if (getConfigurationManager() != null)
- xmlc.getProperties().putAll(getConfigurationManager().getProperties());
- return (ContextHandler)xmlc.configure();
+ // Build the web application
+ ContextHandler webAppContext = null; // TODO new WebAppContext();
+ webAppContext.setResourceBase(file.getAbsoluteFile().toPath());
+ initializeContextPath(webAppContext, contextName, !file.isDirectory());
+ initializeWebAppContextDefaults(webAppContext);
+
+ return webAppContext;
}
- // Otherwise it must be a directory or an archive
- else if (!file.isDirectory() && !FileID.isWebArchiveFile(file))
+ finally
{
- throw new IllegalStateException("unable to create ContextHandler for " + app);
+ Thread.currentThread().setContextClassLoader(old);
}
-
- // Build the web application
- WebAppContext webAppContext = new WebAppContext();
- webAppContext.setWar(file.getAbsolutePath());
- initializeContextPath(webAppContext, contextName, !file.isDirectory());
- initializeWebAppContextDefaults(webAppContext);
-
- return webAppContext;
}
protected void initializeContextPath(ContextHandler context, String contextName, boolean stripExtension)
@@ -342,7 +357,7 @@ public class WebAppProvider extends ScanningAppProvider
{
int dash = contextPath.indexOf('-');
String virtual = contextPath.substring(dash + 1);
- context.setVirtualHosts(virtual.split(","));
+ context.setVirtualHosts(Arrays.asList(virtual.split(",")));
contextPath = URIUtil.SLASH;
}
@@ -352,15 +367,7 @@ public class WebAppProvider extends ScanningAppProvider
// Set the display name and context Path
context.setDisplayName(contextName);
- if (context instanceof WebAppContext)
- {
- WebAppContext webAppContext = (WebAppContext)context;
- webAppContext.setDefaultContextPath(contextPath);
- }
- else
- {
- context.setContextPath(contextPath);
- }
+ context.setContextPath(contextPath);
}
@Override
diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/package-info.java b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/package-info.java
similarity index 100%
rename from jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/package-info.java
rename to jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/package-info.java
diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/util/package-info.java b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/util/package-info.java
similarity index 100%
rename from jetty-deploy/src/main/java/org/eclipse/jetty/deploy/util/package-info.java
rename to jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/util/package-info.java
diff --git a/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentManagerTest.java b/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentManagerTest.java
index 617f9f94d50..ee32352df60 100644
--- a/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentManagerTest.java
+++ b/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentManagerTest.java
@@ -20,6 +20,7 @@ import org.eclipse.jetty.deploy.test.XmlConfiguredJetty;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -77,6 +78,7 @@ public class DeploymentManagerTest
}
@Test
+ @Disabled // TODO
public void testXmlConfigured() throws Exception
{
XmlConfiguredJetty jetty = null;
diff --git a/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/MockAppProvider.java b/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/MockAppProvider.java
index 779cb62e888..5a8377b9592 100644
--- a/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/MockAppProvider.java
+++ b/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/MockAppProvider.java
@@ -20,8 +20,6 @@ import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
-import org.eclipse.jetty.util.resource.Resource;
-import org.eclipse.jetty.webapp.WebAppContext;
public class MockAppProvider extends AbstractLifeCycle implements AppProvider
{
@@ -42,17 +40,16 @@ public class MockAppProvider extends AbstractLifeCycle implements AppProvider
public void findWebapp(String name)
{
- App app = new App(deployMan, this, "mock-" + name);
+ App app = new App(deployMan, this, null, "mock-" + name);
this.deployMan.addApp(app);
}
@Override
public ContextHandler createContextHandler(App app) throws Exception
{
- WebAppContext context = new WebAppContext();
+ ContextHandler contextHandler = new ContextHandler();
File war = new File(webappsDir, app.getOriginId().substring(5));
- context.setWar(Resource.newResource(Resource.toURL(war)).toString());
String path = war.getName();
@@ -74,8 +71,8 @@ public class MockAppProvider extends AbstractLifeCycle implements AppProvider
if (path.endsWith("/") && path.length() > 0)
path = path.substring(0, path.length() - 1);
- context.setDefaultContextPath(path);
+ contextHandler.setContextPath(path);
- return context;
+ return contextHandler;
}
}
diff --git a/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderRuntimeUpdatesTest.java b/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderRuntimeUpdatesTest.java
index c7d76c110c5..0635ae62099 100644
--- a/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderRuntimeUpdatesTest.java
+++ b/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderRuntimeUpdatesTest.java
@@ -25,6 +25,7 @@ import org.eclipse.jetty.util.Scanner;
import org.eclipse.jetty.util.resource.Resource;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
@@ -35,6 +36,7 @@ import org.slf4j.LoggerFactory;
* deployed webapps due to incoming changes identified by the {@link ScanningAppProvider}.
*/
@ExtendWith(WorkDirExtension.class)
+@Disabled // TODO
public class ScanningAppProviderRuntimeUpdatesTest
{
private static final Logger LOG = LoggerFactory.getLogger(ScanningAppProviderRuntimeUpdatesTest.class);
@@ -118,7 +120,7 @@ public class ScanningAppProviderRuntimeUpdatesTest
waitForDirectoryScan();
waitForDirectoryScan();
- jetty.assertWebAppContextsExists("/foo");
+ jetty.assertContextHandlerExists("/foo");
}
/**
@@ -135,7 +137,7 @@ public class ScanningAppProviderRuntimeUpdatesTest
waitForDirectoryScan();
waitForDirectoryScan();
- jetty.assertWebAppContextsExists("/foo");
+ jetty.assertContextHandlerExists("/foo");
jetty.removeWebapp("foo.war");
jetty.removeWebapp("foo.xml");
@@ -143,7 +145,7 @@ public class ScanningAppProviderRuntimeUpdatesTest
waitForDirectoryScan();
waitForDirectoryScan();
- jetty.assertNoWebAppContexts();
+ jetty.assertNoContextHandlers();
}
/**
@@ -160,7 +162,7 @@ public class ScanningAppProviderRuntimeUpdatesTest
waitForDirectoryScan();
waitForDirectoryScan();
- jetty.assertWebAppContextsExists("/foo");
+ jetty.assertContextHandlerExists("/foo");
// Test that webapp response contains "-1"
jetty.assertResponseContains("/foo/info", "FooServlet-1");
@@ -173,7 +175,7 @@ public class ScanningAppProviderRuntimeUpdatesTest
// This should result in the existing foo.war being replaced with the new foo.war
waitForDirectoryScan();
waitForDirectoryScan();
- jetty.assertWebAppContextsExists("/foo");
+ jetty.assertContextHandlerExists("/foo");
// Test that webapp response contains "-2"
jetty.assertResponseContains("/foo/info", "FooServlet-2");
diff --git a/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderStartupTest.java b/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderStartupTest.java
index f638957fafb..443d62a33fd 100644
--- a/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderStartupTest.java
+++ b/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderStartupTest.java
@@ -18,6 +18,7 @@ import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -57,9 +58,10 @@ public class ScanningAppProviderStartupTest
}
@Test
+ @Disabled // TODO
public void testStartupContext()
{
// Check Server for Handlers
- jetty.assertWebAppContextsExists("/foo");
+ jetty.assertContextHandlerExists("/foo");
}
}
diff --git a/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java b/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java
index 13df6a7582a..8dcd08f20af 100644
--- a/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java
+++ b/jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java
@@ -37,14 +37,14 @@ import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.HandlerCollection;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.toolchain.test.PathAssert;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.resource.PathResource;
import org.eclipse.jetty.util.resource.Resource;
-import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.xml.XmlConfiguration;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -200,12 +200,12 @@ public class XmlConfiguredJetty
return Collections.unmodifiableList(_xmlConfigurations);
}
- public void assertNoWebAppContexts()
+ public void assertNoContextHandlers()
{
- List contexts = getWebAppContexts();
+ List contexts = getContextHandlers();
if (contexts.size() > 0)
{
- for (WebAppContext context : contexts)
+ for (ContextHandler context : contexts)
{
System.err.println("WebAppContext should not exist:\n" + context);
}
@@ -238,9 +238,9 @@ public class XmlConfiguredJetty
assertThat(content, containsString(needle));
}
- public void assertWebAppContextsExists(String... expectedContextPaths)
+ public void assertContextHandlerExists(String... expectedContextPaths)
{
- List contexts = getWebAppContexts();
+ List contexts = getContextHandlers();
if (expectedContextPaths.length != contexts.size())
{
System.err.println("## Expected Contexts");
@@ -249,7 +249,7 @@ public class XmlConfiguredJetty
System.err.println(expected);
}
System.err.println("## Actual Contexts");
- for (WebAppContext context : contexts)
+ for (ContextHandler context : contexts)
{
System.err.printf("%s ## %s%n", context.getContextPath(), context);
}
@@ -259,7 +259,7 @@ public class XmlConfiguredJetty
for (String expectedPath : expectedContextPaths)
{
boolean found = false;
- for (WebAppContext context : contexts)
+ for (ContextHandler context : contexts)
{
if (context.getContextPath().equals(expectedPath))
{
@@ -352,17 +352,17 @@ public class XmlConfiguredJetty
return URI.create(uri.toString());
}
- public List getWebAppContexts()
+ public List getContextHandlers()
{
- List contexts = new ArrayList<>();
- HandlerCollection handlers = (HandlerCollection)_server.getHandler();
- Handler[] children = handlers.getChildHandlers();
+ List contexts = new ArrayList<>();
+ ContextHandlerCollection handlers = (ContextHandlerCollection)_server.getHandler();
+ List children = handlers.getHandlers();
for (Handler handler : children)
{
- if (handler instanceof WebAppContext)
+ if (handler instanceof ContextHandler)
{
- WebAppContext context = (WebAppContext)handler;
+ ContextHandler context = (ContextHandler)handler;
contexts.add(context);
}
}
diff --git a/jetty-core/jetty-deploy/src/test/resources/binding-test-contexts-1.xml b/jetty-core/jetty-deploy/src/test/resources/binding-test-contexts-1.xml
index 6714b3b2316..98b637cacb8 100644
--- a/jetty-core/jetty-deploy/src/test/resources/binding-test-contexts-1.xml
+++ b/jetty-core/jetty-deploy/src/test/resources/binding-test-contexts-1.xml
@@ -7,7 +7,7 @@
-org.eclipse.jetty.jndi.-org.eclipse.jetty.plus.jaas.-org.eclipse.jetty.websocket.
- -org.eclipse.jetty.servlet.DefaultServlet
+ -org.eclipse.jetty.ee9.servlet.DefaultServletorg.eclipse.jetty.org.eclipse.foo.
@@ -20,7 +20,7 @@
org.apache.commons.loggingorg.eclipse.jetty.plus.jaas.org.eclipse.jetty.websocket
- org.eclipse.jetty.servlet.DefaultServlet
+ org.eclipse.jetty.ee9.servlet.DefaultServlet
@@ -33,7 +33,7 @@
-
+ /context-binding-test-1.xml
@@ -44,7 +44,7 @@
-
+ /webapps1
diff --git a/jetty-core/jetty-deploy/src/test/resources/context-binding-test-1.xml b/jetty-core/jetty-deploy/src/test/resources/context-binding-test-1.xml
index 9e5215df02a..7cb6f2e94a1 100644
--- a/jetty-core/jetty-deploy/src/test/resources/context-binding-test-1.xml
+++ b/jetty-core/jetty-deploy/src/test/resources/context-binding-test-1.xml
@@ -1,6 +1,6 @@
-
+org.eclipse.foo.
diff --git a/jetty-core/jetty-deploy/src/test/resources/etc/realm.properties b/jetty-core/jetty-deploy/src/test/resources/etc/realm.properties
index 492ffdb580a..cbf905de9fb 100644
--- a/jetty-core/jetty-deploy/src/test/resources/etc/realm.properties
+++ b/jetty-core/jetty-deploy/src/test/resources/etc/realm.properties
@@ -5,7 +5,7 @@
# : [, ...]
#
# Passwords may be clear text, obfuscated or checksummed. The class
-# org.eclipse.jetty.util.security.Password should be used to generate obfuscated
+# org.eclipse.util.Password should be used to generate obfuscated
# passwords or password checksums
#
# If DIGEST Authentication is used, the password must be in a recoverable
diff --git a/jetty-core/jetty-deploy/src/test/resources/etc/webdefault.xml b/jetty-core/jetty-deploy/src/test/resources/etc/webdefault.xml
index 0b8145c8551..3cfe11a75aa 100644
--- a/jetty-core/jetty-deploy/src/test/resources/etc/webdefault.xml
+++ b/jetty-core/jetty-deploy/src/test/resources/etc/webdefault.xml
@@ -34,7 +34,7 @@
- org.eclipse.jetty.servlet.listener.ELContextCleaner
+ org.eclipse.jetty.ee9.servlet.listener.ELContextCleaner
@@ -42,7 +42,7 @@
- org.eclipse.jetty.servlet.listener.IntrospectorCleaner
+ org.eclipse.jetty.ee9.servlet.listener.IntrospectorCleaner
@@ -52,15 +52,15 @@
@@ -131,7 +131,7 @@
default
- org.eclipse.jetty.servlet.DefaultServlet
+ org.eclipse.jetty.ee9.servlet.DefaultServletaliasesfalse
diff --git a/jetty-core/jetty-deploy/src/test/resources/jetty-deploy-wars.xml b/jetty-core/jetty-deploy/src/test/resources/jetty-deploy-wars.xml
index 8730443711b..770fedd1b6e 100644
--- a/jetty-core/jetty-deploy/src/test/resources/jetty-deploy-wars.xml
+++ b/jetty-core/jetty-deploy/src/test/resources/jetty-deploy-wars.xml
@@ -14,7 +14,7 @@
-
+ /webapps1/workish
diff --git a/jetty-core/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml b/jetty-core/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml
index c0a86628a4b..928a63c31ef 100644
--- a/jetty-core/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml
+++ b/jetty-core/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml
@@ -16,7 +16,7 @@
-
+ /webapps/etc/webdefault.xml1
diff --git a/jetty-core/jetty-deploy/src/test/resources/jetty-logging.properties b/jetty-core/jetty-deploy/src/test/resources/jetty-logging.properties
index ad1ad3a27ee..7b80290a89f 100644
--- a/jetty-core/jetty-deploy/src/test/resources/jetty-logging.properties
+++ b/jetty-core/jetty-deploy/src/test/resources/jetty-logging.properties
@@ -1,5 +1,5 @@
# Jetty Logging using jetty-slf4j-impl
#org.eclipse.jetty.deploy.DeploymentTempDirTest.LEVEL=DEBUG
#org.eclipse.jetty.deploy.LEVEL=DEBUG
-#org.eclipse.jetty.webapp.LEVEL=DEBUG
+#org.eclipse.jetty.ee9.webapp.LEVEL=DEBUG
#org.eclipse.jetty.util.Scanner=DEBUG
diff --git a/jetty-core/jetty-deploy/src/test/resources/webapps/badapp/badapp.xml b/jetty-core/jetty-deploy/src/test/resources/webapps/badapp/badapp.xml
index 952aab492d1..50e55934ba2 100644
--- a/jetty-core/jetty-deploy/src/test/resources/webapps/badapp/badapp.xml
+++ b/jetty-core/jetty-deploy/src/test/resources/webapps/badapp/badapp.xml
@@ -1,7 +1,7 @@
-
+/badapp/badapp.wartrue
diff --git a/jetty-core/jetty-deploy/src/test/resources/webapps/foo.xml b/jetty-core/jetty-deploy/src/test/resources/webapps/foo.xml
index 8b600c3bdc6..a373642f6a3 100644
--- a/jetty-core/jetty-deploy/src/test/resources/webapps/foo.xml
+++ b/jetty-core/jetty-deploy/src/test/resources/webapps/foo.xml
@@ -1,6 +1,6 @@
-
+/foo/foo.war
diff --git a/jetty-core/jetty-fcgi/fcgi-client/pom.xml b/jetty-core/jetty-fcgi/fcgi-client/pom.xml
index a2399cd69e6..9803acffe6d 100644
--- a/jetty-core/jetty-fcgi/fcgi-client/pom.xml
+++ b/jetty-core/jetty-fcgi/fcgi-client/pom.xml
@@ -2,13 +2,13 @@
org.eclipse.jetty.fcgi
- fcgi-parent
- 11.0.10-SNAPSHOT
+ fcgi
+ 12.0.0-SNAPSHOT4.0.0fcgi-client
- Jetty :: FastCGI :: Client
+ Jetty Core :: FastCGI :: Client${project.groupId}.client
diff --git a/jetty-fcgi/fcgi-client/src/main/java/module-info.java b/jetty-core/jetty-fcgi/fcgi-client/src/main/java/module-info.java
similarity index 83%
rename from jetty-fcgi/fcgi-client/src/main/java/module-info.java
rename to jetty-core/jetty-fcgi/fcgi-client/src/main/java/module-info.java
index e3805a29ee8..f6034926558 100644
--- a/jetty-fcgi/fcgi-client/src/main/java/module-info.java
+++ b/jetty-core/jetty-fcgi/fcgi-client/src/main/java/module-info.java
@@ -19,6 +19,7 @@ module org.eclipse.jetty.fcgi.client
exports org.eclipse.jetty.fcgi;
exports org.eclipse.jetty.fcgi.client.http;
- exports org.eclipse.jetty.fcgi.generator;
- exports org.eclipse.jetty.fcgi.parser;
+
+ exports org.eclipse.jetty.fcgi.generator to org.eclipse.jetty.fcgi.server;
+ exports org.eclipse.jetty.fcgi.parser to org.eclipse.jetty.fcgi.server;
}
diff --git a/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/FCGI.java b/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/FCGI.java
index a4a32757593..83e70fe1b3e 100644
--- a/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/FCGI.java
+++ b/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/FCGI.java
@@ -25,17 +25,13 @@ public class FCGI
public static Role from(int code)
{
- switch (code)
+ return switch (code)
{
- case 1:
- return RESPONDER;
- case 2:
- return AUTHORIZER;
- case 3:
- return FILTER;
- default:
- throw new IllegalArgumentException();
- }
+ case 1 -> RESPONDER;
+ case 2 -> AUTHORIZER;
+ case 3 -> FILTER;
+ default -> throw new IllegalArgumentException();
+ };
}
public final int code;
@@ -61,31 +57,20 @@ public class FCGI
public static FrameType from(int code)
{
- switch (code)
+ return switch (code)
{
- case 1:
- return BEGIN_REQUEST;
- case 2:
- return ABORT_REQUEST;
- case 3:
- return END_REQUEST;
- case 4:
- return PARAMS;
- case 5:
- return STDIN;
- case 6:
- return STDOUT;
- case 7:
- return STDERR;
- case 8:
- return DATA;
- case 9:
- return GET_VALUES;
- case 10:
- return GET_VALUES_RESULT;
- default:
- throw new IllegalArgumentException();
- }
+ case 1 -> BEGIN_REQUEST;
+ case 2 -> ABORT_REQUEST;
+ case 3 -> END_REQUEST;
+ case 4 -> PARAMS;
+ case 5 -> STDIN;
+ case 6 -> STDOUT;
+ case 7 -> STDERR;
+ case 8 -> DATA;
+ case 9 -> GET_VALUES;
+ case 10 -> GET_VALUES_RESULT;
+ default -> throw new IllegalArgumentException();
+ };
}
public final int code;
diff --git a/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpChannelOverFCGI.java b/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpChannelOverFCGI.java
index 99ab9f9067a..58c7b986fc0 100644
--- a/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpChannelOverFCGI.java
+++ b/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpChannelOverFCGI.java
@@ -11,403 +11,195 @@
// ========================================================================
//
-package org.eclipse.jetty.fcgi.server;
+package org.eclipse.jetty.fcgi.client.http;
-import java.util.Locale;
-import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicReference;
+import java.nio.ByteBuffer;
+import java.util.concurrent.TimeoutException;
-import org.eclipse.jetty.fcgi.FCGI;
-import org.eclipse.jetty.http.HostPortHttpField;
+import org.eclipse.jetty.client.HttpChannel;
+import org.eclipse.jetty.client.HttpExchange;
+import org.eclipse.jetty.client.HttpReceiver;
+import org.eclipse.jetty.client.HttpSender;
+import org.eclipse.jetty.client.api.Result;
+import org.eclipse.jetty.fcgi.generator.Flusher;
+import org.eclipse.jetty.fcgi.generator.Generator;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
-import org.eclipse.jetty.http.HttpHeader;
-import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpVersion;
-import org.eclipse.jetty.http.MetaData;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.HttpChannel;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.HttpInput;
-import org.eclipse.jetty.server.HttpTransport;
+import org.eclipse.jetty.io.IdleTimeout;
import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HttpChannelOverFCGI extends HttpChannel
{
private static final Logger LOG = LoggerFactory.getLogger(HttpChannelOverFCGI.class);
- private static final HttpInput.Content EOF_CONTENT = new HttpInput.EofContent();
- private final Callback asyncFillCallback = new AsyncFillCallback();
- private final ServerFCGIConnection connection;
- private final HttpFields.Mutable fields = HttpFields.build();
- private final Dispatcher dispatcher;
- private HttpInput.Content normalContent;
- private HttpInput.Content specialContent;
- private String method;
- private String path;
- private String query;
- private String version;
- private HostPortHttpField hostPort;
+ private final HttpConnectionOverFCGI connection;
+ private final Flusher flusher;
+ private final HttpSenderOverFCGI sender;
+ private final HttpReceiverOverFCGI receiver;
+ private final FCGIIdleTimeout idle;
+ private int request;
+ private HttpVersion version;
- public HttpChannelOverFCGI(ServerFCGIConnection connection, Connector connector, HttpConfiguration configuration, EndPoint endPoint, HttpTransport transport)
+ public HttpChannelOverFCGI(final HttpConnectionOverFCGI connection, Flusher flusher, long idleTimeout)
{
- super(connector, configuration, endPoint, transport);
+ super(connection.getHttpDestination());
this.connection = connection;
- this.dispatcher = new Dispatcher(connector.getServer().getThreadPool(), this);
+ this.flusher = flusher;
+ this.sender = new HttpSenderOverFCGI(this);
+ this.receiver = new HttpReceiverOverFCGI(this);
+ this.idle = new FCGIIdleTimeout(connection, idleTimeout);
+ }
+
+ protected int getRequest()
+ {
+ return request;
+ }
+
+ void setRequest(int request)
+ {
+ this.request = request;
}
@Override
- public boolean onContent(HttpInput.Content content)
+ protected HttpSender getHttpSender()
{
- boolean result = super.onContent(content);
-
- HttpInput.Content special = this.specialContent;
- Throwable failure = special == null ? null : special.getError();
- if (failure == null)
- {
- if (normalContent != null)
- throw new IllegalStateException("onContent has unconsumed content");
- normalContent = content;
- }
- else
- {
- content.failed(failure);
- }
-
- return result;
+ return sender;
}
@Override
- public boolean needContent()
+ protected HttpReceiver getHttpReceiver()
{
- if (hasContent())
- {
- if (LOG.isDebugEnabled())
- LOG.debug("needContent has immediate content {}", this);
- return true;
- }
+ return receiver;
+ }
- parseAndFill();
+ public boolean isFailed()
+ {
+ return sender.isFailed() || receiver.isFailed();
+ }
- if (hasContent())
- {
- if (LOG.isDebugEnabled())
- LOG.debug("needContent has parsed content {}", this);
- return true;
- }
+ void receive()
+ {
+ connection.process();
+ }
- connection.getEndPoint().tryFillInterested(asyncFillCallback);
+ @Override
+ public void send(HttpExchange exchange)
+ {
+ version = exchange.getRequest().getVersion();
+ idle.onOpen();
+ sender.send(exchange);
+ }
+
+ @Override
+ public void release()
+ {
+ connection.release(this);
+ }
+
+ protected boolean responseBegin(int code, String reason)
+ {
+ idle.notIdle();
+ HttpExchange exchange = getHttpExchange();
+ if (exchange == null)
+ return false;
+ exchange.getResponse().version(version).status(code).reason(reason);
+ return receiver.responseBegin(exchange);
+ }
+
+ protected boolean responseHeader(HttpField field)
+ {
+ HttpExchange exchange = getHttpExchange();
+ return exchange != null && receiver.responseHeader(exchange, field);
+ }
+
+ protected boolean responseHeaders()
+ {
+ idle.notIdle();
+ HttpExchange exchange = getHttpExchange();
+ return exchange != null && receiver.responseHeaders(exchange);
+ }
+
+ protected boolean content(ByteBuffer buffer, Callback callback)
+ {
+ idle.notIdle();
+ HttpExchange exchange = getHttpExchange();
+ if (exchange != null)
+ return receiver.responseContent(exchange, buffer, callback);
+ callback.succeeded();
return false;
}
- private boolean hasContent()
+ protected boolean responseSuccess()
{
- return specialContent != null || normalContent != null;
+ HttpExchange exchange = getHttpExchange();
+ return exchange != null && receiver.responseSuccess(exchange);
+ }
+
+ protected boolean responseFailure(Throwable failure)
+ {
+ HttpExchange exchange = getHttpExchange();
+ return exchange != null && receiver.responseFailure(failure);
}
@Override
- public HttpInput.Content produceContent()
+ public void exchangeTerminated(HttpExchange exchange, Result result)
{
- if (!hasContent())
- parseAndFill();
+ super.exchangeTerminated(exchange, result);
+ idle.onClose();
+ HttpFields responseHeaders = result.getResponse().getHeaders();
+ if (result.isFailed())
+ connection.close(result.getFailure());
+ else if (!connection.closeByHTTP(responseHeaders))
+ release();
+ }
- if (!hasContent())
- return null;
+ protected void flush(Generator.Result... results)
+ {
+ flusher.flush(results);
+ }
- HttpInput.Content content = normalContent;
- if (content != null)
+ private class FCGIIdleTimeout extends IdleTimeout
+ {
+ private final HttpConnectionOverFCGI connection;
+ private boolean open;
+
+ public FCGIIdleTimeout(HttpConnectionOverFCGI connection, long idleTimeout)
+ {
+ super(connection.getHttpDestination().getHttpClient().getScheduler());
+ this.connection = connection;
+ setIdleTimeout(idleTimeout >= 0 ? idleTimeout : connection.getEndPoint().getIdleTimeout());
+ }
+
+ @Override
+ public void onOpen()
+ {
+ open = true;
+ notIdle();
+ super.onOpen();
+ }
+
+ @Override
+ public void onClose()
+ {
+ super.onClose();
+ open = false;
+ }
+
+ @Override
+ protected void onIdleExpired(TimeoutException timeout)
{
if (LOG.isDebugEnabled())
- LOG.debug("produceContent produced {} {}", content, this);
- normalContent = null;
- return content;
- }
- content = specialContent;
- if (LOG.isDebugEnabled())
- LOG.debug("produceContent produced special {} {}", content, this);
- return content;
- }
-
- private void parseAndFill()
- {
- if (LOG.isDebugEnabled())
- LOG.debug("parseAndFill {}", this);
- connection.parseAndFill();
- }
-
- @Override
- public boolean failAllContent(Throwable failure)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("failing all content {}", this);
- HttpInput.Content normal = normalContent;
- if (normal != null)
- normal.failed(failure);
- HttpInput.Content special = specialContent;
- if (special != null)
- return special.isEof();
- while (true)
- {
- HttpInput.Content content = produceContent();
- if (content == null)
- return false;
- special = specialContent;
- if (special != null)
- return special.isEof();
- content.failed(failure);
- }
- }
-
- @Override
- public boolean failed(Throwable x)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("failed {}", this, x);
-
- HttpInput.Content special = specialContent;
- Throwable error = special == null ? null : special.getError();
- if (error != null && error != x)
- error.addSuppressed(x);
- else
- specialContent = new HttpInput.ErrorContent(x);
-
- return getRequest().getHttpInput().onContentProducible();
- }
-
- @Override
- protected boolean eof()
- {
- if (LOG.isDebugEnabled())
- LOG.debug("received EOF");
- specialContent = EOF_CONTENT;
- return getRequest().getHttpInput().onContentProducible();
- }
-
- protected void header(HttpField field)
- {
- String name = field.getName();
- String value = field.getValue();
- getRequest().setAttribute(name, value);
- if (FCGI.Headers.REQUEST_METHOD.equalsIgnoreCase(name))
- method = value;
- else if (FCGI.Headers.DOCUMENT_URI.equalsIgnoreCase(name))
- path = value;
- else if (FCGI.Headers.QUERY_STRING.equalsIgnoreCase(name))
- query = value;
- else if (FCGI.Headers.SERVER_PROTOCOL.equalsIgnoreCase(name))
- version = value;
- else
- processField(field);
- }
-
- private void processField(HttpField field)
- {
- HttpField httpField = convertHeader(field);
- if (httpField != null)
- {
- fields.add(httpField);
- if (HttpHeader.HOST.is(httpField.getName()))
- hostPort = (HostPortHttpField)httpField;
- }
- }
-
- public void onRequest()
- {
- String uri = path;
- if (!StringUtil.isEmpty(query))
- uri += "?" + query;
- // TODO https?
- onRequest(new MetaData.Request(method, HttpScheme.HTTP.asString(), hostPort, uri, HttpVersion.fromString(version), fields, Long.MIN_VALUE));
- }
-
- private HttpField convertHeader(HttpField field)
- {
- String name = field.getName();
- if (name.startsWith("HTTP_"))
- {
- // Converts e.g. "HTTP_ACCEPT_ENCODING" to "Accept-Encoding"
- String[] parts = name.split("_");
- StringBuilder httpName = new StringBuilder();
- for (int i = 1; i < parts.length; ++i)
- {
- if (i > 1)
- httpName.append("-");
- String part = parts[i];
- httpName.append(Character.toUpperCase(part.charAt(0)));
- httpName.append(part.substring(1).toLowerCase(Locale.ENGLISH));
- }
- String headerName = httpName.toString();
- String value = field.getValue();
- if (HttpHeader.HOST.is(headerName))
- return new HostPortHttpField(value);
- else
- return new HttpField(headerName, value);
- }
- return null;
- }
-
- protected void dispatch()
- {
- dispatcher.dispatch();
- }
-
- public boolean onIdleTimeout(Throwable timeout)
- {
- boolean handle = doOnIdleTimeout(timeout);
- if (handle)
- execute(this);
- return !handle;
- }
-
- private boolean doOnIdleTimeout(Throwable x)
- {
- boolean neverDispatched = getState().isIdle();
- HttpInput.Content normal = this.normalContent;
- boolean waitingForContent = normal == null || normal.remaining() == 0;
- if ((waitingForContent || neverDispatched) && specialContent == null)
- {
- x.addSuppressed(new Throwable("HttpInput idle timeout"));
- specialContent = new HttpInput.ErrorContent(x);
- return getRequest().getHttpInput().onContentProducible();
- }
- return false;
- }
-
- @Override
- public void recycle()
- {
- super.recycle();
- HttpInput.Content normal = normalContent;
- if (normal != null)
- throw new AssertionError("unconsumed content: " + normal);
- specialContent = null;
- }
-
- @Override
- public void onCompleted()
- {
- super.onCompleted();
- HttpInput input = getRequest().getHttpInput();
- boolean consumed = input.consumeAll();
- // Assume we don't arrive here from the connection's onFillable() (which already
- // calls fillInterested()), because we dispatch() when all the headers are received.
- // When the request/response is completed, we must arrange to call fillInterested().
- connection.onCompleted(consumed);
- }
-
- private class AsyncFillCallback implements Callback
- {
- @Override
- public void succeeded()
- {
- if (getRequest().getHttpInput().onContentProducible())
- handle();
+ LOG.debug("Idle timeout for request {}", request);
+ connection.abort(timeout);
}
@Override
- public void failed(Throwable x)
+ public boolean isOpen()
{
- if (HttpChannelOverFCGI.this.failed(x))
- handle();
- }
-
- @Override
- public InvocationType getInvocationType()
- {
- return InvocationType.NON_BLOCKING;
- }
- }
-
- private static class Dispatcher implements Runnable
- {
- private final AtomicReference state = new AtomicReference<>(State.IDLE);
- private final Executor executor;
- private final Runnable runnable;
-
- private Dispatcher(Executor executor, Runnable runnable)
- {
- this.executor = executor;
- this.runnable = runnable;
- }
-
- public void dispatch()
- {
- while (true)
- {
- State current = state.get();
- if (LOG.isDebugEnabled())
- LOG.debug("Dispatching, state={}", current);
- switch (current)
- {
- case IDLE:
- {
- if (!state.compareAndSet(current, State.DISPATCH))
- continue;
- executor.execute(this);
- return;
- }
- case DISPATCH:
- case EXECUTE:
- {
- if (state.compareAndSet(current, State.SCHEDULE))
- return;
- continue;
- }
- case SCHEDULE:
- {
- return;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
- }
-
- @Override
- public void run()
- {
- while (true)
- {
- State current = state.get();
- if (LOG.isDebugEnabled())
- LOG.debug("Running, state={}", current);
- switch (current)
- {
- case DISPATCH:
- {
- if (state.compareAndSet(current, State.EXECUTE))
- runnable.run();
- continue;
- }
- case EXECUTE:
- {
- if (state.compareAndSet(current, State.IDLE))
- return;
- continue;
- }
- case SCHEDULE:
- {
- if (state.compareAndSet(current, State.DISPATCH))
- continue;
- throw new IllegalStateException();
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
- }
-
- private enum State
- {
- IDLE, DISPATCH, EXECUTE, SCHEDULE
+ return open;
}
}
}
diff --git a/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpClientTransportOverFCGI.java b/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpClientTransportOverFCGI.java
index e460a288664..598c532c932 100644
--- a/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpClientTransportOverFCGI.java
+++ b/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpClientTransportOverFCGI.java
@@ -13,7 +13,6 @@
package org.eclipse.jetty.fcgi.client.http;
-import java.io.IOException;
import java.util.List;
import java.util.Map;
@@ -86,7 +85,7 @@ public class HttpClientTransportOverFCGI extends AbstractConnectorHttpClientTran
}
@Override
- public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map context) throws IOException
+ public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map context)
{
HttpDestination destination = (HttpDestination)context.get(HTTP_DESTINATION_CONTEXT_KEY);
@SuppressWarnings("unchecked")
@@ -97,12 +96,12 @@ public class HttpClientTransportOverFCGI extends AbstractConnectorHttpClientTran
return customize(connection, context);
}
- protected HttpConnectionOverFCGI newHttpConnection(EndPoint endPoint, HttpDestination destination, Promise promise)
+ protected org.eclipse.jetty.io.Connection newHttpConnection(EndPoint endPoint, HttpDestination destination, Promise promise)
{
return new HttpConnectionOverFCGI(endPoint, destination, promise);
}
- protected void customize(Request request, HttpFields.Mutable fastCGIHeaders)
+ public void customize(Request request, HttpFields.Mutable fastCGIHeaders)
{
fastCGIHeaders.put(FCGI.Headers.DOCUMENT_ROOT, getScriptRoot());
}
diff --git a/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java b/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java
index 796483ef5ff..8dd042ff329 100644
--- a/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java
+++ b/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java
@@ -317,7 +317,7 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements IConne
private int acquireRequest()
{
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
int last = requests.getLast();
int request = last + 1;
@@ -328,7 +328,7 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements IConne
private void releaseRequest(int request)
{
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
requests.removeFirstOccurrence(request);
}
@@ -445,7 +445,7 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements IConne
{
switch (stream)
{
- case STD_OUT:
+ case STD_OUT ->
{
HttpChannelOverFCGI channel = HttpConnectionOverFCGI.this.channel;
if (channel != null)
@@ -457,17 +457,9 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements IConne
{
noChannel(request);
}
- break;
- }
- case STD_ERR:
- {
- LOG.info(BufferUtil.toUTF8String(buffer));
- break;
- }
- default:
- {
- throw new IllegalArgumentException();
}
+ case STD_ERR -> LOG.info(BufferUtil.toUTF8String(buffer));
+ default -> throw new IllegalArgumentException();
}
return false;
}
diff --git a/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Flusher.java b/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Flusher.java
index d88e8f2a17e..49b2865f3a3 100644
--- a/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Flusher.java
+++ b/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Flusher.java
@@ -48,7 +48,7 @@ public class Flusher
private void offer(Generator.Result result)
{
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
queue.offer(result);
}
@@ -56,7 +56,7 @@ public class Flusher
private Generator.Result poll()
{
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
return queue.poll();
}
diff --git a/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Generator.java b/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Generator.java
index 1cae12e42c3..72e5ae2d513 100644
--- a/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Generator.java
+++ b/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Generator.java
@@ -121,7 +121,7 @@ public class Generator
public ByteBuffer[] getByteBuffers()
{
- return buffers.toArray(new ByteBuffer[buffers.size()]);
+ return buffers.toArray(new ByteBuffer[0]);
}
@Override
diff --git a/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ClientParser.java b/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ClientParser.java
index 20102ff096d..999ce4161c8 100644
--- a/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ClientParser.java
+++ b/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ClientParser.java
@@ -51,16 +51,8 @@ public class ClientParser extends Parser
}
}
- private class EndRequestListener implements Listener
+ private record EndRequestListener(Listener listener, StreamContentParser... streamParsers) implements Listener
{
- private final Listener listener;
- private final StreamContentParser[] streamParsers;
-
- private EndRequestListener(Listener listener, StreamContentParser... streamParsers)
- {
- this.listener = listener;
- this.streamParsers = streamParsers;
- }
@Override
public void onBegin(int request, int code, String reason)
diff --git a/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ResponseContentParser.java b/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ResponseContentParser.java
index 309d0c0836b..bce8007aaa9 100644
--- a/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ResponseContentParser.java
+++ b/jetty-core/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ResponseContentParser.java
@@ -82,7 +82,7 @@ public class ResponseContentParser extends StreamContentParser
private static class ResponseParser implements HttpParser.ResponseHandler
{
private final HttpFields.Mutable fields = HttpFields.build();
- private ClientParser.Listener listener;
+ private final ClientParser.Listener listener;
private final int request;
private final FCGIHttpParser httpParser;
private State state = State.HEADERS;
diff --git a/jetty-fcgi/fcgi-client/src/test/resources/jetty-logging.properties b/jetty-core/jetty-fcgi/fcgi-client/src/test/resources/jetty-logging.properties
similarity index 100%
rename from jetty-fcgi/fcgi-client/src/test/resources/jetty-logging.properties
rename to jetty-core/jetty-fcgi/fcgi-client/src/test/resources/jetty-logging.properties
diff --git a/jetty-core/jetty-fcgi/fcgi-server/pom.xml b/jetty-core/jetty-fcgi/fcgi-server/pom.xml
index d6421e28f13..a512fccb5f1 100644
--- a/jetty-core/jetty-fcgi/fcgi-server/pom.xml
+++ b/jetty-core/jetty-fcgi/fcgi-server/pom.xml
@@ -2,13 +2,13 @@
org.eclipse.jetty.fcgi
- fcgi-parent
- 11.0.10-SNAPSHOT
+ fcgi
+ 12.0.0-SNAPSHOT4.0.0fcgi-server
- Jetty :: FastCGI :: Server
+ Jetty Core :: FastCGI :: Server${project.groupId}.server
@@ -19,34 +19,24 @@
org.slf4jslf4j-api
-
+
org.eclipse.jetty.fcgifcgi-client
-
- org.eclipse.jetty
- jetty-proxy
- org.eclipse.jettyjetty-server
-
org.eclipse.jettyjetty-slf4j-impltest
-
- org.eclipse.jetty
- jetty-servlet
- test
- org.eclipse.jetty.http2http2-server
@@ -57,11 +47,6 @@
jetty-alpn-java-servertest
-
- org.eclipse.jetty
- jetty-annotations
- test
- org.eclipse.jettyjetty-unixdomain-server
diff --git a/jetty-fcgi/fcgi-server/src/main/java/module-info.java b/jetty-core/jetty-fcgi/fcgi-server/src/main/java/module-info.java
similarity index 79%
rename from jetty-fcgi/fcgi-server/src/main/java/module-info.java
rename to jetty-core/jetty-fcgi/fcgi-server/src/main/java/module-info.java
index f9ea05c49d0..65813325e51 100644
--- a/jetty-fcgi/fcgi-server/src/main/java/module-info.java
+++ b/jetty-core/jetty-fcgi/fcgi-server/src/main/java/module-info.java
@@ -16,11 +16,7 @@ module org.eclipse.jetty.fcgi.server
requires org.slf4j;
requires transitive org.eclipse.jetty.fcgi.client;
- requires transitive org.eclipse.jetty.proxy;
-
- // Only required if using the proxy features.
- requires static jetty.servlet.api;
+ requires transitive org.eclipse.jetty.server;
exports org.eclipse.jetty.fcgi.server;
- exports org.eclipse.jetty.fcgi.server.proxy;
}
diff --git a/jetty-core/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnectionFactory.java b/jetty-core/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnectionFactory.java
index b15004d6177..3e9ff77d31c 100644
--- a/jetty-core/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnectionFactory.java
+++ b/jetty-core/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnectionFactory.java
@@ -13,6 +13,7 @@
package org.eclipse.jetty.fcgi.server;
+import org.eclipse.jetty.fcgi.server.internal.ServerFCGIConnection;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.server.AbstractConnectionFactory;
diff --git a/jetty-core/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/HttpStreamOverFCGI.java b/jetty-core/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/HttpStreamOverFCGI.java
new file mode 100644
index 00000000000..a448b6839d7
--- /dev/null
+++ b/jetty-core/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/HttpStreamOverFCGI.java
@@ -0,0 +1,379 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.fcgi.server.internal;
+
+import java.nio.ByteBuffer;
+import java.util.Locale;
+
+import org.eclipse.jetty.fcgi.FCGI;
+import org.eclipse.jetty.fcgi.generator.Flusher;
+import org.eclipse.jetty.fcgi.generator.Generator;
+import org.eclipse.jetty.fcgi.generator.ServerGenerator;
+import org.eclipse.jetty.http.HostPortHttpField;
+import org.eclipse.jetty.http.HttpField;
+import org.eclipse.jetty.http.HttpFields;
+import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.http.HttpHeaderValue;
+import org.eclipse.jetty.http.HttpMethod;
+import org.eclipse.jetty.http.HttpScheme;
+import org.eclipse.jetty.http.HttpVersion;
+import org.eclipse.jetty.http.MetaData;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.server.Content;
+import org.eclipse.jetty.server.HttpChannel;
+import org.eclipse.jetty.server.HttpStream;
+import org.eclipse.jetty.util.BufferUtil;
+import org.eclipse.jetty.util.Callback;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.thread.Invocable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HttpStreamOverFCGI implements HttpStream
+{
+ private static final Logger LOG = LoggerFactory.getLogger(HttpStreamOverFCGI.class);
+
+ private final Callback _demandCallback = new DemandCallback();
+ private final HttpFields.Mutable _headers = HttpFields.build();
+ private final ServerFCGIConnection _connection;
+ private final ServerGenerator _generator;
+ private final HttpChannel _httpChannel;
+ private final int _id;
+ private final long _nanoTime;
+ private String _method;
+ private HostPortHttpField hostPort;
+ private String _path;
+ private String _query;
+ private String _version;
+ private Content _content;
+ private boolean _committed;
+ private boolean _shutdown;
+ private boolean _aborted;
+
+ public HttpStreamOverFCGI(ServerFCGIConnection connection, ServerGenerator generator, HttpChannel httpChannel, int id)
+ {
+ _connection = connection;
+ _generator = generator;
+ _httpChannel = httpChannel;
+ _id = id;
+ _nanoTime = System.nanoTime();
+ }
+
+ public HttpChannel getHttpChannel()
+ {
+ return _httpChannel;
+ }
+
+ @Override
+ public String getId()
+ {
+ return String.valueOf(_id);
+ }
+
+ @Override
+ public long getNanoTimeStamp()
+ {
+ return _nanoTime;
+ }
+
+ public void onHeader(HttpField field)
+ {
+ String name = field.getName();
+ String value = field.getValue();
+ if (FCGI.Headers.REQUEST_METHOD.equalsIgnoreCase(name))
+ _method = value;
+ else if (FCGI.Headers.DOCUMENT_URI.equalsIgnoreCase(name))
+ _path = value;
+ else if (FCGI.Headers.QUERY_STRING.equalsIgnoreCase(name))
+ _query = value;
+ else if (FCGI.Headers.SERVER_PROTOCOL.equalsIgnoreCase(name))
+ _version = value;
+ else
+ processField(field);
+ }
+
+ public void onHeaders()
+ {
+ String pathQuery = URIUtil.addPathQuery(_path, _query);
+ // TODO https?
+ MetaData.Request request = new MetaData.Request(_method, HttpScheme.HTTP.asString(), hostPort, pathQuery, HttpVersion.fromString(_version), _headers, Long.MIN_VALUE);
+ Runnable task = _httpChannel.onRequest(request);
+ _headers.forEach(field -> _httpChannel.getRequest().setAttribute(field.getName(), field.getValue()));
+ // TODO: here we just execute the task.
+ // However, we should really return all the way back to onFillable()
+ // and feed the Runnable to an ExecutionStrategy.
+ execute(task);
+ }
+
+ private void processField(HttpField field)
+ {
+ HttpField httpField = convertHeader(field);
+ if (httpField != null)
+ {
+ _headers.add(httpField);
+ if (HttpHeader.HOST.is(httpField.getName()))
+ hostPort = (HostPortHttpField)httpField;
+ }
+ }
+
+ private HttpField convertHeader(HttpField field)
+ {
+ String name = field.getName();
+ if (name.startsWith("HTTP_"))
+ {
+ // Converts e.g. "HTTP_ACCEPT_ENCODING" to "Accept-Encoding"
+ String[] parts = name.split("_");
+ StringBuilder httpName = new StringBuilder();
+ for (int i = 1; i < parts.length; ++i)
+ {
+ if (i > 1)
+ httpName.append("-");
+ String part = parts[i];
+ httpName.append(Character.toUpperCase(part.charAt(0)));
+ httpName.append(part.substring(1).toLowerCase(Locale.ENGLISH));
+ }
+ String headerName = httpName.toString();
+ String value = field.getValue();
+ if (HttpHeader.HOST.is(headerName))
+ return new HostPortHttpField(value);
+ else
+ return new HttpField(headerName, value);
+ }
+ return null;
+ }
+
+ @Override
+ public Content readContent()
+ {
+ if (_content == null)
+ _connection.parseAndFill();
+ Content content = _content;
+ _content = Content.next(content);
+ return content;
+ }
+
+ @Override
+ public void demandContent()
+ {
+ if (_content != null)
+ return;
+
+ _connection.parseAndFill();
+
+ if (_content != null)
+ {
+ notifyContentAvailable();
+ return;
+ }
+
+ _connection.tryFillInterested(_demandCallback);
+ }
+
+ private void notifyContentAvailable()
+ {
+ Runnable onContentAvailable = _httpChannel.onContentAvailable();
+ if (onContentAvailable != null)
+ onContentAvailable.run();
+ }
+
+ public void onContent(Content content)
+ {
+ _content = content;
+ }
+
+ public void onComplete()
+ {
+ _content = Content.last(_content);
+ }
+
+ @Override
+ public void prepareResponse(HttpFields.Mutable headers)
+ {
+ // Nothing to do for FastCGI.
+ }
+
+ @Override
+ public void send(MetaData.Request request, MetaData.Response response, boolean last, Callback callback, ByteBuffer... buffers)
+ {
+ if (buffers.length > 1)
+ throw new IllegalStateException();
+ ByteBuffer content = buffers.length == 0 ? BufferUtil.EMPTY_BUFFER : buffers[0];
+
+ if (LOG.isDebugEnabled())
+ LOG.debug("send {} {} l={}", this, request, last);
+ boolean head = HttpMethod.HEAD.is(request.getMethod());
+ if (response != null)
+ {
+ commit(response, head, last, content, callback);
+ }
+ else
+ {
+ Flusher flusher = _connection.getFlusher();
+ if (head)
+ {
+ if (last)
+ {
+ Generator.Result result = generateResponseContent(true, BufferUtil.EMPTY_BUFFER, callback);
+ flusher.flush(result);
+ }
+ else
+ {
+ // Skip content generation
+ callback.succeeded();
+ }
+ }
+ else
+ {
+ Generator.Result result = generateResponseContent(last, content, callback);
+ flusher.flush(result);
+ }
+
+ if (last && _shutdown)
+ flusher.shutdown();
+ }
+ }
+
+ private void commit(MetaData.Response info, boolean head, boolean last, ByteBuffer content, Callback callback)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("commit {} {} l={}", this, info, last);
+
+ _committed = true;
+
+ boolean shutdown = _shutdown = info.getFields().contains(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString());
+
+ Flusher flusher = _connection.getFlusher();
+ if (head)
+ {
+ if (last)
+ {
+ Generator.Result headersResult = generateResponseHeaders(info, Callback.NOOP);
+ Generator.Result contentResult = generateResponseContent(true, BufferUtil.EMPTY_BUFFER, callback);
+ flusher.flush(headersResult, contentResult);
+ }
+ else
+ {
+ Generator.Result headersResult = generateResponseHeaders(info, callback);
+ flusher.flush(headersResult);
+ }
+ }
+ else
+ {
+ Generator.Result headersResult = generateResponseHeaders(info, Callback.NOOP);
+ Generator.Result contentResult = generateResponseContent(last, content, callback);
+ flusher.flush(headersResult, contentResult);
+ }
+
+ if (last && shutdown)
+ flusher.shutdown();
+ }
+
+ private Generator.Result generateResponseHeaders(MetaData.Response info, Callback callback)
+ {
+ return _generator.generateResponseHeaders(_id, info.getStatus(), info.getReason(), info.getFields(), callback);
+ }
+
+ private Generator.Result generateResponseContent(boolean last, ByteBuffer buffer, Callback callback)
+ {
+ return _generator.generateResponseContent(_id, buffer, last, _aborted, callback);
+ }
+
+ @Override
+ public boolean isPushSupported()
+ {
+ return false;
+ }
+
+ @Override
+ public void push(MetaData.Request request)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isCommitted()
+ {
+ return _committed;
+ }
+
+ @Override
+ public void succeeded()
+ {
+ _httpChannel.recycle();
+ _connection.onCompleted(null);
+ }
+
+ @Override
+ public void failed(Throwable x)
+ {
+ // TODO: should we do more?
+ _aborted = true;
+ _connection.onCompleted(x);
+ }
+
+ @Override
+ public boolean isComplete()
+ {
+ // TODO
+ return false;
+ }
+
+ @Override
+ public void setUpgradeConnection(Connection connection)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Connection upgrade()
+ {
+ return null;
+ }
+
+ public boolean onIdleTimeout(Throwable timeout)
+ {
+ Runnable task = _httpChannel.onFailure(timeout);
+ if (task != null)
+ execute(task);
+ return false;
+ }
+
+ private void execute(Runnable task)
+ {
+ _connection.getConnector().getExecutor().execute(task);
+ }
+
+ private class DemandCallback implements Callback
+ {
+ @Override
+ public void succeeded()
+ {
+ notifyContentAvailable();
+ }
+
+ @Override
+ public void failed(Throwable x)
+ {
+ Runnable task = _httpChannel.onFailure(x);
+ if (task != null)
+ _connection.getConnector().getExecutor().execute(task);
+ }
+
+ @Override
+ public InvocationType getInvocationType()
+ {
+ return Invocable.getInvocationType(_httpChannel);
+ }
+ }
+}
diff --git a/jetty-core/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java b/jetty-core/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java
index 8c31d1e0a52..8fb6263e2e6 100644
--- a/jetty-core/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java
+++ b/jetty-core/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java
@@ -11,40 +11,53 @@
// ========================================================================
//
-package org.eclipse.jetty.fcgi.server;
+package org.eclipse.jetty.fcgi.server.internal;
+import java.net.SocketAddress;
import java.nio.ByteBuffer;
+import java.util.Set;
import org.eclipse.jetty.fcgi.FCGI;
import org.eclipse.jetty.fcgi.generator.Flusher;
+import org.eclipse.jetty.fcgi.generator.ServerGenerator;
import org.eclipse.jetty.fcgi.parser.ServerParser;
import org.eclipse.jetty.http.BadMessageException;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.io.AbstractConnection;
+import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.RetainableByteBuffer;
import org.eclipse.jetty.io.RetainableByteBufferPool;
+import org.eclipse.jetty.server.ConnectionMetaData;
import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Content;
+import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.HttpInput;
+import org.eclipse.jetty.util.Attributes;
+import org.eclipse.jetty.util.HostPort;
+import org.eclipse.jetty.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class ServerFCGIConnection extends AbstractConnection
+public class ServerFCGIConnection extends AbstractConnection implements ConnectionMetaData
{
private static final Logger LOG = LoggerFactory.getLogger(ServerFCGIConnection.class);
+ private final HttpChannel.Factory httpChannelFactory = new HttpChannel.DefaultFactory();
+ private final Attributes attributes = new Lazy();
private final Connector connector;
private final RetainableByteBufferPool networkByteBufferPool;
private final boolean sendStatus200;
private final Flusher flusher;
private final HttpConfiguration configuration;
private final ServerParser parser;
+ private final String id;
private boolean useInputDirectByteBuffers;
private boolean useOutputDirectByteBuffers;
private RetainableByteBuffer networkBuffer;
- private HttpChannelOverFCGI channel;
+ private HttpStreamOverFCGI stream;
public ServerFCGIConnection(Connector connector, EndPoint endPoint, HttpConfiguration configuration, boolean sendStatus200)
{
@@ -55,6 +68,12 @@ public class ServerFCGIConnection extends AbstractConnection
this.configuration = configuration;
this.sendStatus200 = sendStatus200;
this.parser = new ServerParser(new ServerListener());
+ this.id = StringUtil.randomAlphaNumeric(16);
+ }
+
+ Flusher getFlusher()
+ {
+ return flusher;
}
public boolean isUseInputDirectByteBuffers()
@@ -77,6 +96,102 @@ public class ServerFCGIConnection extends AbstractConnection
this.useOutputDirectByteBuffers = useOutputDirectByteBuffers;
}
+ @Override
+ public String getId()
+ {
+ return id;
+ }
+
+ @Override
+ public HttpConfiguration getHttpConfiguration()
+ {
+ return configuration;
+ }
+
+ @Override
+ public HttpVersion getHttpVersion()
+ {
+ return HttpVersion.HTTP_1_1;
+ }
+
+ @Override
+ public String getProtocol()
+ {
+ return "fcgi/1.0";
+ }
+
+ @Override
+ public Connection getConnection()
+ {
+ return this;
+ }
+
+ @Override
+ public Connector getConnector()
+ {
+ return connector;
+ }
+
+ @Override
+ public boolean isPersistent()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean isSecure()
+ {
+ return false;
+ }
+
+ @Override
+ public SocketAddress getRemoteSocketAddress()
+ {
+ return getEndPoint().getRemoteSocketAddress();
+ }
+
+ @Override
+ public SocketAddress getLocalSocketAddress()
+ {
+ return getEndPoint().getLocalSocketAddress();
+ }
+
+ @Override
+ public HostPort getServerAuthority()
+ {
+ return ConnectionMetaData.getServerAuthority(configuration, this);
+ }
+
+ @Override
+ public Object removeAttribute(String name)
+ {
+ return attributes.removeAttribute(name);
+ }
+
+ @Override
+ public Object setAttribute(String name, Object attribute)
+ {
+ return attributes.setAttribute(name, attribute);
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ return attributes.getAttribute(name);
+ }
+
+ @Override
+ public Set getAttributeNameSet()
+ {
+ return attributes.getAttributeNameSet();
+ }
+
+ @Override
+ public void clearAttributes()
+ {
+ attributes.clearAttributes();
+ }
+
@Override
public void onOpen()
{
@@ -135,12 +250,12 @@ public class ServerFCGIConnection extends AbstractConnection
LOG.debug("parseAndFill {}", this);
// This loop must run only until the request is completed.
// See also HttpConnection.parseAndFillForContent().
- while (channel != null)
+ while (stream != null)
{
if (parse(networkBuffer.getBuffer()))
return;
// Check if the request was completed by the parsing.
- if (channel == null)
+ if (stream == null)
return;
if (fillInputBuffer() <= 0)
break;
@@ -179,8 +294,8 @@ public class ServerFCGIConnection extends AbstractConnection
@Override
protected boolean onReadTimeout(Throwable timeout)
{
- if (channel != null)
- return channel.onIdleTimeout(timeout);
+ if (stream != null)
+ return stream.onIdleTimeout(timeout);
return true;
}
@@ -200,11 +315,13 @@ public class ServerFCGIConnection extends AbstractConnection
flusher.shutdown();
}
- void onCompleted(boolean fillMore)
+ void onCompleted(Throwable failure)
{
releaseInputBuffer();
- if (getEndPoint().isOpen() && fillMore)
+ if (failure == null)
fillInterested();
+ else
+ getFlusher().shutdown();
}
private class ServerListener implements ServerParser.Listener
@@ -213,10 +330,12 @@ public class ServerFCGIConnection extends AbstractConnection
public void onStart(int request, FCGI.Role role, int flags)
{
// TODO: handle flags
- if (channel != null)
+ if (stream != null)
throw new UnsupportedOperationException("FastCGI Multiplexing");
- channel = new HttpChannelOverFCGI(ServerFCGIConnection.this, connector, configuration, getEndPoint(),
- new HttpTransportOverFCGI(connector.getByteBufferPool(), isUseOutputDirectByteBuffers(), sendStatus200, flusher, request));
+ HttpChannel channel = httpChannelFactory.newHttpChannel(ServerFCGIConnection.this);
+ ServerGenerator generator = new ServerGenerator(connector.getByteBufferPool(), isUseOutputDirectByteBuffers(), sendStatus200);
+ stream = new HttpStreamOverFCGI(ServerFCGIConnection.this, generator, channel, request);
+ channel.setHttpStream(stream);
if (LOG.isDebugEnabled())
LOG.debug("Request {} start on {}", request, channel);
}
@@ -225,34 +344,34 @@ public class ServerFCGIConnection extends AbstractConnection
public void onHeader(int request, HttpField field)
{
if (LOG.isDebugEnabled())
- LOG.debug("Request {} header {} on {}", request, field, channel);
- if (channel != null)
- channel.header(field);
+ LOG.debug("Request {} header {} on {}", request, field, stream);
+ if (stream != null)
+ stream.onHeader(field);
}
@Override
public boolean onHeaders(int request)
{
if (LOG.isDebugEnabled())
- LOG.debug("Request {} headers on {}", request, channel);
- if (channel != null)
+ LOG.debug("Request {} headers on {}", request, stream);
+ if (stream != null)
{
- channel.onRequest();
- channel.dispatch();
- // We have dispatched to the application, so we must stop the fill & parse loop.
+ stream.onHeaders();
+ // We have dispatched to the application,
+ // so we must stop the fill & parse loop.
return true;
}
return false;
}
@Override
- public boolean onContent(int request, FCGI.StreamType stream, ByteBuffer buffer)
+ public boolean onContent(int request, FCGI.StreamType streamType, ByteBuffer buffer)
{
if (LOG.isDebugEnabled())
- LOG.debug("Request {} {} content {} on {}", request, stream, buffer, channel);
- if (channel != null)
+ LOG.debug("Request {} {} content {} on {}", request, streamType, buffer, stream);
+ if (stream != null)
{
- channel.onContent(new FastCGIContent(buffer));
+ stream.onContent(new FastCGIContent(buffer, false));
// Signal that the content is processed asynchronously, to ensure backpressure.
return true;
}
@@ -263,14 +382,13 @@ public class ServerFCGIConnection extends AbstractConnection
public void onEnd(int request)
{
if (LOG.isDebugEnabled())
- LOG.debug("Request {} end on {}", request, channel);
- if (channel != null)
+ LOG.debug("Request {} end on {}", request, stream);
+ if (stream != null)
{
- channel.onContentComplete();
- channel.onRequestComplete();
- // Nulling out the channel signals that the
+ stream.onComplete();
+ // Nulling out the stream signals that the
// request is complete, see also parseAndFill().
- channel = null;
+ stream = null;
}
}
@@ -278,33 +396,31 @@ public class ServerFCGIConnection extends AbstractConnection
public void onFailure(int request, Throwable failure)
{
if (LOG.isDebugEnabled())
- LOG.debug("Request {} failure on {}: {}", request, channel, failure);
- if (channel != null)
- channel.onBadMessage(new BadMessageException(HttpStatus.BAD_REQUEST_400, null, failure));
- channel = null;
+ LOG.debug("Request {} failure on {}: {}", request, stream, failure);
+ if (stream != null)
+ stream.getHttpChannel().onFailure(new BadMessageException(HttpStatus.BAD_REQUEST_400, null, failure));
+ stream = null;
}
- private class FastCGIContent extends HttpInput.Content
+ private class FastCGIContent extends Content.Abstract
{
- public FastCGIContent(ByteBuffer content)
+ private final ByteBuffer content;
+
+ public FastCGIContent(ByteBuffer content, boolean last)
{
- super(content);
+ super(false, last);
+ this.content = content;
networkBuffer.retain();
}
@Override
- public void succeeded()
+ public ByteBuffer getByteBuffer()
{
- release();
+ return content;
}
@Override
- public void failed(Throwable x)
- {
- release();
- }
-
- private void release()
+ public void release()
{
networkBuffer.release();
}
diff --git a/jetty-core/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/AbstractHttpClientServerTest.java b/jetty-core/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/AbstractHttpClientServerTest.java
index 095ffa2d9d6..82089f5d262 100644
--- a/jetty-core/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/AbstractHttpClientServerTest.java
+++ b/jetty-core/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/AbstractHttpClientServerTest.java
@@ -94,9 +94,8 @@ public abstract class AbstractHttpClientServerTest
assertThat("Server BufferPool - unreleased", serverBufferPool.getLeakedResources(), Matchers.is(0L));
}
- if ((clientBufferPool != null) && (clientBufferPool instanceof LeakTrackingByteBufferPool))
+ if ((clientBufferPool != null) && (clientBufferPool instanceof LeakTrackingByteBufferPool pool))
{
- LeakTrackingByteBufferPool pool = (LeakTrackingByteBufferPool)clientBufferPool;
assertThat("Client BufferPool - leaked acquires", pool.getLeakedAcquires(), Matchers.is(0L));
assertThat("Client BufferPool - leaked releases", pool.getLeakedReleases(), Matchers.is(0L));
assertThat("Client BufferPool - leaked removes", pool.getLeakedRemoves(), Matchers.is(0L));
diff --git a/jetty-core/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/HttpClientTest.java b/jetty-core/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/HttpClientTest.java
index fe78e9fe136..16b00ec4a66 100644
--- a/jetty-core/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/HttpClientTest.java
+++ b/jetty-core/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/HttpClientTest.java
@@ -13,12 +13,12 @@
package org.eclipse.jetty.fcgi.server;
-import java.io.IOException;
+import java.io.OutputStream;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
import java.util.Arrays;
+import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
@@ -27,10 +27,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.zip.GZIPOutputStream;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.ServletOutputStream;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response;
@@ -40,13 +36,16 @@ import org.eclipse.jetty.client.util.FutureResponseListener;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.io.MappedByteBufferPool;
import org.eclipse.jetty.logging.StacklessLogging;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-import org.eclipse.jetty.toolchain.test.IO;
+import org.eclipse.jetty.server.Content;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.toolchain.test.Net;
import org.eclipse.jetty.util.Callback;
+import org.eclipse.jetty.util.Fields;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Test;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -59,7 +58,14 @@ public class HttpClientTest extends AbstractHttpClientServerTest
@Test
public void testGETResponseWithoutContent() throws Exception
{
- start(new EmptyServerHandler());
+ start(new Handler.Processor()
+ {
+ @Override
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
for (int i = 0; i < 2; ++i)
{
@@ -73,13 +79,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest
public void testGETResponseWithContent() throws Exception
{
byte[] data = new byte[]{0, 1, 2, 3, 4, 5, 6, 7};
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- response.getOutputStream().write(data);
- baseRequest.setHandled(true);
+ response.write(true, callback, ByteBuffer.wrap(data));
}
});
@@ -101,17 +106,16 @@ public class HttpClientTest extends AbstractHttpClientServerTest
{
byte[] data = new byte[16 * 1024 * 1024];
new Random().nextBytes(data);
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
// Setting the Content-Length triggers the HTTP
// content mode for response content parsing,
// otherwise the RAW content mode is used.
response.setContentLength(data.length);
- response.getOutputStream().write(data);
- baseRequest.setHandled(true);
+ response.write(true, callback, ByteBuffer.wrap(data));
}
});
@@ -130,30 +134,29 @@ public class HttpClientTest extends AbstractHttpClientServerTest
{
String paramName1 = "a";
String paramName2 = "b";
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback) throws Exception
{
- response.setCharacterEncoding("UTF-8");
- ServletOutputStream output = response.getOutputStream();
- String paramValue1 = request.getParameter(paramName1);
- output.write(paramValue1.getBytes(StandardCharsets.UTF_8));
- String paramValue2 = request.getParameter(paramName2);
+ response.setContentType("text/plain;charset=utf-8");
+ Fields fields = org.eclipse.jetty.server.Request.extractQueryParameters(request);
+ String paramValue1 = fields.getValue(paramName1);
+ org.eclipse.jetty.server.Response.write(response, false, UTF_8.encode(paramValue1));
+ String paramValue2 = fields.getValue(paramName2);
assertEquals("", paramValue2);
- output.write("empty".getBytes(StandardCharsets.UTF_8));
- baseRequest.setHandled(true);
+ org.eclipse.jetty.server.Response.write(response, true, UTF_8.encode("empty"));
}
});
String value1 = "\u20AC";
- String paramValue1 = URLEncoder.encode(value1, StandardCharsets.UTF_8);
+ String paramValue1 = URLEncoder.encode(value1, UTF_8);
String query = paramName1 + "=" + paramValue1 + "&" + paramName2;
ContentResponse response = client.GET(scheme + "://localhost:" + connector.getLocalPort() + "/?" + query);
assertNotNull(response);
assertEquals(200, response.getStatus());
- String content = new String(response.getContent(), StandardCharsets.UTF_8);
+ String content = new String(response.getContent(), UTF_8);
assertEquals(value1 + "empty", content);
}
@@ -162,36 +165,35 @@ public class HttpClientTest extends AbstractHttpClientServerTest
{
String paramName1 = "a";
String paramName2 = "b";
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback) throws Exception
{
- response.setCharacterEncoding("UTF-8");
- ServletOutputStream output = response.getOutputStream();
- String[] paramValues1 = request.getParameterValues(paramName1);
+ response.setContentType("text/plain;charset=utf-8");
+ Fields fields = org.eclipse.jetty.server.Request.extractQueryParameters(request);
+ List paramValues1 = fields.getValues(paramName1);
for (String paramValue : paramValues1)
{
- output.write(paramValue.getBytes(StandardCharsets.UTF_8));
+ org.eclipse.jetty.server.Response.write(response, false, UTF_8.encode(paramValue));
}
- String paramValue2 = request.getParameter(paramName2);
- output.write(paramValue2.getBytes(StandardCharsets.UTF_8));
- baseRequest.setHandled(true);
+ String paramValue2 = fields.getValue(paramName2);
+ org.eclipse.jetty.server.Response.write(response, true, UTF_8.encode(paramValue2));
}
});
String value11 = "\u20AC";
String value12 = "\u20AA";
String value2 = "&";
- String paramValue11 = URLEncoder.encode(value11, StandardCharsets.UTF_8);
- String paramValue12 = URLEncoder.encode(value12, StandardCharsets.UTF_8);
- String paramValue2 = URLEncoder.encode(value2, StandardCharsets.UTF_8);
+ String paramValue11 = URLEncoder.encode(value11, UTF_8);
+ String paramValue12 = URLEncoder.encode(value12, UTF_8);
+ String paramValue2 = URLEncoder.encode(value2, UTF_8);
String query = paramName1 + "=" + paramValue11 + "&" + paramName1 + "=" + paramValue12 + "&" + paramName2 + "=" + paramValue2;
ContentResponse response = client.GET(scheme + "://localhost:" + connector.getLocalPort() + "/?" + query);
assertNotNull(response);
assertEquals(200, response.getStatus());
- String content = new String(response.getContent(), StandardCharsets.UTF_8);
+ String content = new String(response.getContent(), UTF_8);
assertEquals(value11 + value12 + value2, content);
}
@@ -200,18 +202,17 @@ public class HttpClientTest extends AbstractHttpClientServerTest
{
String paramName = "a";
String paramValue = "\u20AC";
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- baseRequest.setHandled(true);
- String value = request.getParameter(paramName);
+ Fields fields = org.eclipse.jetty.server.Request.extractQueryParameters(request);
+ String value = fields.getValue(paramName);
if (paramValue.equals(value))
{
- response.setCharacterEncoding("UTF-8");
- response.setContentType("text/plain");
- response.getOutputStream().print(value);
+ response.setContentType("text/plain;charset=utf-8");
+ response.write(true, callback, value);
}
}
});
@@ -223,7 +224,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
assertNotNull(response);
assertEquals(200, response.getStatus());
- assertEquals(paramValue, new String(response.getContent(), StandardCharsets.UTF_8));
+ assertEquals(paramValue, new String(response.getContent(), UTF_8));
}
@Test
@@ -231,31 +232,30 @@ public class HttpClientTest extends AbstractHttpClientServerTest
{
String paramName = "a";
String paramValue = "\u20AC";
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- baseRequest.setHandled(true);
- String value = request.getParameter(paramName);
+ Fields fields = org.eclipse.jetty.server.Request.extractQueryParameters(request);
+ String value = fields.getValue(paramName);
if (paramValue.equals(value))
{
- response.setCharacterEncoding("UTF-8");
- response.setContentType("text/plain");
- response.getOutputStream().print(value);
+ response.setContentType("text/plain;charset=utf-8");
+ response.write(true, callback, value);
}
}
});
String uri = scheme + "://localhost:" + connector.getLocalPort() +
- "/?" + paramName + "=" + URLEncoder.encode(paramValue, StandardCharsets.UTF_8);
+ "/?" + paramName + "=" + URLEncoder.encode(paramValue, UTF_8);
ContentResponse response = client.POST(uri)
.timeout(5, TimeUnit.SECONDS)
.send();
assertNotNull(response);
assertEquals(200, response.getStatus());
- assertEquals(paramValue, new String(response.getContent(), StandardCharsets.UTF_8));
+ assertEquals(paramValue, new String(response.getContent(), UTF_8));
}
@Test
@@ -263,18 +263,17 @@ public class HttpClientTest extends AbstractHttpClientServerTest
{
String paramName = "a";
String paramValue = "\u20AC";
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- baseRequest.setHandled(true);
- String value = request.getParameter(paramName);
+ Fields fields = org.eclipse.jetty.server.Request.extractQueryParameters(request);
+ String value = fields.getValue(paramName);
if (paramValue.equals(value))
{
- response.setCharacterEncoding("UTF-8");
- response.setContentType("text/plain");
- response.getOutputStream().print(value);
+ response.setContentType("text/plain;charset=utf-8");
+ response.write(true, callback, value);
}
}
});
@@ -287,7 +286,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
assertNotNull(response);
assertEquals(200, response.getStatus());
- assertEquals(paramValue, new String(response.getContent(), StandardCharsets.UTF_8));
+ assertEquals(paramValue, new String(response.getContent(), UTF_8));
}
@Test
@@ -296,18 +295,17 @@ public class HttpClientTest extends AbstractHttpClientServerTest
byte[] content = {0, 1, 2, 3};
String paramName = "a";
String paramValue = "\u20AC";
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- baseRequest.setHandled(true);
- String value = request.getParameter(paramName);
+ Fields fields = org.eclipse.jetty.server.Request.extractQueryParameters(request);
+ String value = fields.getValue(paramName);
if (paramValue.equals(value))
{
- response.setCharacterEncoding("UTF-8");
response.setContentType("application/octet-stream");
- IO.copy(request.getInputStream(), response.getOutputStream());
+ Content.copy(request, response, callback);
}
}
});
@@ -330,7 +328,14 @@ public class HttpClientTest extends AbstractHttpClientServerTest
public void testPOSTWithContentNotifiesRequestContentListener() throws Exception
{
byte[] content = {0, 1, 2, 3};
- start(new EmptyServerHandler());
+ start(new Handler.Processor()
+ {
+ @Override
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
ContentResponse response = client.POST(scheme + "://localhost:" + connector.getLocalPort())
.onRequestContent((request, buffer) ->
@@ -351,7 +356,14 @@ public class HttpClientTest extends AbstractHttpClientServerTest
@Test
public void testPOSTWithContentTracksProgress() throws Exception
{
- start(new EmptyServerHandler());
+ start(new Handler.Processor()
+ {
+ @Override
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
AtomicInteger progress = new AtomicInteger();
ContentResponse response = client.POST(scheme + "://localhost:" + connector.getLocalPort())
@@ -382,16 +394,17 @@ public class HttpClientTest extends AbstractHttpClientServerTest
clientBufferPool = new MappedByteBufferPool.Tagged();
byte[] data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback) throws Exception
{
- baseRequest.setHandled(true);
- response.setHeader("Content-Encoding", "gzip");
- GZIPOutputStream gzipOutput = new GZIPOutputStream(response.getOutputStream());
+ response.getHeaders().put("Content-Encoding", "gzip");
+ OutputStream outputStream = org.eclipse.jetty.server.Response.asOutputStream(response);
+ GZIPOutputStream gzipOutput = new GZIPOutputStream(outputStream);
gzipOutput.write(data);
gzipOutput.finish();
+ callback.succeeded();
}
});
@@ -408,20 +421,13 @@ public class HttpClientTest extends AbstractHttpClientServerTest
public void testConnectionIdleTimeout() throws Exception
{
long idleTimeout = 1000;
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback) throws Exception
{
- try
- {
- baseRequest.setHandled(true);
- TimeUnit.MILLISECONDS.sleep(2 * idleTimeout);
- }
- catch (InterruptedException x)
- {
- throw new ServletException(x);
- }
+ TimeUnit.MILLISECONDS.sleep(2 * idleTimeout);
+ callback.succeeded();
}
});
@@ -453,7 +459,14 @@ public class HttpClientTest extends AbstractHttpClientServerTest
public void testSendToIPv6Address() throws Exception
{
Assumptions.assumeTrue(Net.isIpv6InterfaceAvailable());
- start(new EmptyServerHandler());
+ start(new Handler.Processor()
+ {
+ @Override
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
ContentResponse response = client.newRequest("[::1]", connector.getLocalPort())
.scheme(scheme)
@@ -468,13 +481,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest
public void testHEADWithResponseContentLength() throws Exception
{
int length = 1024;
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- baseRequest.setHandled(true);
- response.getOutputStream().write(new byte[length]);
+ response.write(true, callback, ByteBuffer.wrap(new byte[length]));
}
});
@@ -505,14 +517,13 @@ public class HttpClientTest extends AbstractHttpClientServerTest
public void testLongPollIsAbortedWhenClientIsStopped() throws Exception
{
CountDownLatch latch = new CountDownLatch(1);
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- baseRequest.setHandled(true);
- request.startAsync();
latch.countDown();
+ // Do not complete the callback.
}
});
@@ -536,20 +547,19 @@ public class HttpClientTest extends AbstractHttpClientServerTest
@Test
public void testEarlyEOF() throws Exception
{
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback) throws Exception
{
- baseRequest.setHandled(true);
// Promise some content, then flush the headers, then fail to send the content.
response.setContentLength(16);
- response.flushBuffer();
+ org.eclipse.jetty.server.Response.write(response, false);
throw new NullPointerException("Explicitly thrown by test");
}
});
- try (StacklessLogging ignore = new StacklessLogging(org.eclipse.jetty.server.HttpChannel.class))
+ try (StacklessLogging ignore = new StacklessLogging(HttpChannel.class))
{
assertThrows(ExecutionException.class, () ->
client.newRequest("localhost", connector.getLocalPort())
@@ -575,14 +585,13 @@ public class HttpClientTest extends AbstractHttpClientServerTest
{
byte[] data = new byte[length];
new Random().nextBytes(data);
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- baseRequest.setHandled(true);
- response.setHeader("Connection", "close");
- response.getOutputStream().write(data);
+ response.getHeaders().put("Connection", "close");
+ response.write(true, callback, ByteBuffer.wrap(data));
}
});
@@ -605,15 +614,13 @@ public class HttpClientTest extends AbstractHttpClientServerTest
@Test
public void testSmallAsyncContent() throws Exception
{
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(org.eclipse.jetty.server.Request request, org.eclipse.jetty.server.Response response, Callback callback) throws Exception
{
- ServletOutputStream output = response.getOutputStream();
- output.write(65);
- output.flush();
- output.write(66);
+ org.eclipse.jetty.server.Response.write(response, false, UTF_8.encode("A"));
+ org.eclipse.jetty.server.Response.write(response, true, UTF_8.encode("B"));
}
});
diff --git a/jetty-fcgi/fcgi-server/src/test/resources/jetty-logging.properties b/jetty-core/jetty-fcgi/fcgi-server/src/test/resources/jetty-logging.properties
similarity index 100%
rename from jetty-fcgi/fcgi-server/src/test/resources/jetty-logging.properties
rename to jetty-core/jetty-fcgi/fcgi-server/src/test/resources/jetty-logging.properties
diff --git a/jetty-core/jetty-fcgi/pom.xml b/jetty-core/jetty-fcgi/pom.xml
index 994805bb38a..4e8997767d1 100644
--- a/jetty-core/jetty-fcgi/pom.xml
+++ b/jetty-core/jetty-fcgi/pom.xml
@@ -2,15 +2,15 @@
org.eclipse.jetty
- jetty-project
- 11.0.10-SNAPSHOT
+ jetty-core
+ 12.0.0-SNAPSHOT4.0.0org.eclipse.jetty.fcgi
- fcgi-parent
+ fcgipom
- Jetty :: FastCGI :: Parent
+ Jetty Core :: FastCGI :: Parentfcgi-client
diff --git a/jetty-core/jetty-http-spi/pom.xml b/jetty-core/jetty-http-spi/pom.xml
index 0e4cdfabc84..02f4327fb61 100644
--- a/jetty-core/jetty-http-spi/pom.xml
+++ b/jetty-core/jetty-http-spi/pom.xml
@@ -1,16 +1,15 @@
org.eclipse.jetty
- jetty-project
- 11.0.10-SNAPSHOT
+ jetty-core
+ 12.0.0-SNAPSHOT4.0.0jetty-http-spi
- Jetty :: Http Service Provider Interface
+ EE9 :: Jetty :: Http Service Provider Interface${project.groupId}.http.spiorg.eclipse.jetty.http.spi.*
- true
@@ -43,15 +42,6 @@
jetty-slf4j-impltest
-
- jakarta.ws.rs
- jakarta.ws.rs-api
-
-
- com.sun.xml.ws
- jaxws-rt
- test
-
@@ -75,6 +65,13 @@
+
+ org.jacoco
+ jacoco-maven-plugin
+
+ true
+
+
diff --git a/jetty-http-spi/src/main/java/module-info.java b/jetty-core/jetty-http-spi/src/main/java/module-info.java
similarity index 100%
rename from jetty-http-spi/src/main/java/module-info.java
rename to jetty-core/jetty-http-spi/src/main/java/module-info.java
diff --git a/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/HttpSpiContextHandler.java b/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/HttpSpiContextHandler.java
index 35b0d22dda3..128001137e1 100644
--- a/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/HttpSpiContextHandler.java
+++ b/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/HttpSpiContextHandler.java
@@ -13,8 +13,6 @@
package org.eclipse.jetty.http.spi;
-import java.io.IOException;
-import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
@@ -24,12 +22,11 @@ import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpPrincipal;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.handler.ContextHandler;
-import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.Callback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,7 +37,7 @@ public class HttpSpiContextHandler extends ContextHandler
{
public static final Logger LOG = LoggerFactory.getLogger(HttpSpiContextHandler.class);
- private HttpContext _httpContext;
+ private final HttpContext _httpContext;
private HttpHandler _httpHandler;
@@ -48,68 +45,43 @@ public class HttpSpiContextHandler extends ContextHandler
{
this._httpContext = httpContext;
this._httpHandler = httpHandler;
+ super.setHandler(new Handler.Processor()
+ {
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ try (HttpExchange jettyHttpExchange = request.isSecure()
+ ? new JettyHttpsExchange(_httpContext, request, response)
+ : new JettyHttpExchange(_httpContext, request, response))
+ {
+ Authenticator auth = _httpContext.getAuthenticator();
+ if (auth != null && handleAuthentication(request, response, callback, jettyHttpExchange, auth))
+ return;
+
+ _httpHandler.handle(jettyHttpExchange);
+ callback.succeeded();
+ }
+ catch (Exception ex)
+ {
+ LOG.debug("Failed to handle", ex);
+ Response.writeError(request, response, callback, 500, null, ex);
+ }
+ }
+ });
}
@Override
- public void doScope(String target, Request baseRequest, HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException
+ public void setHandler(Handler handler)
{
- if (!target.startsWith(getContextPath()))
- {
- return;
- }
-
- HttpExchange jettyHttpExchange;
- if (baseRequest.isSecure())
- {
- jettyHttpExchange = new JettyHttpsExchange(_httpContext, req, resp);
- }
- else
- {
- jettyHttpExchange = new JettyHttpExchange(_httpContext, req, resp);
- }
-
- // TODO: add filters processing
-
- try
- {
- Authenticator auth = _httpContext.getAuthenticator();
- if (auth != null)
- {
- handleAuthentication(resp, jettyHttpExchange, auth);
- }
- else
- {
- _httpHandler.handle(jettyHttpExchange);
- }
- }
- catch (Exception ex)
- {
- LOG.debug("Failed to handle", ex);
- PrintWriter writer = new PrintWriter(jettyHttpExchange.getResponseBody());
-
- resp.setStatus(500);
- writer.println("
");
-
- writer.close();
- }
- finally
- {
- baseRequest.setHandled(true);
- }
+ throw new UnsupportedOperationException();
}
- private void handleAuthentication(HttpServletResponse resp, HttpExchange httpExchange, Authenticator auth) throws IOException
+ private boolean handleAuthentication(
+ Request request,
+ Response response,
+ Callback callback,
+ HttpExchange httpExchange,
+ Authenticator auth)
{
Result result = auth.authenticate(httpExchange);
if (result instanceof Authenticator.Failure)
@@ -118,31 +90,35 @@ public class HttpSpiContextHandler extends ContextHandler
for (Map.Entry> header : httpExchange.getResponseHeaders().entrySet())
{
for (String value : header.getValue())
- {
- resp.addHeader(header.getKey(), value);
- }
+ response.addHeader(header.getKey(), value);
}
- resp.sendError(rc);
+ Response.writeError(request, response, callback, rc);
+ return true;
}
- else if (result instanceof Authenticator.Retry)
+
+ if (result instanceof Authenticator.Retry)
{
int rc = ((Authenticator.Retry)result).getResponseCode();
for (Map.Entry> header : httpExchange.getResponseHeaders().entrySet())
{
for (String value : header.getValue())
{
- resp.addHeader(header.getKey(), value);
+ response.addHeader(header.getKey(), value);
}
}
- resp.setStatus(rc);
- resp.flushBuffer();
+ Response.writeError(request, response, callback, rc);
+ return true;
}
- else if (result instanceof Authenticator.Success)
+
+ if (result instanceof Authenticator.Success)
{
HttpPrincipal principal = ((Authenticator.Success)result).getPrincipal();
((JettyExchange)httpExchange).setPrincipal(principal);
- _httpHandler.handle(httpExchange);
+ return false;
}
+
+ Response.writeError(request, response, callback, 500);
+ return true;
}
public HttpHandler getHttpHandler()
diff --git a/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpContext.java b/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpContext.java
index 6589cdd7ccf..f7c2fd9f1bd 100644
--- a/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpContext.java
+++ b/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpContext.java
@@ -29,22 +29,21 @@ import com.sun.net.httpserver.HttpServer;
public class JettyHttpContext extends com.sun.net.httpserver.HttpContext
{
- private HttpSpiContextHandler _jettyContextHandler;
+ private final HttpSpiContextHandler _jettyContextHandler;
- private HttpServer _server;
+ private final HttpServer _server;
- private Map _attributes = new HashMap();
+ private final Map _attributes = new HashMap();
- private List _filters = new ArrayList();
+ private final List _filters = new ArrayList();
private Authenticator _authenticator;
- protected JettyHttpContext(HttpServer server, String path,
- HttpHandler handler)
+ protected JettyHttpContext(HttpServer server, String contextPath, HttpHandler handler)
{
this._server = server;
_jettyContextHandler = new HttpSpiContextHandler(this, handler);
- _jettyContextHandler.setContextPath(path);
+ _jettyContextHandler.setContextPath(contextPath);
}
protected HttpSpiContextHandler getJettyContextHandler()
diff --git a/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchange.java b/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchange.java
index 330416e6597..0f2f9dcc530 100644
--- a/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchange.java
+++ b/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchange.java
@@ -23,14 +23,14 @@ import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpPrincipal;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
public class JettyHttpExchange extends HttpExchange implements JettyExchange
{
- private JettyHttpExchangeDelegate _delegate;
+ private final JettyHttpExchangeDelegate _delegate;
- public JettyHttpExchange(HttpContext jaxWsContext, HttpServletRequest req, HttpServletResponse resp)
+ public JettyHttpExchange(HttpContext jaxWsContext, Request req, Response resp)
{
super();
_delegate = new JettyHttpExchangeDelegate(jaxWsContext, req, resp);
diff --git a/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchangeDelegate.java b/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchangeDelegate.java
index 785ceb2ef2b..5d54ff07270 100644
--- a/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchangeDelegate.java
+++ b/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchangeDelegate.java
@@ -17,9 +17,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Enumeration;
import java.util.List;
import java.util.Map;
@@ -27,61 +26,52 @@ import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpPrincipal;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.http.HttpField;
+import org.eclipse.jetty.server.Content;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
/**
* Jetty implementation of {@link com.sun.net.httpserver.HttpExchange}
*/
public class JettyHttpExchangeDelegate extends HttpExchange
{
+ private final HttpContext _httpContext;
- private HttpContext _httpContext;
+ private final Request _request;
- private HttpServletRequest _req;
+ private final Response _response;
- private HttpServletResponse _resp;
-
- private Headers _responseHeaders = new Headers();
+ private final Headers _responseHeaders = new Headers();
private int _responseCode = 0;
- private InputStream _is;
+ private InputStream _inputStream;
- private OutputStream _os;
+ private OutputStream _outputStream;
private HttpPrincipal _httpPrincipal;
- JettyHttpExchangeDelegate(HttpContext jaxWsContext, HttpServletRequest req, HttpServletResponse resp)
+ JettyHttpExchangeDelegate(HttpContext httpSpiContext, Request request, Response response)
{
- this._httpContext = jaxWsContext;
- this._req = req;
- this._resp = resp;
- try
- {
- this._is = req.getInputStream();
- this._os = resp.getOutputStream();
- }
- catch (IOException ex)
- {
- throw new RuntimeException(ex);
- }
+ this._httpContext = httpSpiContext;
+ this._request = request;
+ this._response = response;
+ this._inputStream = Content.asInputStream(request);
+ this._outputStream = Content.asOutputStream(response);
}
@Override
public Headers getRequestHeaders()
{
Headers headers = new Headers();
- Enumeration> en = _req.getHeaderNames();
- while (en.hasMoreElements())
+
+ for (HttpField field : _request.getHeaders())
{
- String name = (String)en.nextElement();
- Enumeration> en2 = _req.getHeaders(name);
- while (en2.hasMoreElements())
- {
- String value = (String)en2.nextElement();
- headers.add(name, value);
- }
+ if (field.getValue() == null)
+ continue;
+ for (String value : field.getValues())
+ headers.add(field.getName(), value);
}
return headers;
}
@@ -95,26 +85,13 @@ public class JettyHttpExchangeDelegate extends HttpExchange
@Override
public URI getRequestURI()
{
- try
- {
- String uriAsString = _req.getRequestURI();
- if (_req.getQueryString() != null)
- {
- uriAsString += "?" + _req.getQueryString();
- }
-
- return new URI(uriAsString);
- }
- catch (URISyntaxException ex)
- {
- throw new RuntimeException(ex);
- }
+ return _request.getHttpURI().toURI();
}
@Override
public String getRequestMethod()
{
- return _req.getMethod();
+ return _request.getMethod();
}
@Override
@@ -128,7 +105,7 @@ public class JettyHttpExchangeDelegate extends HttpExchange
{
try
{
- _resp.getOutputStream().close();
+ _outputStream.close();
}
catch (IOException ex)
{
@@ -139,13 +116,13 @@ public class JettyHttpExchangeDelegate extends HttpExchange
@Override
public InputStream getRequestBody()
{
- return _is;
+ return _inputStream;
}
@Override
public OutputStream getResponseBody()
{
- return _os;
+ return _outputStream;
}
@Override
@@ -160,20 +137,23 @@ public class JettyHttpExchangeDelegate extends HttpExchange
for (String value : values)
{
- _resp.setHeader(name, value);
+ _response.setHeader(name, value);
}
}
if (responseLength > 0)
{
- _resp.setHeader("content-length", "" + responseLength);
+ _response.setHeader("content-length", "" + responseLength);
}
- _resp.setStatus(rCode);
+ _response.setStatus(rCode);
}
@Override
public InetSocketAddress getRemoteAddress()
{
- return new InetSocketAddress(_req.getRemoteAddr(), _req.getRemotePort());
+ SocketAddress remote = _request.getConnectionMetaData().getRemoteSocketAddress();
+ if (remote instanceof InetSocketAddress inet)
+ return inet;
+ return null;
}
@Override
@@ -185,32 +165,35 @@ public class JettyHttpExchangeDelegate extends HttpExchange
@Override
public InetSocketAddress getLocalAddress()
{
- return new InetSocketAddress(_req.getLocalAddr(), _req.getLocalPort());
+ SocketAddress local = _request.getConnectionMetaData().getLocalSocketAddress();
+ if (local instanceof InetSocketAddress inet)
+ return inet;
+ return null;
}
@Override
public String getProtocol()
{
- return _req.getProtocol();
+ return _request.getConnectionMetaData().getProtocol();
}
@Override
public Object getAttribute(String name)
{
- return _req.getAttribute(name);
+ return _request.getAttribute(name);
}
@Override
public void setAttribute(String name, Object value)
{
- _req.setAttribute(name, value);
+ _request.setAttribute(name, value);
}
@Override
public void setStreams(InputStream i, OutputStream o)
{
- _is = i;
- _os = o;
+ _inputStream = i;
+ _outputStream = o;
}
@Override
diff --git a/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServer.java b/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServer.java
index c927af44785..0318127bbde 100644
--- a/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServer.java
+++ b/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServer.java
@@ -17,6 +17,7 @@ import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
@@ -41,19 +42,13 @@ import org.slf4j.LoggerFactory;
public class JettyHttpServer extends com.sun.net.httpserver.HttpServer
{
private static final Logger LOG = LoggerFactory.getLogger(JettyHttpServer.class);
-
private final HttpConfiguration _httpConfiguration;
-
private final Server _server;
-
- private boolean _serverShared;
-
+ private final boolean _serverShared;
+ private final Map _contexts = new HashMap<>();
+ private final Map _connectors = new HashMap<>();
private InetSocketAddress _addr;
- private Map _contexts = new HashMap<>();
-
- private Map _connectors = new HashMap<>();
-
public JettyHttpServer(Server server, boolean shared)
{
this(server, shared, new HttpConfiguration());
@@ -233,7 +228,7 @@ public class JettyHttpServer extends com.sun.net.httpserver.HttpServer
JettyHttpContext context = new JettyHttpContext(this, path, httpHandler);
HttpSpiContextHandler jettyContextHandler = context.getJettyContextHandler();
- ContextHandlerCollection chc = _server.getChildHandlerByClass(ContextHandlerCollection.class);
+ ContextHandlerCollection chc = _server.getDescendant(ContextHandlerCollection.class);
if (chc == null)
throw new RuntimeException("could not find ContextHandlerCollection, you must configure one");
@@ -270,10 +265,7 @@ public class JettyHttpServer extends com.sun.net.httpserver.HttpServer
throw new RuntimeException("another context already bound to path " + path);
}
- Handler[] handlers = _server.getHandlers();
- if (handlers == null)
- return;
-
+ List handlers = _server.getHandlers();
for (Handler handler : handlers)
{
if (handler instanceof ContextHandler)
@@ -293,7 +285,7 @@ public class JettyHttpServer extends com.sun.net.httpserver.HttpServer
return;
HttpSpiContextHandler handler = context.getJettyContextHandler();
- ContextHandlerCollection chc = _server.getChildHandlerByClass(ContextHandlerCollection.class);
+ ContextHandlerCollection chc = _server.getDescendant(ContextHandlerCollection.class);
try
{
handler.stop();
diff --git a/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpsExchange.java b/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpsExchange.java
index cda6eef40b3..41476aa8092 100644
--- a/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpsExchange.java
+++ b/jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpsExchange.java
@@ -24,17 +24,17 @@ import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpPrincipal;
import com.sun.net.httpserver.HttpsExchange;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
/**
*
*/
public class JettyHttpsExchange extends HttpsExchange implements JettyExchange
{
- private JettyHttpExchangeDelegate _delegate;
+ private final JettyHttpExchangeDelegate _delegate;
- public JettyHttpsExchange(HttpContext jaxWsContext, HttpServletRequest req, HttpServletResponse resp)
+ public JettyHttpsExchange(HttpContext jaxWsContext, Request req, Response resp)
{
super();
_delegate = new JettyHttpExchangeDelegate(jaxWsContext, req, resp);
diff --git a/jetty-core/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestSPIServer.java b/jetty-core/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestSPIServer.java
index 7a90944fd1b..b4029b4a241 100644
--- a/jetty-core/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestSPIServer.java
+++ b/jetty-core/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestSPIServer.java
@@ -16,7 +16,6 @@ package org.eclipse.jetty.http.spi;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.URI;
-import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -24,11 +23,11 @@ import com.sun.net.httpserver.BasicAuthenticator;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpServer;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.util.BasicAuthentication;
+import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Server;
import org.junit.jupiter.api.Test;
@@ -67,11 +66,9 @@ public class TestSPIServer
OutputStream responseBody = exchange.getResponseBody();
Headers requestHeaders = exchange.getRequestHeaders();
Set keySet = requestHeaders.keySet();
- Iterator iter = keySet.iterator();
- while (iter.hasNext())
+ for (String key : keySet)
{
- String key = iter.next();
- List values = requestHeaders.get(key);
+ List values = requestHeaders.get(key);
String s = key + " = " + values.toString() + "\n";
responseBody.write(s.getBytes());
}
@@ -83,9 +80,7 @@ public class TestSPIServer
@Override
public boolean checkCredentials(String username, String password)
{
- if ("username".equals(username) && password.equals("password"))
- return true;
- return false;
+ return "username".equals(username) && password.equals("password");
}
});
@@ -109,7 +104,7 @@ public class TestSPIServer
Request request = client.newRequest("http://localhost:" + port + "/");
client.getAuthenticationStore().addAuthentication(new BasicAuthentication(URI.create("http://localhost:" + port), "Test", "username", "password"));
ContentResponse response = request.send();
- assertEquals(HttpServletResponse.SC_OK, response.getStatus());
+ assertEquals(HttpStatus.OK_200, response.getStatus());
}
finally
{
@@ -150,11 +145,9 @@ public class TestSPIServer
OutputStream responseBody = exchange.getResponseBody();
Headers requestHeaders = exchange.getRequestHeaders();
Set keySet = requestHeaders.keySet();
- Iterator iter = keySet.iterator();
- while (iter.hasNext())
+ for (String key : keySet)
{
- String key = iter.next();
- List values = requestHeaders.get(key);
+ List values = requestHeaders.get(key);
String s = key + " = " + values.toString() + "\n";
responseBody.write(s.getBytes());
}
@@ -166,9 +159,7 @@ public class TestSPIServer
@Override
public boolean checkCredentials(String username, String password)
{
- if ("username".equals(username) && password.equals("password"))
- return true;
- return false;
+ return "username".equals(username) && password.equals("password");
}
});
@@ -186,7 +177,7 @@ public class TestSPIServer
Request request = client.newRequest("http://localhost:" + port + "/");
client.getAuthenticationStore().addAuthentication(new BasicAuthentication(URI.create("http://localhost:" + port), "Test", "username", "password"));
ContentResponse response = request.send();
- assertEquals(HttpServletResponse.SC_OK, response.getStatus());
+ assertEquals(HttpStatus.OK_200, response.getStatus());
}
finally
{
diff --git a/tests/jetty-http-tools/pom.xml b/jetty-core/jetty-http-tools/pom.xml
similarity index 78%
rename from tests/jetty-http-tools/pom.xml
rename to jetty-core/jetty-http-tools/pom.xml
index 5b1c7ce3d05..1e8d5cfcf1d 100644
--- a/tests/jetty-http-tools/pom.xml
+++ b/jetty-core/jetty-http-tools/pom.xml
@@ -1,14 +1,14 @@
- org.eclipse.jetty.tests
- tests-parent
- 11.0.10-SNAPSHOT
+ org.eclipse.jetty
+ jetty-core
+ 12.0.0-SNAPSHOT4.0.0jetty-http-tools
- Jetty Tests :: HTTP Utilities
+ Jetty :: HTTP Testing Utilities
diff --git a/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderKey.java b/jetty-core/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderKey.java
similarity index 100%
rename from tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderKey.java
rename to jetty-core/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderKey.java
diff --git a/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderValue.java b/jetty-core/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderValue.java
similarity index 100%
rename from tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderValue.java
rename to jetty-core/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderValue.java
diff --git a/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsHeaderValue.java b/jetty-core/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsHeaderValue.java
similarity index 100%
rename from tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsHeaderValue.java
rename to jetty-core/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsHeaderValue.java
diff --git a/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchers.java b/jetty-core/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchers.java
similarity index 100%
rename from tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchers.java
rename to jetty-core/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchers.java
diff --git a/tests/jetty-http-tools/src/test/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchersTest.java b/jetty-core/jetty-http-tools/src/test/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchersTest.java
similarity index 100%
rename from tests/jetty-http-tools/src/test/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchersTest.java
rename to jetty-core/jetty-http-tools/src/test/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchersTest.java
diff --git a/jetty-core/jetty-http/pom.xml b/jetty-core/jetty-http/pom.xml
index 36af987fedd..c3ec5511410 100644
--- a/jetty-core/jetty-http/pom.xml
+++ b/jetty-core/jetty-http/pom.xml
@@ -1,14 +1,14 @@
- jetty-projectorg.eclipse.jetty
- 11.0.10-SNAPSHOT
+ jetty-core
+ 12.0.0-SNAPSHOT4.0.0jetty-http
- Jetty :: Http Utility
+ Jetty Core :: Http Utility${project.groupId}.http
diff --git a/jetty-http/src/main/java/module-info.java b/jetty-core/jetty-http/src/main/java/module-info.java
similarity index 89%
rename from jetty-http/src/main/java/module-info.java
rename to jetty-core/jetty-http/src/main/java/module-info.java
index 20e0b7c90e6..06f8a8c1e34 100644
--- a/jetty-http/src/main/java/module-info.java
+++ b/jetty-core/jetty-http/src/main/java/module-info.java
@@ -23,5 +23,6 @@ module org.eclipse.jetty.http
uses org.eclipse.jetty.http.HttpFieldPreEncoder;
provides org.eclipse.jetty.http.HttpFieldPreEncoder with
- org.eclipse.jetty.http.Http1FieldPreEncoder;
+ org.eclipse.jetty.http.Http10FieldPreEncoder,
+ org.eclipse.jetty.http.Http11FieldPreEncoder;
}
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/BadMessageException.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/BadMessageException.java
index a9dad571766..088546f0026 100644
--- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/BadMessageException.java
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/BadMessageException.java
@@ -26,12 +26,12 @@ public class BadMessageException extends RuntimeException
public BadMessageException()
{
- this(400, null);
+ this(400, null, null);
}
public BadMessageException(int code)
{
- this(code, null);
+ this(code, null, null);
}
public BadMessageException(String reason)
@@ -49,6 +49,11 @@ public class BadMessageException extends RuntimeException
this(code, reason, null);
}
+ public BadMessageException(int code, Throwable cause)
+ {
+ this(code, null, cause);
+ }
+
public BadMessageException(int code, String reason, Throwable cause)
{
super(code + ": " + reason, cause);
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/CachingContentFactory.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/CachingContentFactory.java
new file mode 100644
index 00000000000..be4ee311610
--- /dev/null
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/CachingContentFactory.java
@@ -0,0 +1,407 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.http;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SeekableByteChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.FileTime;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.eclipse.jetty.util.BufferUtil;
+import org.eclipse.jetty.util.QuotedStringTokenizer;
+import org.eclipse.jetty.util.resource.Resource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * HttpContent.ContentFactory implementation that wraps any other HttpContent.ContentFactory instance
+ * using it as a caching authority.
+ * Only HttpContent instances whose path is not a directory are cached.
+ * HttpContent instances returned by getContent() implement HttpContent.InMemory when a cached instance is found.
+ *
+ * TODO should directories (generated HTML) and not-found contents be cached?
+ * TODO this form of caching is done at a layer below the request processor (i.e.: done in the guts of the ResourceHandler)
+ * Consider if caching should rather be done at a layer above using a CachingHandler that would intercept Response.write()
+ * of a configured URI set, save that in a cache and serve that again.
+ */
+public class CachingContentFactory implements HttpContent.ContentFactory
+{
+ private static final Logger LOG = LoggerFactory.getLogger(CachingContentFactory.class);
+
+ private final HttpContent.ContentFactory _authority;
+ private final boolean _useFileMappedBuffer;
+ private final ConcurrentMap _cache = new ConcurrentHashMap<>();
+ private final AtomicLong _cachedSize = new AtomicLong();
+ private int _maxCachedFileSize = 128 * 1024 * 1024;
+ private int _maxCachedFiles = 2048;
+ private int _maxCacheSize = 256 * 1024 * 1024;
+
+ public CachingContentFactory(HttpContent.ContentFactory authority)
+ {
+ this(authority, false);
+ }
+
+ public CachingContentFactory(HttpContent.ContentFactory authority, boolean useFileMappedBuffer)
+ {
+ _authority = authority;
+ _useFileMappedBuffer = useFileMappedBuffer;
+ }
+
+ public long getCachedSize()
+ {
+ return _cachedSize.get();
+ }
+
+ public int getCachedFiles()
+ {
+ return _cache.size();
+ }
+
+ public int getMaxCachedFileSize()
+ {
+ return _maxCachedFileSize;
+ }
+
+ public void setMaxCachedFileSize(int maxCachedFileSize)
+ {
+ _maxCachedFileSize = maxCachedFileSize;
+ shrinkCache();
+ }
+
+ public int getMaxCacheSize()
+ {
+ return _maxCacheSize;
+ }
+
+ public void setMaxCacheSize(int maxCacheSize)
+ {
+ _maxCacheSize = maxCacheSize;
+ shrinkCache();
+ }
+
+ /**
+ * @return the max number of cached files.
+ */
+ public int getMaxCachedFiles()
+ {
+ return _maxCachedFiles;
+ }
+
+ /**
+ * @param maxCachedFiles the max number of cached files.
+ */
+ public void setMaxCachedFiles(int maxCachedFiles)
+ {
+ _maxCachedFiles = maxCachedFiles;
+ shrinkCache();
+ }
+
+ public boolean isUseFileMappedBuffer()
+ {
+ return _useFileMappedBuffer;
+ }
+
+ private void shrinkCache()
+ {
+ // While we need to shrink
+ while (_cache.size() > 0 && (_cache.size() > _maxCachedFiles || _cachedSize.get() > _maxCacheSize))
+ {
+ // Scan the entire cache and generate an ordered list by last accessed time.
+ SortedSet sorted = new TreeSet<>((c1, c2) ->
+ {
+ if (c1._lastAccessed != c2._lastAccessed)
+ return Long.compare(c1._lastAccessed, c2._lastAccessed);
+
+ if (c1._contentLengthValue < c2._contentLengthValue)
+ return -1;
+
+ return c1._cacheKey.compareTo(c2._cacheKey);
+ });
+ sorted.addAll(_cache.values());
+
+ // Invalidate least recently used first
+ for (CachingHttpContent content : sorted)
+ {
+ if (_cache.size() <= _maxCachedFiles && _cachedSize.get() <= _maxCacheSize)
+ break;
+ removeFromCache(content);
+ }
+ }
+ }
+
+ private void removeFromCache(CachingHttpContent content)
+ {
+ if (content == _cache.remove(content._cacheKey))
+ {
+ content.release();
+ _cachedSize.addAndGet(-content.calculateSize());
+ }
+ }
+
+ public void flushCache()
+ {
+ for (CachingHttpContent content : _cache.values())
+ {
+ removeFromCache(content);
+ }
+ }
+
+ @Override
+ public HttpContent getContent(String path, int maxBuffer) throws IOException
+ {
+ // TODO load precompressed otherwise it is never served from cache
+ CachingHttpContent cachingHttpContent = _cache.get(path);
+ if (cachingHttpContent != null)
+ {
+ if (cachingHttpContent.isValid())
+ return cachingHttpContent;
+ else
+ removeFromCache(cachingHttpContent);
+ }
+ HttpContent httpContent = _authority.getContent(path, maxBuffer);
+ // Do not cache directories or files that are too big
+ if (httpContent != null && !Files.isDirectory(httpContent.getPath()) && httpContent.getContentLengthValue() <= _maxCachedFileSize)
+ {
+ httpContent = cachingHttpContent = new CachingHttpContent(path, null, httpContent);
+ _cache.put(path, cachingHttpContent);
+ _cachedSize.addAndGet(cachingHttpContent.calculateSize());
+ shrinkCache();
+ }
+ return httpContent;
+ }
+
+ private class CachingHttpContent implements HttpContent
+ {
+ private final HttpContent _delegate;
+ private final ByteBuffer _buffer;
+ private final FileTime _lastModifiedValue;
+ private final String _cacheKey;
+ private final String _etag;
+ private final long _contentLengthValue;
+ private final Map _precompressedContents;
+ private volatile long _lastAccessed;
+
+ private CachingHttpContent(String key, String precalculatedEtag, HttpContent httpContent) throws IOException
+ {
+ _etag = precalculatedEtag;
+ _contentLengthValue = httpContent.getContentLengthValue(); // TODO getContentLengthValue() could return -1
+ ByteBuffer byteBuffer;
+
+ if (_useFileMappedBuffer)
+ {
+ // mmap the content into memory
+ byteBuffer = BufferUtil.toMappedBuffer(httpContent.getPath(), 0, _contentLengthValue);
+ }
+ else
+ {
+ // TODO use pool & check length limit
+ // load the content into memory
+ byteBuffer = ByteBuffer.allocateDirect((int)_contentLengthValue);
+ try (SeekableByteChannel channel = Files.newByteChannel(httpContent.getPath()))
+ {
+ // fill buffer
+ int read = 0;
+ while (read != _contentLengthValue)
+ read += channel.read(byteBuffer);
+ }
+ byteBuffer.flip();
+ }
+
+ // Load precompressed contents into memory.
+ Map precompressedContents = httpContent.getPrecompressedContents();
+ if (precompressedContents != null)
+ {
+ _precompressedContents = new HashMap<>();
+ for (Map.Entry entry : precompressedContents.entrySet())
+ {
+ CompressedContentFormat format = entry.getKey();
+
+ // Rewrite the etag to be the content's one with the required suffix all within quotes.
+ String precompressedEtag = httpContent.getETagValue();
+ boolean weak = false;
+ if (precompressedEtag.startsWith("W/"))
+ {
+ weak = true;
+ precompressedEtag = precompressedEtag.substring(2);
+ }
+ precompressedEtag = (weak ? "W/\"" : "\"") + QuotedStringTokenizer.unquote(precompressedEtag) + format.getEtagSuffix() + '"';
+
+ // The etag of the precompressed content must be the one of the non-compressed content, with the etag suffix appended.
+ _precompressedContents.put(format, new CachingHttpContent(key, precompressedEtag, entry.getValue()));
+ }
+ }
+ else
+ {
+ _precompressedContents = null;
+ }
+
+ _cacheKey = key;
+ _buffer = byteBuffer;
+ _lastModifiedValue = Files.getLastModifiedTime(httpContent.getPath());
+ _delegate = httpContent;
+ _lastAccessed = System.nanoTime();
+ }
+
+ long calculateSize()
+ {
+ long totalSize = _contentLengthValue;
+ if (_precompressedContents != null)
+ {
+ for (CachingHttpContent cachingHttpContent : _precompressedContents.values())
+ {
+ totalSize += cachingHttpContent.calculateSize();
+ }
+ }
+ return totalSize;
+ }
+
+ @Override
+ public ByteBuffer getBuffer()
+ {
+ // TODO this should return a RetainableByteBuffer otherwise there is a race between
+ // threads serving the buffer while another thread invalidates it. That's going to
+ // be a lot of fun since RetainableByteBuffer is only meant to be acquired from a pool
+ // but the byte buffer here could be coming from a mmap'ed file.
+ return _buffer.slice();
+ }
+
+ public boolean isValid()
+ {
+ try
+ {
+ FileTime lastModifiedTime = Files.getLastModifiedTime(_delegate.getPath());
+ if (lastModifiedTime.equals(_lastModifiedValue))
+ {
+ _lastAccessed = System.nanoTime();
+ return true;
+ }
+ }
+ catch (IOException e)
+ {
+ LOG.debug("unable to get delegate path' LastModifiedTime", e);
+ }
+ release();
+ return false;
+ }
+
+ @Override
+ public void release()
+ {
+ // TODO re-pool buffer and release precompressed contents
+ }
+
+ @Override
+ public HttpField getContentType()
+ {
+ return _delegate.getContentType();
+ }
+
+ @Override
+ public String getContentTypeValue()
+ {
+ return _delegate.getContentTypeValue();
+ }
+
+ @Override
+ public String getCharacterEncoding()
+ {
+ return _delegate.getCharacterEncoding();
+ }
+
+ @Override
+ public MimeTypes.Type getMimeType()
+ {
+ return _delegate.getMimeType();
+ }
+
+ @Override
+ public HttpField getContentEncoding()
+ {
+ return _delegate.getContentEncoding();
+ }
+
+ @Override
+ public String getContentEncodingValue()
+ {
+ return _delegate.getContentEncodingValue();
+ }
+
+ @Override
+ public HttpField getContentLength()
+ {
+ return _delegate.getContentLength();
+ }
+
+ @Override
+ public long getContentLengthValue()
+ {
+ return _delegate.getContentLengthValue();
+ }
+
+ @Override
+ public HttpField getLastModified()
+ {
+ return _delegate.getLastModified();
+ }
+
+ @Override
+ public String getLastModifiedValue()
+ {
+ return _delegate.getLastModifiedValue();
+ }
+
+ @Override
+ public HttpField getETag()
+ {
+ String eTag = getETagValue();
+ return eTag == null ? null : new HttpField(HttpHeader.ETAG, eTag);
+ }
+
+ @Override
+ public String getETagValue()
+ {
+ if (_etag != null)
+ return _etag;
+ else
+ return _delegate.getETagValue();
+ }
+
+ @Override
+ public Path getPath()
+ {
+ return _delegate.getPath();
+ }
+
+ @Override
+ public Resource getResource()
+ {
+ return _delegate.getResource();
+ }
+
+ @Override
+ public Map getPrecompressedContents()
+ {
+ return _precompressedContents;
+ }
+ }
+}
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCache.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCache.java
new file mode 100644
index 00000000000..32358751520
--- /dev/null
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCache.java
@@ -0,0 +1,118 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.http;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Cookie parser
+ *
Optimized stateful cookie parser. Cookies fields are added with the
+ * {@link #addCookieField(String)} method and parsed on the next subsequent
+ * call to {@link #getCookies(HttpFields)}.
+ * If the added fields are identical to those last added (as strings), then the
+ * cookies are not re parsed.
+ *
+ */
+public class CookieCache extends CookieCutter
+{
+ protected static final Logger LOG = LoggerFactory.getLogger(CookieCache.class);
+ protected final List _rawFields = new ArrayList<>();
+ protected final List _cookieList = new ArrayList<>();
+ private int _addedFields;
+ private boolean _parsed = false;
+ private boolean _set = false;
+
+ public CookieCache()
+ {
+ this(CookieCompliance.RFC6265, null);
+ }
+
+ public CookieCache(CookieCompliance compliance, ComplianceViolation.Listener complianceListener)
+ {
+ super(compliance, complianceListener);
+ }
+
+ private void addCookieField(String rawField)
+ {
+ if (_set)
+ throw new IllegalStateException();
+
+ if (rawField == null)
+ return;
+ rawField = rawField.trim();
+ if (rawField.length() == 0)
+ return;
+
+ if (_rawFields.size() > _addedFields)
+ {
+ if (rawField.equals(_rawFields.get(_addedFields)))
+ {
+ _addedFields++;
+ return;
+ }
+
+ while (_rawFields.size() > _addedFields)
+ {
+ _rawFields.remove(_addedFields);
+ }
+ }
+ _rawFields.add(_addedFields++, rawField);
+ _parsed = false;
+ }
+
+ public List getCookies(HttpFields headers)
+ {
+ // TODO this could be done a lot better with a single iteration and not creating a new list etc.
+ _set = false;
+ _addedFields = 0;
+ for (HttpField field : headers)
+ {
+ if (HttpHeader.COOKIE.equals(field.getHeader()))
+ addCookieField(field.getValue());
+ }
+
+ while (_rawFields.size() > _addedFields)
+ {
+ _rawFields.remove(_addedFields);
+ _parsed = false;
+ }
+
+ if (_parsed)
+ return _cookieList;
+
+ parseFields(_rawFields);
+ _parsed = true;
+ return _cookieList;
+ }
+
+ @Override
+ protected void addCookie(String name, String value, String domain, String path, int version, String comment)
+ {
+ try
+ {
+ // TODO probably should only do name & value now. Version is not longer a thing!
+ HttpCookie cookie = new HttpCookie(name, value, domain, path, -1, false, false, comment, version);
+ _cookieList.add(cookie);
+ }
+ catch (Exception e)
+ {
+ LOG.debug("Unable to add Cookie name={}, value={}, domain={}, path={}, version={}, comment={}",
+ name, value, domain, path, version, comment, e);
+ }
+ }
+}
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCutter.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCutter.java
index bdd08083c4f..adaaa62a4cc 100644
--- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCutter.java
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCutter.java
@@ -157,7 +157,7 @@ public abstract class CookieCutter
try
{
- if (name.startsWith("$"))
+ if (name != null && name.startsWith("$"))
{
if (RESERVED_NAMES_NOT_DOLLAR_PREFIXED.isAllowedBy(_complianceMode))
{
@@ -165,20 +165,10 @@ public abstract class CookieCutter
String lowercaseName = name.toLowerCase(Locale.ENGLISH);
switch (lowercaseName)
{
- case "$path":
- cookiePath = value;
- break;
- case "$domain":
- cookieDomain = value;
- break;
- case "$port":
- cookieComment = "$port=" + value;
- break;
- case "$version":
- cookieVersion = Integer.parseInt(value);
- break;
- default:
- break;
+ case "$path" -> cookiePath = value;
+ case "$domain" -> cookieDomain = value;
+ case "$port" -> cookieComment = "$port=" + value;
+ case "$version" -> cookieVersion = Integer.parseInt(value);
}
}
}
@@ -188,10 +178,7 @@ public abstract class CookieCutter
if (cookieName != null)
{
if (!reject)
- {
addCookie(cookieName, cookieValue, cookieDomain, cookiePath, cookieVersion, cookieComment);
- reject = false;
- }
cookieDomain = null;
cookiePath = null;
cookieComment = null;
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java
index c3cfebd187a..d7074d84a5f 100644
--- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java
@@ -39,7 +39,6 @@ public class GZIPContentDecoder implements Destroyable
private final List _inflateds = new ArrayList<>();
private final ByteBufferPool _pool;
private final int _bufferSize;
- private final boolean _useDirectBuffers;
private InflaterPool.Entry _inflaterEntry;
private Inflater _inflater;
private State _state;
@@ -63,23 +62,12 @@ public class GZIPContentDecoder implements Destroyable
this(new InflaterPool(0, true), pool, bufferSize);
}
- public GZIPContentDecoder(ByteBufferPool pool, int bufferSize, boolean useDirectBuffers)
- {
- this(new InflaterPool(0, true), pool, bufferSize, useDirectBuffers);
- }
-
public GZIPContentDecoder(InflaterPool inflaterPool, ByteBufferPool pool, int bufferSize)
- {
- this(inflaterPool, pool, bufferSize, false);
- }
-
- public GZIPContentDecoder(InflaterPool inflaterPool, ByteBufferPool pool, int bufferSize, boolean useDirectBuffers)
{
_inflaterEntry = inflaterPool.acquire();
_inflater = _inflaterEntry.get();
_bufferSize = bufferSize;
_pool = pool;
- _useDirectBuffers = useDirectBuffers;
reset();
}
@@ -221,13 +209,6 @@ public class GZIPContentDecoder implements Destroyable
if (buffer == null)
buffer = acquire(_bufferSize);
- if (_inflater.needsInput())
- {
- if (!compressed.hasRemaining())
- return;
- _inflater.setInput(compressed);
- }
-
try
{
int pos = BufferUtil.flipToFill(buffer);
@@ -246,6 +227,12 @@ public class GZIPContentDecoder implements Destroyable
if (decodedChunk(chunk))
return;
}
+ else if (_inflater.needsInput())
+ {
+ if (!compressed.hasRemaining())
+ return;
+ _inflater.setInput(compressed);
+ }
else if (_inflater.finished())
{
_state = State.CRC;
@@ -269,7 +256,7 @@ public class GZIPContentDecoder implements Destroyable
{
case ID:
{
- _value += (currByte & 0xFFL) << (8 * _size);
+ _value += (currByte & 0xFF) << 8 * _size;
++_size;
if (_size == 2)
{
@@ -316,7 +303,7 @@ public class GZIPContentDecoder implements Destroyable
}
case EXTRA_LENGTH:
{
- _value += (currByte & 0xFFL) << (8 * _size);
+ _value += (currByte & 0xFF) << 8 * _size;
++_size;
if (_size == 2)
_state = State.EXTRA;
@@ -370,7 +357,7 @@ public class GZIPContentDecoder implements Destroyable
}
case CRC:
{
- _value += (currByte & 0xFFL) << (8 * _size);
+ _value += (currByte & 0xFF) << 8 * _size;
++_size;
if (_size == 4)
{
@@ -445,7 +432,7 @@ public class GZIPContentDecoder implements Destroyable
*/
public ByteBuffer acquire(int capacity)
{
- return _pool == null ? BufferUtil.allocate(capacity) : _pool.acquire(capacity, _useDirectBuffers);
+ return _pool == null ? BufferUtil.allocate(capacity) : _pool.acquire(capacity, false);
}
/**
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/Http10FieldPreEncoder.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/Http10FieldPreEncoder.java
new file mode 100644
index 00000000000..2dcbc83c769
--- /dev/null
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/Http10FieldPreEncoder.java
@@ -0,0 +1,26 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.http;
+
+/**
+ *
+ */
+public class Http10FieldPreEncoder extends Http1FieldPreEncoder
+{
+ @Override
+ public HttpVersion getHttpVersion()
+ {
+ return HttpVersion.HTTP_1_0;
+ }
+}
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/Http11FieldPreEncoder.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/Http11FieldPreEncoder.java
new file mode 100644
index 00000000000..c0d0cf6a117
--- /dev/null
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/Http11FieldPreEncoder.java
@@ -0,0 +1,26 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.http;
+
+/**
+ *
+ */
+public class Http11FieldPreEncoder extends Http1FieldPreEncoder
+{
+ @Override
+ public HttpVersion getHttpVersion()
+ {
+ return HttpVersion.HTTP_1_1;
+ }
+}
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/Http1FieldPreEncoder.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/Http1FieldPreEncoder.java
index 6d2ce95148d..9fc30dd88dd 100644
--- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/Http1FieldPreEncoder.java
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/Http1FieldPreEncoder.java
@@ -20,15 +20,8 @@ import static java.nio.charset.StandardCharsets.ISO_8859_1;
/**
*
*/
-public class Http1FieldPreEncoder implements HttpFieldPreEncoder
+public abstract class Http1FieldPreEncoder implements HttpFieldPreEncoder
{
-
- @Override
- public HttpVersion getHttpVersion()
- {
- return HttpVersion.HTTP_1_0;
- }
-
@Override
public byte[] getEncodedField(HttpHeader header, String headerString, String value)
{
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpContent.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpContent.java
index 14103bcb0d9..26ad161a7cf 100644
--- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpContent.java
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpContent.java
@@ -14,9 +14,8 @@
package org.eclipse.jetty.http;
import java.io.IOException;
-import java.io.InputStream;
import java.nio.ByteBuffer;
-import java.nio.channels.ReadableByteChannel;
+import java.nio.file.Path;
import java.util.Map;
import org.eclipse.jetty.http.MimeTypes.Type;
@@ -32,6 +31,8 @@ import org.eclipse.jetty.util.resource.Resource;
* reuse in from a cache).
*
*/
+// TODO also review metadata (like getContentLengthValue and getLastModifiedValue) to check if they can be removed as those
+// are available via the Path API
public interface HttpContent
{
HttpField getContentType();
@@ -58,29 +59,27 @@ public interface HttpContent
String getETagValue();
- ByteBuffer getIndirectBuffer();
-
- ByteBuffer getDirectBuffer();
+ // TODO rename?
+ Path getPath();
+ // TODO getPath() is supposed to replace the following
Resource getResource();
- InputStream getInputStream() throws IOException;
-
- ReadableByteChannel getReadableByteChannel() throws IOException;
-
- void release();
-
Map getPrecompressedContents();
- public interface ContentFactory
+ ByteBuffer getBuffer();
+
+ void release();
+
+ interface ContentFactory
{
/**
* @param path The path within the context to the resource
- * @param maxBuffer The maximum buffer to allocated for this request. For cached content, a larger buffer may have
- * previously been allocated and returned by the {@link HttpContent#getDirectBuffer()} or {@link HttpContent#getIndirectBuffer()} calls.
+ * @param maxBuffer The maximum buffer to allocated for this request.
* @return A {@link HttpContent}
* @throws IOException if unable to get content
*/
+ // TODO maxBuffer is not needed anymore
HttpContent getContent(String path, int maxBuffer) throws IOException;
}
}
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCookie.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCookie.java
index c8d0747436d..e49ff1b7f36 100644
--- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCookie.java
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCookie.java
@@ -23,7 +23,6 @@ import org.eclipse.jetty.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-// TODO consider replacing this with java.net.HttpCookie (once it supports RFC6265)
public class HttpCookie
{
private static final Logger LOG = LoggerFactory.getLogger(HttpCookie.class);
@@ -50,9 +49,11 @@ public class HttpCookie
public enum SameSite
{
- NONE("None"), STRICT("Strict"), LAX("Lax");
+ NONE("None"),
+ STRICT("Strict"),
+ LAX("Lax");
- private String attributeValue;
+ private final String attributeValue;
SameSite(String attributeValue)
{
@@ -486,6 +487,10 @@ public class HttpCookie
}
}
+ /**
+ * @deprecated We should not need to do this now
+ */
+ @Deprecated
public static String getCommentWithoutAttributes(String comment)
{
if (comment == null)
@@ -503,6 +508,10 @@ public class HttpCookie
return strippedComment.length() == 0 ? null : strippedComment;
}
+ /**
+ * @deprecated We should not need to do this now
+ */
+ @Deprecated
public static String getCommentWithAttributes(String comment, boolean httpOnly, SameSite sameSite)
{
if (comment == null && sameSite == null)
@@ -522,17 +531,10 @@ public class HttpCookie
{
switch (sameSite)
{
- case NONE:
- builder.append(SAME_SITE_NONE_COMMENT);
- break;
- case STRICT:
- builder.append(SAME_SITE_STRICT_COMMENT);
- break;
- case LAX:
- builder.append(SAME_SITE_LAX_COMMENT);
- break;
- default:
- throw new IllegalArgumentException(sameSite.toString());
+ case NONE -> builder.append(SAME_SITE_NONE_COMMENT);
+ case STRICT -> builder.append(SAME_SITE_STRICT_COMMENT);
+ case LAX -> builder.append(SAME_SITE_LAX_COMMENT);
+ default -> throw new IllegalArgumentException(sameSite.toString());
}
}
@@ -556,4 +558,34 @@ public class HttpCookie
return _cookie;
}
}
+
+ /**
+ * Check that samesite is set on the cookie. If not, use a
+ * context default value, if one has been set.
+ *
+ * @param cookie the cookie to check
+ * @param attributes the context to check settings
+ * @return either the original cookie, or a new one that has the samesit default set
+ */
+ public static HttpCookie checkSameSite(HttpCookie cookie, Attributes attributes)
+ {
+ if (cookie == null || cookie.getSameSite() != null)
+ return cookie;
+
+ //sameSite is not set, use the default configured for the context, if one exists
+ SameSite contextDefault = HttpCookie.getSameSiteDefault(attributes);
+ if (contextDefault == null)
+ return cookie; //no default set
+
+ return new HttpCookie(cookie.getName(),
+ cookie.getValue(),
+ cookie.getDomain(),
+ cookie.getPath(),
+ cookie.getMaxAge(),
+ cookie.isHttpOnly(),
+ cookie.isSecure(),
+ cookie.getComment(),
+ cookie.getVersion(),
+ contextDefault);
+ }
}
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpField.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpField.java
index b435d6268d1..09866c2fd26 100644
--- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpField.java
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpField.java
@@ -138,23 +138,37 @@ public class HttpField
* except if they are q=0, in which case the item itself is ignored.
*/
public boolean contains(String search)
+ {
+ return contains(_value, search);
+ }
+
+ /**
+ * Look for a value in a possible multi valued field
+ *
+ * @param value The field value to search in.
+ * @param search Values to search for (case insensitive)
+ * @return True iff the value is contained in the field value entirely or
+ * as an element of a quoted comma separated list. List element parameters (eg qualities) are ignored,
+ * except if they are q=0, in which case the item itself is ignored.
+ */
+ public static boolean contains(String value, String search)
{
if (search == null)
- return _value == null;
+ return value == null;
if (search.isEmpty())
return false;
- if (_value == null)
+ if (value == null)
return false;
- if (search.equalsIgnoreCase(_value))
+ if (search.equalsIgnoreCase(value))
return true;
int state = 0;
int match = 0;
int param = 0;
- for (int i = 0; i < _value.length(); i++)
+ for (int i = 0; i < value.length(); i++)
{
- char c = StringUtil.asciiToLowerCase(_value.charAt(i));
+ char c = StringUtil.asciiToLowerCase(value.charAt(i));
switch (state)
{
case 0: // initial white space
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java
index 3bb96ea6afd..e349a5cac31 100644
--- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java
@@ -25,52 +25,79 @@ import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
+import java.util.Spliterators;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
+import java.util.function.Function;
import java.util.function.ToIntFunction;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
/**
* Interface that represents on ordered collection of {@link HttpField}s.
- * Both {@link Mutable} and {@link Immutable} implementations are available
+ * Both {@link MutableHttpFields} and {@link ImmutableHttpFields} implementations are available
* via the static methods such as {@link #build()} and {@link #from(HttpField...)}.
+ * To implement this interface, only the {@link #iterator()} method
+ * need be implemented, however default implementations may be inefficient
*/
public interface HttpFields extends Iterable
{
+ HttpField EXPIRES_01JAN1970 = new PreEncodedHttpField(HttpHeader.EXPIRES, DateGenerator.__01Jan1970);
+ HttpField CONNECTION_CLOSE = new PreEncodedHttpField(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString());
+ HttpField CONNECTION_KEEPALIVE = new PreEncodedHttpField(HttpHeader.CONNECTION, HttpHeaderValue.KEEP_ALIVE.asString());
+
HttpFields EMPTY = build().asImmutable();
static Mutable build()
{
- return new Mutable();
+ return new MutableHttpFields();
}
static Mutable build(int capacity)
{
- return new Mutable(capacity);
+ return new MutableHttpFields(capacity);
}
static Mutable build(HttpFields fields)
{
- return new Mutable(fields);
+ return new MutableHttpFields(fields);
}
static Mutable build(HttpFields fields, HttpField replaceField)
{
- return new Mutable(fields, replaceField);
+ return new MutableHttpFields(fields, replaceField);
}
static Mutable build(HttpFields fields, EnumSet removeFields)
{
- return new Mutable(fields, removeFields);
+ return new MutableHttpFields(fields, removeFields);
}
- static Immutable from(HttpField... fields)
+ static ImmutableHttpFields from(HttpField... fields)
{
- return new Immutable(fields);
+ return new ImmutableHttpFields(fields);
}
- Immutable asImmutable();
+ static ImmutableHttpFields from(HttpFields fields, Function mutation)
+ {
+ return new ImmutableHttpFields(fields.stream().map(mutation).filter(Objects::nonNull).toArray(HttpField[]::new));
+ }
+
+ default HttpFields asImmutable()
+ {
+ return HttpFields.build(this).asImmutable();
+ }
+
+ /**
+ * Efficiently take the fields as an Immutable that cannot be changed by any further mutations
+ * to this instance.
+ * @return An immutable version of the fields.
+ */
+ default HttpFields takeAsImmutable()
+ {
+ return HttpFields.build(this).takeAsImmutable();
+ }
default String asString()
{
@@ -228,7 +255,23 @@ public interface HttpFields extends Iterable
*/
default long getDateField(String name)
{
- HttpField field = getField(name);
+ return parseDateField(getField(name));
+ }
+
+ /**
+ * Get a header as a date value. Returns the value of a date field, or -1 if not found. The case
+ * of the field name is ignored.
+ *
+ * @param header the header
+ * @return the value of the field as a number of milliseconds since unix epoch
+ */
+ default long getDateField(HttpHeader header)
+ {
+ return parseDateField(getField(header));
+ }
+
+ static long parseDateField(HttpField field)
+ {
if (field == null)
return -1;
@@ -248,7 +291,16 @@ public interface HttpFields extends Iterable
* @param index the field index
* @return A Field value or null if the Field value has not been set
*/
- HttpField getField(int index);
+ default HttpField getField(int index)
+ {
+ int i = 0;
+ for (HttpField f: this)
+ {
+ if (i++ == index)
+ return f;
+ }
+ return null;
+ }
default HttpField getField(HttpHeader header)
{
@@ -275,7 +327,9 @@ public interface HttpFields extends Iterable
* _names for this request.
*
* @return an enumeration of field names
+ * @deprecated use {@link #getFieldNamesCollection()}
*/
+ @Deprecated
default Enumeration getFieldNames()
{
return Collections.enumeration(getFieldNamesCollection());
@@ -494,96 +548,27 @@ public interface HttpFields extends Iterable
return !i.hasNext();
}
- int size();
+ default int size()
+ {
+ int s = 0;
+ for (HttpField f : this)
+ s++;
+ return s;
+ }
- Stream stream();
+ default Stream stream()
+ {
+ return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator(), 0), false);
+ }
/**
- * HTTP Fields. A collection of HTTP header and or Trailer fields.
- *
- *
This class is not synchronized as it is expected that modifications will only be performed by a
- * single thread.
- *
- *
The cookie handling provided by this class is guided by the Servlet specification and RFC6265.
+ * A mutable HttpFields interface.
+ * To implement this interface, only the {@link #listIterator()}
+ * method needs to be implemented, however default implementations
+ * may not be efficient.
*/
- class Mutable implements Iterable, HttpFields
+ interface Mutable extends Iterable, HttpFields
{
- private HttpField[] _fields;
- private int _size;
-
- /**
- * Initialize an empty HttpFields.
- */
- protected Mutable()
- {
- this(16); // Based on small sample of Chrome requests.
- }
-
- /**
- * Initialize an empty HttpFields.
- *
- * @param capacity the capacity of the http fields
- */
- Mutable(int capacity)
- {
- _fields = new HttpField[capacity];
- }
-
- /**
- * Initialize HttpFields from another.
- *
- * @param fields the fields to copy data from
- */
- Mutable(HttpFields fields)
- {
- add(fields);
- }
-
- /**
- * Initialize HttpFields from another and replace a field
- *
- * @param fields the fields to copy data from
- * @param replaceField the replacement field
- */
- Mutable(HttpFields fields, HttpField replaceField)
- {
- _fields = new HttpField[fields.size() + 4];
- _size = 0;
- boolean put = false;
- for (HttpField f : fields)
- {
- if (replaceField.isSameName(f))
- {
- if (!put)
- _fields[_size++] = replaceField;
- put = true;
- }
- else
- {
- _fields[_size++] = f;
- }
- }
- if (!put)
- _fields[_size++] = replaceField;
- }
-
- /**
- * Initialize HttpFields from another and remove fields
- *
- * @param fields the fields to copy data from
- * @param removeFields the the fields to remove
- */
- Mutable(HttpFields fields, EnumSet removeFields)
- {
- _fields = new HttpField[fields.size() + 4];
- _size = 0;
- for (HttpField f : fields)
- {
- if (f.getHeader() == null || !removeFields.contains(f.getHeader()))
- _fields[_size++] = f;
- }
- }
-
/**
* Add to or set a field. If the field is allowed to have multiple values, add will add multiple
* headers of the same name.
@@ -592,14 +577,14 @@ public interface HttpFields extends Iterable
* @param value the value of the field.
* @return this builder
*/
- public Mutable add(String name, String value)
+ default Mutable add(String name, String value)
{
if (value != null)
return add(new HttpField(name, value));
return this;
}
- public Mutable add(HttpHeader header, HttpHeaderValue value)
+ default Mutable add(HttpHeader header, HttpHeaderValue value)
{
return add(header, value.toString());
}
@@ -612,7 +597,7 @@ public interface HttpFields extends Iterable
* @param value the value of the field.
* @return this builder
*/
- public Mutable add(HttpHeader header, String value)
+ default Mutable add(HttpHeader header, String value)
{
if (value == null)
throw new IllegalArgumentException("null value");
@@ -621,44 +606,19 @@ public interface HttpFields extends Iterable
return add(field);
}
- public Mutable add(HttpField field)
+ default Mutable add(HttpField field)
{
- if (field != null)
- {
- if (_size == _fields.length)
- _fields = Arrays.copyOf(_fields, _size * 2);
- _fields[_size++] = field;
- }
+ ListIterator i = listIterator();
+ while (i.hasNext())
+ i.next();
+ i.add(field);
return this;
}
- public Mutable add(HttpFields fields)
+ default Mutable add(HttpFields fields)
{
- if (_fields == null)
- _fields = new HttpField[fields.size() + 4];
- else if (_size + fields.size() >= _fields.length)
- _fields = Arrays.copyOf(_fields, _size + fields.size() + 4);
-
- if (fields.size() == 0)
- return this;
-
- if (fields instanceof Immutable)
- {
- Immutable b = (Immutable)fields;
- System.arraycopy(b._fields, 0, _fields, _size, b._fields.length);
- _size += b._fields.length;
- }
- else if (fields instanceof Mutable)
- {
- Mutable b = (Mutable)fields;
- System.arraycopy(b._fields, 0, _fields, _size, b._size);
- _size += b._size;
- }
- else
- {
- for (HttpField f : fields)
- _fields[_size++] = f;
- }
+ for (HttpField field : fields)
+ add(field);
return this;
}
@@ -670,7 +630,7 @@ public interface HttpFields extends Iterable
* @param values The value(s) to add
* @return this builder
*/
- public Mutable addCSV(HttpHeader header, String... values)
+ default Mutable addCSV(HttpHeader header, String... values)
{
QuotedCSV existing = null;
for (HttpField f : this)
@@ -696,7 +656,7 @@ public interface HttpFields extends Iterable
* @param values The value(s) to add
* @return this builder
*/
- public Mutable addCSV(String name, String... values)
+ default Mutable addCSV(String name, String... values)
{
QuotedCSV existing = null;
for (HttpField f : this)
@@ -721,33 +681,33 @@ public interface HttpFields extends Iterable
* @param date the field date value
* @return this builder
*/
- public Mutable addDateField(String name, long date)
+ default Mutable addDateField(String name, long date)
{
add(name, DateGenerator.formatDate(date));
return this;
}
- @Override
- public Immutable asImmutable()
+ default Mutable clear()
{
- return new Immutable(Arrays.copyOf(_fields, _size));
- }
-
- public Mutable clear()
- {
- _size = 0;
+ for (ListIterator i = listIterator(); i.hasNext(); )
+ {
+ i.next();
+ i.remove();
+ }
return this;
}
- /** Ensure that specific HttpField exists when the field may not exist or may
+ /**
+ * Ensure that specific HttpField exists when the field may not exist or may
* exist and be multi valued. Multiple existing fields are merged into a
* single field.
+ *
* @param field The header to ensure is contained. The field is used
- * directly if possible so {@link PreEncodedHttpField}s can be
- * passed. If the value needs to be merged with existing values,
- * then a new field is created.
+ * directly if possible so {@link PreEncodedHttpField}s can be
+ * passed. If the value needs to be merged with existing values,
+ * then a new field is created.
*/
- public void ensureField(HttpField field)
+ default void ensureField(HttpField field)
{
// Is the field value multi valued?
if (field.getValue().indexOf(',') < 0)
@@ -768,212 +728,27 @@ public interface HttpFields extends Iterable
}
}
- /**
- * Compute ensure field with a single value
- * @param ensure The field to ensure exists
- * @param fields The list of existing fields with the same header
- */
- private static HttpField computeEnsure(HttpField ensure, List fields)
- {
- // If no existing fields return the ensure field
- if (fields == null || fields.isEmpty())
- return ensure;
-
- String ensureValue = ensure.getValue();
-
- // Handle a single existing field
- if (fields.size() == 1)
- {
- // If the existing field contains the ensure value, return it, else append values.
- HttpField f = fields.get(0);
- return f.contains(ensureValue)
- ? f
- : new HttpField(ensure.getHeader(), ensure.getName(), f.getValue() + ", " + ensureValue);
- }
-
- // Handle multiple existing fields
- StringBuilder v = new StringBuilder();
- for (HttpField f : fields)
- {
- // Always append multiple fields into a single field value
- if (v.length() > 0)
- v.append(", ");
- v.append(f.getValue());
-
- // check if the ensure value is already contained
- if (ensureValue != null && f.contains(ensureValue))
- ensureValue = null;
- }
-
- // If the ensure value was not contained append it
- if (ensureValue != null)
- v.append(", ").append(ensureValue);
-
- return new HttpField(ensure.getHeader(), ensure.getName(), v.toString());
- }
-
- /**
- * Compute ensure field with a multiple values
- * @param ensure The field to ensure exists
- * @param values The QuotedCSV parsed field values.
- * @param fields The list of existing fields with the same header
- */
- private static HttpField computeEnsure(HttpField ensure, String[] values, List fields)
- {
- // If no existing fields return the ensure field
- if (fields == null || fields.isEmpty())
- return ensure;
-
- // Handle a single existing field
- if (fields.size() == 1)
- {
- HttpField f = fields.get(0);
- // check which ensured values are already contained
- int ensured = values.length;
- for (int i = 0; i < values.length; i++)
- {
- if (f.contains(values[i]))
- {
- ensured--;
- values[i] = null;
- }
- }
-
- // if all ensured values contained return the existing field
- if (ensured == 0)
- return f;
- // else if no ensured values contained append the entire ensured valued
- if (ensured == values.length)
- return new HttpField(ensure.getHeader(), ensure.getName(),
- f.getValue() + ", " + ensure.getValue());
- // else append just the ensured values that are not contained
- StringBuilder v = new StringBuilder(f.getValue());
- for (String value : values)
- {
- if (value != null)
- v.append(", ").append(value);
- }
- return new HttpField(ensure.getHeader(), ensure.getName(), v.toString());
- }
-
- // Handle a multiple existing field
- StringBuilder v = new StringBuilder();
- int ensured = values.length;
- for (HttpField f : fields)
- {
- // Always append multiple fields into a single field value
- if (v.length() > 0)
- v.append(", ");
- v.append(f.getValue());
-
- // null out ensured values that are included
- for (int i = 0; i < values.length; i++)
- {
- if (values[i] != null && f.contains(values[i]))
- {
- ensured--;
- values[i] = null;
- }
- }
- }
-
- // if no ensured values exist append them all
- if (ensured == values.length)
- v.append(", ").append(ensure.getValue());
- // else if some ensured values are missing, append them
- else if (ensured > 0)
- {
- for (String value : values)
- if (value != null)
- v.append(", ").append(value);
- }
-
- // return a merged header with missing ensured values added
- return new HttpField(ensure.getHeader(), ensure.getName(), v.toString());
- }
-
@Override
- public boolean equals(Object o)
+ default Iterator iterator()
{
- if (this == o)
- return true;
- if (!(o instanceof Mutable))
- return false;
-
- return isEqualTo((HttpFields)o);
+ return listIterator();
}
- /**
- * Get a Field by index.
- *
- * @param index the field index
- * @return A Field value or null if the Field value has not been set
- */
- @Override
- public HttpField getField(int index)
- {
- if (index >= _size || index < 0)
- throw new NoSuchElementException();
- return _fields[index];
- }
+ ListIterator listIterator();
- @Override
- public int hashCode()
- {
- int hash = 0;
- for (int i = _fields.length; i-- > 0; )
- hash ^= _fields[i].hashCode();
- return hash;
- }
-
- @Override
- public Iterator iterator()
- {
- return new Iterator<>()
- {
- int _index = 0;
-
- @Override
- public boolean hasNext()
- {
- return _index < _size;
- }
-
- @Override
- public HttpField next()
- {
- return _fields[_index++];
- }
-
- @Override
- public void remove()
- {
- if (_size == 0)
- throw new IllegalStateException();
- Mutable.this.remove(--_index);
- }
- };
- }
-
- public ListIterator listIterator()
- {
- return new ListItr();
- }
-
- public Mutable put(HttpField field)
+ default Mutable put(HttpField field)
{
boolean put = false;
-
- for (int i = 0; i < _size; i++)
+ for (ListIterator i = listIterator(); i.hasNext(); )
{
- HttpField f = _fields[i];
+ HttpField f = i.next();
if (f.isSameName(field))
{
if (put)
- System.arraycopy(_fields, i + 1, _fields, i, _size-- - i-- - 1);
+ i.remove();
else
{
- _fields[i] = field;
+ i.set(field);
put = true;
}
}
@@ -990,16 +765,18 @@ public interface HttpFields extends Iterable
* @param value the value of the field. If null the field is cleared.
* @return this builder
*/
- public Mutable put(String name, String value)
+ default Mutable put(String name, String value)
{
- return (value == null)
- ? remove(name)
- : put(new HttpField(name, value));
+ if (value == null)
+ return remove(name);
+ return put(new HttpField(name, value));
}
- public Mutable put(HttpHeader header, HttpHeaderValue value)
+ default Mutable put(HttpHeader header, HttpHeaderValue value)
{
- return put(header, value.toString());
+ if (value == null)
+ return remove(header);
+ return put(new HttpField(header, value.toString()));
}
/**
@@ -1009,11 +786,11 @@ public interface HttpFields extends Iterable
* @param value the value of the field. If null the field is cleared.
* @return this builder
*/
- public Mutable put(HttpHeader header, String value)
+ default Mutable put(HttpHeader header, String value)
{
- return (value == null)
- ? remove(header)
- : put(new HttpField(header, value));
+ if (value == null)
+ return remove(header);
+ return put(new HttpField(header, value));
}
/**
@@ -1023,15 +800,19 @@ public interface HttpFields extends Iterable
* @param list the List value of the field. If null the field is cleared.
* @return this builder
*/
- public Mutable put(String name, List list)
+ default Mutable put(String name, List list)
{
- Objects.requireNonNull(name, "name must not be null");
- Objects.requireNonNull(list, "list must not be null");
- remove(name);
- for (String v : list)
+ Objects.requireNonNull(name);
+ Objects.requireNonNull(list);
+ boolean first = true;
+ for (String s : list)
{
- if (v != null)
- add(name, v);
+ HttpField field = new HttpField(name, s);
+ if (first)
+ put(field);
+ else
+ add(field);
+ first = false;
}
return this;
}
@@ -1043,7 +824,7 @@ public interface HttpFields extends Iterable
* @param date the field date value
* @return this builder
*/
- public Mutable putDateField(HttpHeader name, long date)
+ default Mutable putDateField(HttpHeader name, long date)
{
return put(name, DateGenerator.formatDate(date));
}
@@ -1055,7 +836,7 @@ public interface HttpFields extends Iterable
* @param date the field date value
* @return this builder
*/
- public Mutable putDateField(String name, long date)
+ default Mutable putDateField(String name, long date)
{
return put(name, DateGenerator.formatDate(date));
}
@@ -1067,9 +848,9 @@ public interface HttpFields extends Iterable
* @param value the field long value
* @return this builder
*/
- public Mutable putLongField(HttpHeader name, long value)
+ default Mutable putLongField(HttpHeader name, long value)
{
- return put(name, Long.toString(value));
+ return put(new HttpField.LongValueHttpField(name, value));
}
/**
@@ -1079,7 +860,7 @@ public interface HttpFields extends Iterable
* @param value the field long value
* @return this builder
*/
- public Mutable putLongField(String name, long value)
+ default Mutable putLongField(String name, long value)
{
return put(name, Long.toString(value));
}
@@ -1159,9 +940,9 @@ public interface HttpFields extends Iterable
* @param header the HTTP header
* @param computeFn the compute function
*/
- public void computeField(HttpHeader header, BiFunction, HttpField> computeFn)
+ default void computeField(HttpHeader header, BiFunction, HttpField> computeFn)
{
- computeField(header, computeFn, (f, h) -> f.getHeader() == h);
+ put(computeFn.apply(header, stream().filter(f -> f.getHeader() == header).collect(Collectors.toList())));
}
/**
@@ -1171,12 +952,516 @@ public interface HttpFields extends Iterable
* @param computeFn the compute function
* @see #computeField(HttpHeader, BiFunction)
*/
+ default void computeField(String name, BiFunction, HttpField> computeFn)
+ {
+ put(computeFn.apply(name, stream().filter(f -> f.is(name)).collect(Collectors.toList())));
+ }
+
+ /**
+ * Remove a field.
+ *
+ * @param header the field to remove
+ * @return this builder
+ */
+ default Mutable remove(HttpHeader header)
+ {
+ for (ListIterator i = listIterator(); i.hasNext();)
+ {
+ HttpField f = i.next();
+ if (f.getHeader() == header)
+ i.remove();
+ }
+ return this;
+ }
+
+ default Mutable remove(EnumSet fields)
+ {
+ for (ListIterator i = listIterator(); i.hasNext();)
+ {
+ HttpField f = i.next();
+ HttpHeader h = f.getHeader();
+ if (h != null && fields.contains(h))
+ i.remove();
+ }
+ return this;
+ }
+
+ /**
+ * Remove a field.
+ *
+ * @param name the field to remove
+ * @return this builder
+ */
+ default Mutable remove(String name)
+ {
+ for (ListIterator i = listIterator(); i.hasNext();)
+ {
+ HttpField f = i.next();
+ if (f.is(name))
+ i.remove();
+ }
+ return this;
+ }
+
+ static String formatCsvExcludingExisting(QuotedCSV existing, String... values)
+ {
+ // remove any existing values from the new values
+ boolean add = true;
+ if (existing != null && !existing.isEmpty())
+ {
+ add = false;
+
+ for (int i = values.length; i-- > 0; )
+ {
+ String unquoted = QuotedCSV.unquote(values[i]);
+ if (existing.getValues().contains(unquoted))
+ values[i] = null;
+ else
+ add = true;
+ }
+ }
+
+ if (add)
+ {
+ StringBuilder value = new StringBuilder();
+ for (String v : values)
+ {
+ if (v == null)
+ continue;
+ if (value.length() > 0)
+ value.append(", ");
+ value.append(v);
+ }
+ if (value.length() > 0)
+ return value.toString();
+ }
+
+ return null;
+ }
+
+ /**
+ * Compute ensure field with a single value
+ * @param ensure The field to ensure exists
+ * @param fields The list of existing fields with the same header
+ */
+ static HttpField computeEnsure(HttpField ensure, List fields)
+ {
+ // If no existing fields return the ensure field
+ if (fields == null || fields.isEmpty())
+ return ensure;
+
+ String ensureValue = ensure.getValue();
+
+ // Handle a single existing field
+ if (fields.size() == 1)
+ {
+ // If the existing field contains the ensure value, return it, else append values.
+ HttpField f = fields.get(0);
+ return f.contains(ensureValue)
+ ? f
+ : new HttpField(ensure.getHeader(), ensure.getName(), f.getValue() + ", " + ensureValue);
+ }
+
+ // Handle multiple existing fields
+ StringBuilder v = new StringBuilder();
+ for (HttpField f : fields)
+ {
+ // Always append multiple fields into a single field value
+ if (v.length() > 0)
+ v.append(", ");
+ v.append(f.getValue());
+
+ // check if the ensure value is already contained
+ if (ensureValue != null && f.contains(ensureValue))
+ ensureValue = null;
+ }
+
+ // If the ensure value was not contained append it
+ if (ensureValue != null)
+ v.append(", ").append(ensureValue);
+
+ return new HttpField(ensure.getHeader(), ensure.getName(), v.toString());
+ }
+
+ /**
+ * Compute ensure field with a multiple values
+ * @param ensure The field to ensure exists
+ * @param values The QuotedCSV parsed field values.
+ * @param fields The list of existing fields with the same header
+ */
+ static HttpField computeEnsure(HttpField ensure, String[] values, List fields)
+ {
+ // If no existing fields return the ensure field
+ if (fields == null || fields.isEmpty())
+ return ensure;
+
+ // Handle a single existing field
+ if (fields.size() == 1)
+ {
+ HttpField f = fields.get(0);
+ // check which ensured values are already contained
+ int ensured = values.length;
+ for (int i = 0; i < values.length; i++)
+ {
+ if (f.contains(values[i]))
+ {
+ ensured--;
+ values[i] = null;
+ }
+ }
+
+ // if all ensured values contained return the existing field
+ if (ensured == 0)
+ return f;
+ // else if no ensured values contained append the entire ensured valued
+ if (ensured == values.length)
+ return new HttpField(ensure.getHeader(), ensure.getName(),
+ f.getValue() + ", " + ensure.getValue());
+ // else append just the ensured values that are not contained
+ StringBuilder v = new StringBuilder(f.getValue());
+ for (String value : values)
+ {
+ if (value != null)
+ v.append(", ").append(value);
+ }
+ return new HttpField(ensure.getHeader(), ensure.getName(), v.toString());
+ }
+
+ // Handle a multiple existing field
+ StringBuilder v = new StringBuilder();
+ int ensured = values.length;
+ for (HttpField f : fields)
+ {
+ // Always append multiple fields into a single field value
+ if (v.length() > 0)
+ v.append(", ");
+ v.append(f.getValue());
+
+ // null out ensured values that are included
+ for (int i = 0; i < values.length; i++)
+ {
+ if (values[i] != null && f.contains(values[i]))
+ {
+ ensured--;
+ values[i] = null;
+ }
+ }
+ }
+
+ // if no ensured values exist append them all
+ if (ensured == values.length)
+ v.append(", ").append(ensure.getValue());
+ // else if some ensured values are missing, append them
+ else if (ensured > 0)
+ {
+ for (String value : values)
+ if (value != null)
+ v.append(", ").append(value);
+ }
+
+ // return a merged header with missing ensured values added
+ return new HttpField(ensure.getHeader(), ensure.getName(), v.toString());
+ }
+ }
+
+ /**
+ * HTTP Fields. A collection of HTTP header and or Trailer fields.
+ *
+ *
This class is not synchronized as it is expected that modifications will only be performed by a
+ * single thread.
+ *
+ *
The cookie handling provided by this class is guided by the Servlet specification and RFC6265.
+ */
+ class MutableHttpFields implements Mutable
+ {
+ private static final int INITIAL_SIZE = 16;
+ private static final int SIZE_INCREMENT = 4;
+
+ private HttpField[] _fields;
+ private int _size;
+
+ /**
+ * Initialize an empty HttpFields.
+ */
+ protected MutableHttpFields()
+ {
+ this(INITIAL_SIZE); // Based on small sample of Chrome requests.
+ }
+
+ /**
+ * Initialize an empty HttpFields.
+ *
+ * @param capacity the capacity of the http fields
+ */
+ protected MutableHttpFields(int capacity)
+ {
+ _fields = new HttpField[capacity];
+ }
+
+ /**
+ * Initialize HttpFields from another.
+ *
+ * @param fields the fields to copy data from
+ */
+ protected MutableHttpFields(HttpFields fields)
+ {
+ add(fields);
+ }
+
+ /**
+ * Initialize HttpFields from another and replace a field
+ *
+ * @param fields the fields to copy data from
+ * @param replaceField the replacement field
+ */
+ protected MutableHttpFields(HttpFields fields, HttpField replaceField)
+ {
+ _fields = new HttpField[fields.size() + SIZE_INCREMENT];
+ _size = 0;
+ boolean put = false;
+ for (HttpField f : fields)
+ {
+ if (replaceField.isSameName(f))
+ {
+ if (!put)
+ _fields[_size++] = replaceField;
+ put = true;
+ }
+ else
+ {
+ _fields[_size++] = f;
+ }
+ }
+ if (!put)
+ _fields[_size++] = replaceField;
+ }
+
+ /**
+ * Initialize HttpFields from another and remove fields
+ *
+ * @param fields the fields to copy data from
+ * @param removeFields the the fields to remove
+ */
+ protected MutableHttpFields(HttpFields fields, EnumSet removeFields)
+ {
+ _fields = new HttpField[fields.size() + SIZE_INCREMENT];
+ _size = 0;
+ for (HttpField f : fields)
+ {
+ if (f.getHeader() == null || !removeFields.contains(f.getHeader()))
+ _fields[_size++] = f;
+ }
+ }
+
+ @Override
+ public Mutable add(HttpField field)
+ {
+ if (field != null)
+ {
+ if (_fields == null)
+ _fields = new HttpField[INITIAL_SIZE];
+ if (_size == _fields.length)
+ _fields = Arrays.copyOf(_fields, _size + SIZE_INCREMENT);
+ _fields[_size++] = field;
+ }
+ return this;
+ }
+
+ @Override
+ public Mutable add(HttpFields fields)
+ {
+ if (_fields == null)
+ _fields = new HttpField[fields.size() + SIZE_INCREMENT];
+ else if (_size + fields.size() >= _fields.length)
+ _fields = Arrays.copyOf(_fields, _size + fields.size() + SIZE_INCREMENT);
+
+ if (fields.size() == 0)
+ return this;
+
+ if (fields instanceof ImmutableHttpFields immutable)
+ {
+ System.arraycopy(immutable._fields, 0, _fields, _size, immutable._size);
+ _size += immutable._size;
+ }
+ else if (fields instanceof MutableHttpFields mutable)
+ {
+ System.arraycopy(mutable._fields, 0, _fields, _size, mutable._size);
+ _size += mutable._size;
+ }
+ else
+ {
+ for (HttpField f : fields)
+ _fields[_size++] = f;
+ }
+ return this;
+ }
+
+ @Override
+ public HttpFields asImmutable()
+ {
+ return new ImmutableHttpFields(Arrays.copyOf(_fields, _size));
+ }
+
+ @Override
+ public HttpFields takeAsImmutable()
+ {
+ HttpField[] fields = _fields == null ? new HttpField[0] : _fields;
+ int size = _size;
+ _fields = null;
+ _size = 0;
+
+ return new ImmutableHttpFields(fields, size);
+ }
+
+ @Override
+ public Mutable clear()
+ {
+ _size = 0;
+ return this;
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (this == o)
+ return true;
+ if (!(o instanceof MutableHttpFields))
+ return false;
+
+ return isEqualTo((HttpFields)o);
+ }
+
+ /**
+ * Get a Field by index.
+ *
+ * @param index the field index
+ * @return A Field value or null if the Field value has not been set
+ */
+ @Override
+ public HttpField getField(int index)
+ {
+ if (index >= _size || index < 0)
+ throw new NoSuchElementException();
+ return _fields[index];
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = 0;
+ for (int i = _fields.length; i-- > 0; )
+ hash ^= _fields[i].hashCode();
+ return hash;
+ }
+
+ @Override
+ public Iterator iterator()
+ {
+ return new Iterator<>()
+ {
+ int _index = 0;
+
+ @Override
+ public boolean hasNext()
+ {
+ return _index < _size;
+ }
+
+ @Override
+ public HttpField next()
+ {
+ return _fields[_index++];
+ }
+
+ @Override
+ public void remove()
+ {
+ if (_size == 0)
+ throw new IllegalStateException();
+ MutableHttpFields.this.remove(--_index);
+ }
+ };
+ }
+
+ @Override
+ public ListIterator listIterator()
+ {
+ return new ListItr();
+ }
+
+ @Override
+ public Mutable put(HttpField field)
+ {
+ boolean put = false;
+
+ for (int i = 0; i < _size; i++)
+ {
+ HttpField f = _fields[i];
+ if (f.isSameName(field))
+ {
+ if (put)
+ System.arraycopy(_fields, i + 1, _fields, i, _size-- - i-- - 1);
+ else
+ {
+ _fields[i] = field;
+ put = true;
+ }
+ }
+ }
+ if (!put)
+ add(field);
+ return this;
+ }
+
+ @Override
+ public Mutable put(String name, String value)
+ {
+ return (value == null)
+ ? remove(name)
+ : put(new HttpField(name, value));
+ }
+
+ @Override
+ public Mutable put(HttpHeader header, HttpHeaderValue value)
+ {
+ return put(header, value.toString());
+ }
+
+ @Override
+ public Mutable put(HttpHeader header, String value)
+ {
+ return (value == null)
+ ? remove(header)
+ : put(new HttpField(header, value));
+ }
+
+ @Override
+ public Mutable put(String name, List list)
+ {
+ Objects.requireNonNull(name);
+ Objects.requireNonNull(list);
+ remove(name);
+ for (String v : list)
+ {
+ if (v != null)
+ add(name, v);
+ }
+ return this;
+ }
+
+ @Override
+ public void computeField(HttpHeader header, BiFunction, HttpField> computeFn)
+ {
+ computeField(header, computeFn, (f, h) -> f.getHeader() == h);
+ }
+
+ @Override
public void computeField(String name, BiFunction, HttpField> computeFn)
{
computeField(name, computeFn, HttpField::is);
}
- private void computeField(T header, BiFunction, HttpField> computeFn, BiPredicate matcher)
+ public void computeField(T header, BiFunction, HttpField> computeFn, BiPredicate matcher)
{
// Look for first occurrence
int first = -1;
@@ -1230,12 +1515,7 @@ public interface HttpFields extends Iterable
_fields[first] = newField;
}
- /**
- * Remove a field.
- *
- * @param name the field to remove
- * @return this builder
- */
+ @Override
public Mutable remove(HttpHeader name)
{
for (int i = 0; i < _size; i++)
@@ -1247,6 +1527,7 @@ public interface HttpFields extends Iterable
return this;
}
+ @Override
public Mutable remove(EnumSet fields)
{
for (int i = 0; i < _size; i++)
@@ -1258,12 +1539,7 @@ public interface HttpFields extends Iterable
return this;
}
- /**
- * Remove a field.
- *
- * @param name the field to remove
- * @return this builder
- */
+ @Override
public Mutable remove(String name)
{
for (int i = 0; i < _size; i++)
@@ -1299,42 +1575,6 @@ public interface HttpFields extends Iterable
return asString();
}
- private String formatCsvExcludingExisting(QuotedCSV existing, String... values)
- {
- // remove any existing values from the new values
- boolean add = true;
- if (existing != null && !existing.isEmpty())
- {
- add = false;
-
- for (int i = values.length; i-- > 0; )
- {
- String unquoted = QuotedCSV.unquote(values[i]);
- if (existing.getValues().contains(unquoted))
- values[i] = null;
- else
- add = true;
- }
- }
-
- if (add)
- {
- StringBuilder value = new StringBuilder();
- for (String v : values)
- {
- if (v == null)
- continue;
- if (value.length() > 0)
- value.append(", ");
- value.append(v);
- }
- if (value.length() > 0)
- return value.toString();
- }
-
- return null;
- }
-
private class ListItr implements ListIterator
{
int _cursor; // index of next element to return
@@ -1346,8 +1586,10 @@ public interface HttpFields extends Iterable
if (field == null)
return;
- _fields = Arrays.copyOf(_fields, _fields.length + 1);
- System.arraycopy(_fields, _cursor, _fields, _cursor + 1, _size++);
+ int last = _size++;
+ if (_fields.length < _size)
+ _fields = Arrays.copyOf(_fields, _fields.length + SIZE_INCREMENT);
+ System.arraycopy(_fields, _cursor, _fields, _cursor + 1, last - _cursor);
_fields[_cursor++] = field;
_current = -1;
}
@@ -1399,7 +1641,7 @@ public interface HttpFields extends Iterable
{
if (_current < 0)
throw new IllegalStateException();
- Mutable.this.remove(_current);
+ MutableHttpFields.this.remove(_current);
_cursor = _current;
_current = -1;
}
@@ -1425,22 +1667,36 @@ public interface HttpFields extends Iterable
*
*
The cookie handling provided by this class is guided by the Servlet specification and RFC6265.
*/
- class Immutable implements HttpFields
+ class ImmutableHttpFields implements HttpFields
{
final HttpField[] _fields;
+ final int _size;
/**
* Initialize HttpFields from copy.
*
* @param fields the fields to copy data from
*/
- public Immutable(HttpField[] fields)
+ protected ImmutableHttpFields(HttpField[] fields)
{
+ this(fields, fields.length);
+ }
+
+ protected ImmutableHttpFields(HttpField[] fields, int size)
+ {
+ Objects.requireNonNull(fields);
_fields = fields;
+ _size = size;
}
@Override
- public Immutable asImmutable()
+ public HttpFields asImmutable()
+ {
+ return this;
+ }
+
+ @Override
+ public HttpFields takeAsImmutable()
{
return this;
}
@@ -1450,7 +1706,7 @@ public interface HttpFields extends Iterable
{
if (this == o)
return true;
- if (!(o instanceof Immutable))
+ if (!(o instanceof ImmutableHttpFields))
return false;
return isEqualTo((HttpFields)o);
@@ -1461,7 +1717,7 @@ public interface HttpFields extends Iterable
{
// default impl overridden for efficiency
for (HttpField f : _fields)
- if (f.is(header))
+ if (f != null && f.is(header))
return f.getValue();
return null;
}
@@ -1471,7 +1727,7 @@ public interface HttpFields extends Iterable
{
// default impl overridden for efficiency
for (HttpField f : _fields)
- if (f.getHeader() == header)
+ if (f != null && f.getHeader() == header)
return f.getValue();
return null;
}
@@ -1481,7 +1737,7 @@ public interface HttpFields extends Iterable
{
// default impl overridden for efficiency
for (HttpField f : _fields)
- if (f.getHeader() == header)
+ if (f != null && f.getHeader() == header)
return f;
return null;
}
@@ -1491,7 +1747,7 @@ public interface HttpFields extends Iterable
{
// default impl overridden for efficiency
for (HttpField f : _fields)
- if (f.is(name))
+ if (f != null && f.is(name))
return f;
return null;
}
@@ -1523,7 +1779,7 @@ public interface HttpFields extends Iterable
@Override
public boolean hasNext()
{
- return _index < _fields.length;
+ return _index < _size;
}
@Override
@@ -1537,13 +1793,13 @@ public interface HttpFields extends Iterable
@Override
public int size()
{
- return _fields.length;
+ return _size;
}
@Override
public Stream stream()
{
- return Arrays.stream(_fields);
+ return Arrays.stream(_fields).filter(Objects::nonNull);
}
@Override
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java
index 8a4b3ebab79..1adf5ef52e0 100644
--- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java
@@ -47,7 +47,7 @@ public class HttpGenerator
public static final MetaData.Response CONTINUE_100_INFO = new MetaData.Response(HttpVersion.HTTP_1_1, 100, null, null, -1);
public static final MetaData.Response PROGRESS_102_INFO = new MetaData.Response(HttpVersion.HTTP_1_1, 102, null, null, -1);
public static final MetaData.Response RESPONSE_500_INFO =
- new MetaData.Response(HttpVersion.HTTP_1_1, INTERNAL_SERVER_ERROR_500, null, HttpFields.build().put(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE), 0);
+ new MetaData.Response(HttpVersion.HTTP_1_1, INTERNAL_SERVER_ERROR_500, null, HttpFields.build().add(HttpFields.CONNECTION_CLOSE), 0);
// states
public enum State
@@ -171,6 +171,14 @@ public class HttpGenerator
return Boolean.TRUE.equals(_persistent);
}
+ /**
+ * @return true if known to be persistent
+ */
+ public boolean isPersistent(HttpVersion version)
+ {
+ return version == HttpVersion.HTTP_1_1 ? !Boolean.FALSE.equals(_persistent) : Boolean.TRUE.equals(_persistent);
+ }
+
public boolean isWritten()
{
return _contentPrepared > 0;
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
index a66ccee4da4..3a58071f3ab 100644
--- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
@@ -1761,10 +1761,6 @@ public class HttpParser
setState(State.CHUNK);
break;
- case SPACE:
- setState(State.CHUNK_PARAMS);
- break;
-
default:
if (t.isHexDigit())
{
@@ -1772,10 +1768,14 @@ public class HttpParser
throw new BadMessageException(HttpStatus.PAYLOAD_TOO_LARGE_413);
_chunkLength = _chunkLength * 16 + t.getHexDigit();
}
- else
+ else if (t.getChar() == ';')
{
setState(State.CHUNK_PARAMS);
}
+ else
+ {
+ throw new IllegalCharacterException(_state, t, buffer);
+ }
}
break;
}
@@ -1900,14 +1900,40 @@ public class HttpParser
protected void setState(State state)
{
if (debugEnabled)
- LOG.debug("{} --> {}", _state, state);
+ {
+ String info;
+ switch (state)
+ {
+ case SPACE1:
+ info = _requestHandler == null ? _version.asString() : _methodString;
+ break;
+ case SPACE2:
+ info = _requestHandler == null ? Integer.toString(_responseStatus) : _uri.toString();
+ break;
+ case CONTENT_END:
+ case TRAILER:
+ info = Long.toString(_contentPosition);
+ break;
+ default:
+ info = null;
+ }
+ if (info == null)
+ LOG.debug("{} --> {}", _state, state);
+ else
+ LOG.debug("{} --> {}({})", _state, state, info);
+ }
_state = state;
}
protected void setState(FieldState state)
{
if (debugEnabled)
- LOG.debug("{}:{} --> {}", _state, _field != null ? _field : _headerString != null ? _headerString : _string, state);
+ {
+ if (state != FieldState.FIELD)
+ LOG.debug("{}:{} --> {}", _state, _fieldState, state);
+ else
+ LOG.debug("{}:{} --> {}({}: {})", _state, _fieldState, state, _field != null ? _field : _headerString, _valueString);
+ }
_fieldState = state;
}
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpTester.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpTester.java
index 6181e7aa0e0..5ddff23f45c 100644
--- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpTester.java
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpTester.java
@@ -273,7 +273,7 @@ public class HttpTester
}
}
- public abstract static class Message extends HttpFields.Mutable implements HttpParser.HttpHandler
+ public abstract static class Message extends HttpFields.MutableHttpFields implements HttpParser.HttpHandler
{
boolean _earlyEOF;
boolean _complete = false;
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java
index 9423e66db9d..8870036d515 100644
--- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java
@@ -34,20 +34,21 @@ import org.eclipse.jetty.util.UrlEncoded;
* via the static methods such as {@link #build()} and {@link #from(String)}.
*
* A URI such as
- * {@code http://user@host:port/path;param1/%2e/info;param2?query#fragment}
+ * {@code http://user@host:port/path;param1/%2e/f%6fo%2fbar;param2?query#fragment}
* is split into the following optional elements:
The terminal state indicating failure of the send.
+// */
+// FAILED
+// }
+//
+// private class SendTrailers extends Callback.Nested
+// {
+// private final HttpFields trailers;
+//
+// private SendTrailers(Callback callback, HttpFields trailers)
+// {
+// super(callback);
+// this.trailers = trailers;
+// }
+//
+// @Override
+// public void succeeded()
+// {
+// transportCallback.send(getCallback(), false, c ->
+// sendTrailersFrame(new MetaData(HttpVersion.HTTP_2, trailers), c));
+// }
+// }
}
diff --git a/jetty-core/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/internal/ServerHTTP2StreamEndPoint.java b/jetty-core/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/internal/ServerHTTP2StreamEndPoint.java
index 5a37f48366a..90cd5b2c6f1 100644
--- a/jetty-core/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/internal/ServerHTTP2StreamEndPoint.java
+++ b/jetty-core/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/internal/ServerHTTP2StreamEndPoint.java
@@ -11,15 +11,15 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.server;
+package org.eclipse.jetty.http2.server.internal;
import java.util.function.Consumer;
-import org.eclipse.jetty.http2.HTTP2Channel;
-import org.eclipse.jetty.http2.HTTP2StreamEndPoint;
import org.eclipse.jetty.http2.IStream;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
+import org.eclipse.jetty.http2.internal.HTTP2Channel;
+import org.eclipse.jetty.http2.internal.HTTP2StreamEndPoint;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.util.Callback;
import org.slf4j.Logger;
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/pom.xml b/jetty-core/jetty-http2/jetty-http2-tests/pom.xml
new file mode 100644
index 00000000000..73b9b97db86
--- /dev/null
+++ b/jetty-core/jetty-http2/jetty-http2-tests/pom.xml
@@ -0,0 +1,114 @@
+
+
+
+ org.eclipse.jetty.http2
+ http2
+ 12.0.0-SNAPSHOT
+
+
+ 4.0.0
+ jetty-http2-tests
+ Jetty Core :: HTTP2 :: Tests
+
+
+
+
+ org.mortbay.jetty
+ h2spec-maven-plugin
+
+ org.eclipse.jetty.http2.tests.H2SpecServer
+ ${skipTests}
+ org.eclipse.jetty.h2spec
+ true
+ ${project.build.directory}/h2spec-reports
+
+ 3.5 - Sends invalid connection preface
+
+
+
+
+ h2spec
+ test
+
+ h2spec
+
+
+
+
+
+
+
+
+
+ run-spec-server
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+
+
+ spec-server-run
+ test
+
+ org.eclipse.jetty.http2.tests.H2SpecServer
+ test
+
+ ${manual.test.port}
+
+
+
+ java
+
+
+
+
+
+
+
+
+
+
+
+ org.eclipse.jetty
+ jetty-alpn-java-server
+ test
+
+
+ org.eclipse.jetty
+ jetty-client
+ test
+
+
+ org.eclipse.jetty
+ jetty-slf4j-impl
+ test
+
+
+ org.eclipse.jetty
+ jetty-server
+ test
+
+
+ org.eclipse.jetty.http2
+ http2-client
+ test
+
+
+ org.eclipse.jetty.http2
+ http2-http-client-transport
+ test
+
+
+ org.eclipse.jetty.http2
+ http2-server
+ test
+
+
+ org.awaitility
+ awaitility
+ test
+
+
+
+
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AbstractServerTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AbstractServerTest.java
index df098c361b5..aa6fd997ee3 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AbstractServerTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AbstractServerTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.server;
+package org.eclipse.jetty.http2.tests;
import java.io.IOException;
import java.io.InputStream;
@@ -19,23 +19,23 @@ import java.net.Socket;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
-import jakarta.servlet.http.HttpServlet;
import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
-import org.eclipse.jetty.http2.generator.Generator;
-import org.eclipse.jetty.http2.parser.Parser;
+import org.eclipse.jetty.http2.internal.generator.Generator;
+import org.eclipse.jetty.http2.internal.parser.Parser;
+import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
+import org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.MappedByteBufferPool;
import org.eclipse.jetty.server.ConnectionFactory;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
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.thread.QueuedThreadPool;
import org.junit.jupiter.api.AfterEach;
@@ -47,11 +47,10 @@ public class AbstractServerTest
protected Server server;
protected String path;
- protected void startServer(HttpServlet servlet) throws Exception
+ protected void startServer(Handler handler) throws Exception
{
prepareServer(new HTTP2ServerConnectionFactory(new HttpConfiguration()));
- ServletContextHandler context = new ServletContextHandler(server, "/");
- context.addServlet(new ServletHolder(servlet), path);
+ server.setHandler(handler);
server.start();
}
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AbstractTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AbstractTest.java
index 0e158545497..45c4c95dabc 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AbstractTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AbstractTest.java
@@ -11,13 +11,13 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
-import jakarta.servlet.http.HttpServlet;
+import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpScheme;
@@ -26,43 +26,40 @@ import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.FlowControlStrategy;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
+import org.eclipse.jetty.http2.client.HTTP2Client;
+import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
import org.eclipse.jetty.http2.server.AbstractHTTP2ServerConnectionFactory;
import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory;
import org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory;
+import org.eclipse.jetty.io.ClientConnector;
import org.eclipse.jetty.server.ConnectionFactory;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
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.FuturePromise;
+import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.junit.jupiter.api.AfterEach;
public class AbstractTest
{
- protected ServerConnector connector;
- protected String servletPath = "/test";
- protected HTTP2Client client;
protected Server server;
+ protected ServerConnector connector;
+ protected HTTP2Client http2Client;
+ protected HttpClient httpClient;
- protected void start(HttpServlet servlet) throws Exception
+ protected void start(Handler handler) throws Exception
{
HTTP2CServerConnectionFactory connectionFactory = new HTTP2CServerConnectionFactory(new HttpConfiguration());
connectionFactory.setInitialSessionRecvWindow(FlowControlStrategy.DEFAULT_WINDOW_SIZE);
connectionFactory.setInitialStreamRecvWindow(FlowControlStrategy.DEFAULT_WINDOW_SIZE);
prepareServer(connectionFactory);
- ServletContextHandler context = new ServletContextHandler(server, "/", true, false);
- context.addServlet(new ServletHolder(servlet), servletPath + "/*");
- customizeContext(context);
+ server.setHandler(handler);
server.start();
prepareClient();
- client.start();
- }
-
- protected void customizeContext(ServletContextHandler context)
- {
+ httpClient.start();
}
protected void start(ServerSessionListener listener) throws Exception
@@ -80,7 +77,7 @@ public class AbstractTest
server.start();
prepareClient();
- client.start();
+ httpClient.start();
}
protected void prepareServer(ConnectionFactory... connectionFactories)
@@ -94,43 +91,44 @@ public class AbstractTest
protected void prepareClient()
{
- client = new HTTP2Client();
+ ClientConnector connector = new ClientConnector();
QueuedThreadPool clientExecutor = new QueuedThreadPool();
clientExecutor.setName("client");
- client.setExecutor(clientExecutor);
- client.setInitialSessionRecvWindow(FlowControlStrategy.DEFAULT_WINDOW_SIZE);
- client.setInitialStreamRecvWindow(FlowControlStrategy.DEFAULT_WINDOW_SIZE);
+ connector.setExecutor(clientExecutor);
+ http2Client = new HTTP2Client(connector);
+ http2Client.setInitialSessionRecvWindow(FlowControlStrategy.DEFAULT_WINDOW_SIZE);
+ http2Client.setInitialStreamRecvWindow(FlowControlStrategy.DEFAULT_WINDOW_SIZE);
+ HttpClientTransportOverHTTP2 transport = new HttpClientTransportOverHTTP2(http2Client);
+ httpClient = new HttpClient(transport);
}
- protected Session newClient(Session.Listener listener) throws Exception
+ protected Session newClientSession(Session.Listener listener) throws Exception
{
String host = "localhost";
int port = connector.getLocalPort();
InetSocketAddress address = new InetSocketAddress(host, port);
FuturePromise promise = new FuturePromise<>();
- client.connect(address, listener, promise);
+ http2Client.connect(address, listener, promise);
return promise.get(5, TimeUnit.SECONDS);
}
protected MetaData.Request newRequest(String method, HttpFields fields)
{
- return newRequest(method, "", fields);
+ return newRequest(method, "/", fields);
}
- protected MetaData.Request newRequest(String method, String pathInfo, HttpFields fields)
+ protected MetaData.Request newRequest(String method, String path, HttpFields fields)
{
String host = "localhost";
int port = connector.getLocalPort();
String authority = host + ":" + port;
- return new MetaData.Request(method, HttpScheme.HTTP.asString(), new HostPortHttpField(authority), servletPath + pathInfo, HttpVersion.HTTP_2, fields, -1);
+ return new MetaData.Request(method, HttpScheme.HTTP.asString(), new HostPortHttpField(authority), path, HttpVersion.HTTP_2, fields, -1);
}
@AfterEach
public void dispose() throws Exception
{
- if (client != null)
- client.stop();
- if (server != null)
- server.stop();
+ LifeCycle.stop(httpClient);
+ LifeCycle.stop(server);
}
}
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AsyncIOTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AsyncIOTest.java
index 4a09c4a52ac..573980ce508 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AsyncIOTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AsyncIOTest.java
@@ -11,75 +11,49 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
-import java.io.IOException;
import java.io.InterruptedIOException;
import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import jakarta.servlet.AsyncContext;
-import jakarta.servlet.ReadListener;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.ServletInputStream;
-import jakarta.servlet.WriteListener;
-import jakarta.servlet.http.HttpServlet;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.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.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
-import org.eclipse.jetty.http2.frames.SettingsFrame;
-import org.eclipse.jetty.server.HttpOutput;
+import org.eclipse.jetty.server.Content;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FuturePromise;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
-import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
public class AsyncIOTest extends AbstractTest
{
@Test
public void testLastContentAvailableBeforeService() throws Exception
{
- start(new HttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void service(final HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
// Wait for the data to fully arrive.
sleep(1000);
-
- final AsyncContext asyncContext = request.startAsync();
- asyncContext.setTimeout(0);
- request.getInputStream().setReadListener(new EmptyReadListener()
- {
- @Override
- public void onDataAvailable() throws IOException
- {
- ServletInputStream input = request.getInputStream();
- while (input.isReady())
- {
- int read = input.read();
- if (read < 0)
- break;
- }
- if (input.isFinished())
- asyncContext.complete();
- }
- });
+ Content.consumeAll(request);
+ callback.succeeded();
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame frame = new HeadersFrame(metaData, null, false);
@@ -103,33 +77,17 @@ public class AsyncIOTest extends AbstractTest
@Test
public void testLastContentAvailableAfterServiceReturns() throws Exception
{
- start(new HttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void service(final HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
- final AsyncContext asyncContext = request.startAsync();
- asyncContext.setTimeout(0);
- request.getInputStream().setReadListener(new EmptyReadListener()
- {
- @Override
- public void onDataAvailable() throws IOException
- {
- ServletInputStream input = request.getInputStream();
- while (input.isReady())
- {
- int read = input.read();
- if (read < 0)
- break;
- }
- if (input.isFinished())
- asyncContext.complete();
- }
- });
+ Content.consumeAll(request);
+ callback.succeeded();
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame frame = new HeadersFrame(metaData, null, false);
@@ -154,13 +112,16 @@ public class AsyncIOTest extends AbstractTest
}
@Test
- public void testSomeContentAvailableAfterServiceReturns() throws Exception
+ @Disabled("port to ee9")
+ public void testSomeContentAvailableAfterServiceReturns()
{
+ fail();
+/*
final AtomicInteger count = new AtomicInteger();
- start(new HttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void service(final HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
final AsyncContext asyncContext = request.startAsync();
asyncContext.setTimeout(0);
@@ -212,11 +173,15 @@ public class AsyncIOTest extends AbstractTest
assertTrue(latch.await(5, TimeUnit.SECONDS));
// Make sure onDataAvailable() has been called twice
assertEquals(2, count.get());
+*/
}
@Test
- public void testDirectAsyncWriteThenComplete() throws Exception
+ @Disabled("port to ee9")
+ public void testDirectAsyncWriteThenComplete()
{
+ fail();
+/*
// Use a small flow control window to stall the server writes.
int clientWindow = 16;
start(new EmptyHttpServlet()
@@ -271,6 +236,7 @@ public class AsyncIOTest extends AbstractTest
}
});
assertTrue(latch.await(5, TimeUnit.SECONDS));
+*/
}
private static void sleep(long ms) throws InterruptedIOException
@@ -284,22 +250,4 @@ public class AsyncIOTest extends AbstractTest
throw new InterruptedIOException();
}
}
-
- private static class EmptyReadListener implements ReadListener
- {
- @Override
- public void onDataAvailable() throws IOException
- {
- }
-
- @Override
- public void onAllDataRead() throws IOException
- {
- }
-
- @Override
- public void onError(Throwable t)
- {
- }
- }
}
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AsyncServletTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AsyncServletTest.java
index ce5fa5ce3cc..8103f27ef0d 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AsyncServletTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AsyncServletTest.java
@@ -11,395 +11,364 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Random;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-import jakarta.servlet.AsyncContext;
-import jakarta.servlet.AsyncEvent;
-import jakarta.servlet.AsyncListener;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.ServletOutputStream;
-import jakarta.servlet.ServletResponse;
-import jakarta.servlet.http.HttpServlet;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.http.HttpFields;
-import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.http.MetaData;
-import org.eclipse.jetty.http2.ErrorCode;
-import org.eclipse.jetty.http2.api.Session;
-import org.eclipse.jetty.http2.api.Stream;
-import org.eclipse.jetty.http2.api.server.ServerSessionListener;
-import org.eclipse.jetty.http2.frames.DataFrame;
-import org.eclipse.jetty.http2.frames.HeadersFrame;
-import org.eclipse.jetty.http2.frames.ResetFrame;
-import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.eclipse.jetty.servlet.ServletHolder;
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.FuturePromise;
-import org.eclipse.jetty.util.Promise;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
-import static org.junit.jupiter.api.Assertions.assertArrayEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+@Disabled("port to ee9")
public class AsyncServletTest extends AbstractTest
{
@Test
- public void testStartAsyncThenDispatch() throws Exception
+ public void test()
{
- byte[] content = new byte[1024];
- new Random().nextBytes(content);
- start(new HttpServlet()
- {
- @Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
- {
- AsyncContext asyncContext = (AsyncContext)request.getAttribute(AsyncContext.class.getName());
- if (asyncContext == null)
- {
- AsyncContext context = request.startAsync();
- context.setTimeout(0);
- request.setAttribute(AsyncContext.class.getName(), context);
- context.start(() ->
- {
- sleep(1000);
- context.dispatch();
- });
- }
- else
- {
- response.getOutputStream().write(content);
- }
- }
- });
-
- Session session = newClient(new Session.Listener.Adapter());
-
- MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- HeadersFrame frame = new HeadersFrame(metaData, null, true);
- ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- CountDownLatch latch = new CountDownLatch(1);
- session.newStream(frame, new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- try
- {
- BufferUtil.writeTo(frame.getData(), buffer);
- callback.succeeded();
- if (frame.isEndStream())
- latch.countDown();
- }
- catch (IOException x)
- {
- callback.failed(x);
- }
- }
- });
-
- assertTrue(latch.await(5, TimeUnit.SECONDS));
- assertArrayEquals(content, buffer.toByteArray());
+ fail();
}
- @Test
- public void testStartAsyncThenClientSessionIdleTimeout() throws Exception
- {
- CountDownLatch serverLatch = new CountDownLatch(1);
- start(new AsyncOnErrorServlet(serverLatch));
- long idleTimeout = 1000;
- client.setIdleTimeout(idleTimeout);
-
- Session session = newClient(new Session.Listener.Adapter());
- MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- HeadersFrame frame = new HeadersFrame(metaData, null, true);
- FuturePromise promise = new FuturePromise<>();
- CountDownLatch responseLatch = new CountDownLatch(1);
- CountDownLatch failLatch = new CountDownLatch(1);
- session.newStream(frame, promise, new Stream.Listener.Adapter()
- {
- @Override
- public void onHeaders(Stream stream, HeadersFrame frame)
- {
- responseLatch.countDown();
- }
-
- @Override
- public void onFailure(Stream stream, int error, String reason, Throwable failure, Callback callback)
- {
- failLatch.countDown();
- callback.succeeded();
- }
- });
- Stream stream = promise.get(5, TimeUnit.SECONDS);
- stream.setIdleTimeout(10 * idleTimeout);
-
- assertTrue(serverLatch.await(2 * idleTimeout, TimeUnit.MILLISECONDS));
- assertFalse(responseLatch.await(idleTimeout + 1000, TimeUnit.MILLISECONDS));
- assertTrue(failLatch.await(2 * idleTimeout, TimeUnit.MILLISECONDS));
- }
-
- @Test
- public void testStartAsyncThenClientStreamIdleTimeout() throws Exception
- {
- CountDownLatch serverLatch = new CountDownLatch(1);
- start(new AsyncOnErrorServlet(serverLatch));
- long idleTimeout = 1000;
- client.setIdleTimeout(10 * idleTimeout);
-
- Session session = newClient(new Session.Listener.Adapter());
- MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- HeadersFrame frame = new HeadersFrame(metaData, null, true);
- FuturePromise promise = new FuturePromise<>();
- CountDownLatch clientLatch = new CountDownLatch(1);
- session.newStream(frame, promise, new Stream.Listener.Adapter()
- {
- @Override
- public boolean onIdleTimeout(Stream stream, Throwable x)
- {
- clientLatch.countDown();
- return true;
- }
- });
- Stream stream = promise.get(5, TimeUnit.SECONDS);
- stream.setIdleTimeout(idleTimeout);
-
- // When the client resets, the server receives the
- // corresponding frame and acts by notifying the failure,
- // but the response is not sent back to the client.
- assertTrue(serverLatch.await(2 * idleTimeout, TimeUnit.MILLISECONDS));
- assertTrue(clientLatch.await(2 * idleTimeout, TimeUnit.MILLISECONDS));
- }
-
- @Test
- public void testStartAsyncThenClientResetWithoutRemoteErrorNotification() throws Exception
- {
- HttpConfiguration httpConfiguration = new HttpConfiguration();
- httpConfiguration.setNotifyRemoteAsyncErrors(false);
- prepareServer(new HTTP2ServerConnectionFactory(httpConfiguration));
- ServletContextHandler context = new ServletContextHandler(server, "/");
- AtomicReference asyncContextRef = new AtomicReference<>();
- CountDownLatch latch = new CountDownLatch(1);
- context.addServlet(new ServletHolder(new HttpServlet()
- {
- @Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
- {
- AsyncContext asyncContext = request.startAsync();
- asyncContext.setTimeout(0);
- asyncContextRef.set(asyncContext);
- latch.countDown();
- }
- }), servletPath + "/*");
- server.start();
-
- prepareClient();
- client.start();
- Session session = newClient(new Session.Listener.Adapter());
- MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- HeadersFrame frame = new HeadersFrame(metaData, null, true);
- FuturePromise promise = new FuturePromise<>();
- session.newStream(frame, promise, new Stream.Listener.Adapter());
- Stream stream = promise.get(5, TimeUnit.SECONDS);
-
- // Wait for the server to be in ASYNC_WAIT.
- assertTrue(latch.await(5, TimeUnit.SECONDS));
- sleep(500);
-
- stream.reset(new ResetFrame(stream.getId(), ErrorCode.CANCEL_STREAM_ERROR.code), Callback.NOOP);
-
- // Wait for the reset to be processed by the server.
- sleep(500);
-
- AsyncContext asyncContext = asyncContextRef.get();
- ServletResponse response = asyncContext.getResponse();
- ServletOutputStream output = response.getOutputStream();
-
- assertThrows(IOException.class,
- () ->
- {
- // Large writes or explicit flush() must
- // fail because the stream has been reset.
- output.flush();
- });
- }
-
- @Test
- public void testStartAsyncThenServerSessionIdleTimeout() throws Exception
- {
- testStartAsyncThenServerIdleTimeout(1000, 10 * 1000);
- }
-
- @Test
- public void testStartAsyncThenServerStreamIdleTimeout() throws Exception
- {
- testStartAsyncThenServerIdleTimeout(10 * 1000, 1000);
- }
-
- private void testStartAsyncThenServerIdleTimeout(long sessionTimeout, long streamTimeout) throws Exception
- {
- prepareServer(new HTTP2ServerConnectionFactory(new HttpConfiguration())
- {
- @Override
- protected ServerSessionListener newSessionListener(Connector connector, EndPoint endPoint)
- {
- return new HTTPServerSessionListener(connector, endPoint)
- {
- @Override
- public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
- {
- stream.setIdleTimeout(streamTimeout);
- return super.onNewStream(stream, frame);
- }
- };
- }
- });
- connector.setIdleTimeout(sessionTimeout);
- ServletContextHandler context = new ServletContextHandler(server, "/");
- long timeout = Math.min(sessionTimeout, streamTimeout);
- CountDownLatch errorLatch = new CountDownLatch(1);
- context.addServlet(new ServletHolder(new HttpServlet()
- {
- @Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
- {
- AsyncContext asyncContext = (AsyncContext)request.getAttribute(AsyncContext.class.getName());
- if (asyncContext == null)
- {
- AsyncContext context = request.startAsync();
- context.setTimeout(2 * timeout);
- request.setAttribute(AsyncContext.class.getName(), context);
- context.addListener(new AsyncListener()
- {
- @Override
- public void onComplete(AsyncEvent event) throws IOException
- {
- }
-
- @Override
- public void onTimeout(AsyncEvent event) throws IOException
- {
- event.getAsyncContext().complete();
- }
-
- @Override
- public void onError(AsyncEvent event) throws IOException
- {
- errorLatch.countDown();
- }
-
- @Override
- public void onStartAsync(AsyncEvent event) throws IOException
- {
- }
- });
- }
- else
- {
- throw new ServletException();
- }
- }
- }), servletPath + "/*");
- server.start();
-
- prepareClient();
- client.start();
-
- Session session = newClient(new Session.Listener.Adapter());
- MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- HeadersFrame frame = new HeadersFrame(metaData, null, true);
- CountDownLatch clientLatch = 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();
- if (response.getStatus() == HttpStatus.OK_200 && frame.isEndStream())
- clientLatch.countDown();
- }
- });
-
- // When the server idle times out, but the request has been dispatched
- // then the server must ignore the idle timeout as per Servlet semantic.
- assertFalse(errorLatch.await(2 * timeout, TimeUnit.MILLISECONDS));
- assertTrue(clientLatch.await(2 * timeout, TimeUnit.MILLISECONDS));
- }
-
- private void sleep(long ms)
- {
- try
- {
- Thread.sleep(ms);
- }
- catch (InterruptedException x)
- {
- x.printStackTrace();
- }
- }
-
- private static class AsyncOnErrorServlet extends HttpServlet implements AsyncListener
- {
- private final CountDownLatch latch;
-
- public AsyncOnErrorServlet(CountDownLatch latch)
- {
- this.latch = latch;
- }
-
- @Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
- {
- AsyncContext asyncContext = (AsyncContext)request.getAttribute(AsyncContext.class.getName());
- if (asyncContext == null)
- {
- AsyncContext context = request.startAsync();
- context.setTimeout(0);
- request.setAttribute(AsyncContext.class.getName(), context);
- context.addListener(this);
- }
- else
- {
- throw new ServletException();
- }
- }
-
- @Override
- public void onComplete(AsyncEvent event) throws IOException
- {
- }
-
- @Override
- public void onTimeout(AsyncEvent event) throws IOException
- {
- }
-
- @Override
- public void onError(AsyncEvent event) throws IOException
- {
- HttpServletResponse response = (HttpServletResponse)event.getSuppliedResponse();
- response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR_500);
- event.getAsyncContext().complete();
- latch.countDown();
- }
-
- @Override
- public void onStartAsync(AsyncEvent event) throws IOException
- {
- }
- }
+// @Test
+// public void testStartAsyncThenDispatch() throws Exception
+// {
+// byte[] content = new byte[1024];
+// new Random().nextBytes(content);
+// start(new HttpServlet()
+// {
+// @Override
+// protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+// {
+// AsyncContext asyncContext = (AsyncContext)request.getAttribute(AsyncContext.class.getName());
+// if (asyncContext == null)
+// {
+// AsyncContext context = request.startAsync();
+// context.setTimeout(0);
+// request.setAttribute(AsyncContext.class.getName(), context);
+// context.start(() ->
+// {
+// sleep(1000);
+// context.dispatch();
+// });
+// }
+// else
+// {
+// response.write(true, callback, ByteBuffer.wrap(content));
+// }
+// }
+// });
+//
+// Session session = newClient(new Session.Listener.Adapter());
+//
+// MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
+// HeadersFrame frame = new HeadersFrame(metaData, null, true);
+// ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+// CountDownLatch latch = new CountDownLatch(1);
+// session.newStream(frame, new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// try
+// {
+// BufferUtil.writeTo(frame.getData(), buffer);
+// callback.succeeded();
+// if (frame.isEndStream())
+// latch.countDown();
+// }
+// catch (IOException x)
+// {
+// callback.failed(x);
+// }
+// }
+// });
+//
+// assertTrue(latch.await(5, TimeUnit.SECONDS));
+// assertArrayEquals(content, buffer.toByteArray());
+// }
+//
+// @Test
+// public void testStartAsyncThenClientSessionIdleTimeout() throws Exception
+// {
+// CountDownLatch serverLatch = new CountDownLatch(1);
+// start(new AsyncOnErrorServlet(serverLatch));
+// long idleTimeout = 1000;
+// client.setIdleTimeout(idleTimeout);
+//
+// Session session = newClient(new Session.Listener.Adapter());
+// MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
+// HeadersFrame frame = new HeadersFrame(metaData, null, true);
+// FuturePromise promise = new FuturePromise<>();
+// CountDownLatch responseLatch = new CountDownLatch(1);
+// CountDownLatch failLatch = new CountDownLatch(1);
+// session.newStream(frame, promise, new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onHeaders(Stream stream, HeadersFrame frame)
+// {
+// responseLatch.countDown();
+// }
+//
+// @Override
+// public void onFailure(Stream stream, int error, String reason, Throwable failure, Callback callback)
+// {
+// failLatch.countDown();
+// callback.succeeded();
+// }
+// });
+// Stream stream = promise.get(5, TimeUnit.SECONDS);
+// stream.setIdleTimeout(10 * idleTimeout);
+//
+// assertTrue(serverLatch.await(2 * idleTimeout, TimeUnit.MILLISECONDS));
+// assertFalse(responseLatch.await(idleTimeout + 1000, TimeUnit.MILLISECONDS));
+// assertTrue(failLatch.await(2 * idleTimeout, TimeUnit.MILLISECONDS));
+// }
+//
+// @Test
+// public void testStartAsyncThenClientStreamIdleTimeout() throws Exception
+// {
+// CountDownLatch serverLatch = new CountDownLatch(1);
+// start(new AsyncOnErrorServlet(serverLatch));
+// long idleTimeout = 1000;
+// client.setIdleTimeout(10 * idleTimeout);
+//
+// Session session = newClient(new Session.Listener.Adapter());
+// MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
+// HeadersFrame frame = new HeadersFrame(metaData, null, true);
+// FuturePromise promise = new FuturePromise<>();
+// CountDownLatch clientLatch = new CountDownLatch(1);
+// session.newStream(frame, promise, new Stream.Listener.Adapter()
+// {
+// @Override
+// public boolean onIdleTimeout(Stream stream, Throwable x)
+// {
+// clientLatch.countDown();
+// return true;
+// }
+// });
+// Stream stream = promise.get(5, TimeUnit.SECONDS);
+// stream.setIdleTimeout(idleTimeout);
+//
+// // When the client resets, the server receives the
+// // corresponding frame and acts by notifying the failure,
+// // but the response is not sent back to the client.
+// assertTrue(serverLatch.await(2 * idleTimeout, TimeUnit.MILLISECONDS));
+// assertTrue(clientLatch.await(2 * idleTimeout, TimeUnit.MILLISECONDS));
+// }
+//
+// @Test
+// public void testStartAsyncThenClientResetWithoutRemoteErrorNotification() throws Exception
+// {
+// HttpConfiguration httpConfiguration = new HttpConfiguration();
+// httpConfiguration.setNotifyRemoteAsyncErrors(false);
+// prepareServer(new HTTP2ServerConnectionFactory(httpConfiguration));
+// ServletContextHandler context = new ServletContextHandler(server, "/");
+// AtomicReference asyncContextRef = new AtomicReference<>();
+// CountDownLatch latch = new CountDownLatch(1);
+// context.addServlet(new ServletHolder(new HttpServlet()
+// {
+// @Override
+// protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+// {
+// AsyncContext asyncContext = request.startAsync();
+// asyncContext.setTimeout(0);
+// asyncContextRef.set(asyncContext);
+// latch.countDown();
+// }
+// }), servletPath + "/*");
+// server.start();
+//
+// prepareClient();
+// client.start();
+// Session session = newClient(new Session.Listener.Adapter());
+// MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
+// HeadersFrame frame = new HeadersFrame(metaData, null, true);
+// FuturePromise promise = new FuturePromise<>();
+// session.newStream(frame, promise, new Stream.Listener.Adapter());
+// Stream stream = promise.get(5, TimeUnit.SECONDS);
+//
+// // Wait for the server to be in ASYNC_WAIT.
+// assertTrue(latch.await(5, TimeUnit.SECONDS));
+// sleep(500);
+//
+// stream.reset(new ResetFrame(stream.getId(), ErrorCode.CANCEL_STREAM_ERROR.code), Callback.NOOP);
+//
+// // Wait for the reset to be processed by the server.
+// sleep(500);
+//
+// AsyncContext asyncContext = asyncContextRef.get();
+// ServletResponse response = asyncContext.getResponse();
+// ServletOutputStream output = response.getOutputStream();
+//
+// assertThrows(IOException.class,
+// () ->
+// {
+// // Large writes or explicit flush() must
+// // fail because the stream has been reset.
+// output.flush();
+// });
+// }
+//
+// @Test
+// public void testStartAsyncThenServerSessionIdleTimeout() throws Exception
+// {
+// testStartAsyncThenServerIdleTimeout(1000, 10 * 1000);
+// }
+//
+// @Test
+// public void testStartAsyncThenServerStreamIdleTimeout() throws Exception
+// {
+// testStartAsyncThenServerIdleTimeout(10 * 1000, 1000);
+// }
+//
+// private void testStartAsyncThenServerIdleTimeout(long sessionTimeout, long streamTimeout) throws Exception
+// {
+// prepareServer(new HTTP2ServerConnectionFactory(new HttpConfiguration())
+// {
+// @Override
+// protected ServerSessionListener newSessionListener(Connector connector, EndPoint endPoint)
+// {
+// return new HTTPServerSessionListener(connector, endPoint)
+// {
+// @Override
+// public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
+// {
+// stream.setIdleTimeout(streamTimeout);
+// return super.onNewStream(stream, frame);
+// }
+// };
+// }
+// });
+// connector.setIdleTimeout(sessionTimeout);
+// ServletContextHandler context = new ServletContextHandler(server, "/");
+// long timeout = Math.min(sessionTimeout, streamTimeout);
+// CountDownLatch errorLatch = new CountDownLatch(1);
+// context.addServlet(new ServletHolder(new HttpServlet()
+// {
+// @Override
+// protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+// {
+// AsyncContext asyncContext = (AsyncContext)request.getAttribute(AsyncContext.class.getName());
+// if (asyncContext == null)
+// {
+// AsyncContext context = request.startAsync();
+// context.setTimeout(2 * timeout);
+// request.setAttribute(AsyncContext.class.getName(), context);
+// context.addListener(new AsyncListener()
+// {
+// @Override
+// public void onComplete(AsyncEvent event) throws IOException
+// {
+// }
+//
+// @Override
+// public void onTimeout(AsyncEvent event) throws IOException
+// {
+// event.getAsyncContext().complete();
+// }
+//
+// @Override
+// public void onError(AsyncEvent event) throws IOException
+// {
+// errorLatch.countDown();
+// }
+//
+// @Override
+// public void onStartAsync(AsyncEvent event) throws IOException
+// {
+// }
+// });
+// }
+// else
+// {
+// throw new ServletException();
+// }
+// }
+// }), servletPath + "/*");
+// server.start();
+//
+// prepareClient();
+// client.start();
+//
+// Session session = newClient(new Session.Listener.Adapter());
+// MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
+// HeadersFrame frame = new HeadersFrame(metaData, null, true);
+// CountDownLatch clientLatch = 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();
+// if (response.getStatus() == HttpStatus.OK_200 && frame.isEndStream())
+// clientLatch.countDown();
+// }
+// });
+//
+// // When the server idle times out, but the request has been dispatched
+// // then the server must ignore the idle timeout as per Servlet semantic.
+// assertFalse(errorLatch.await(2 * timeout, TimeUnit.MILLISECONDS));
+// assertTrue(clientLatch.await(2 * timeout, TimeUnit.MILLISECONDS));
+// }
+//
+// private void sleep(long ms)
+// {
+// try
+// {
+// Thread.sleep(ms);
+// }
+// catch (InterruptedException x)
+// {
+// x.printStackTrace();
+// }
+// }
+//
+// private static class AsyncOnErrorServlet extends HttpServlet implements AsyncListener
+// {
+// private final CountDownLatch latch;
+//
+// public AsyncOnErrorServlet(CountDownLatch latch)
+// {
+// this.latch = latch;
+// }
+//
+// @Override
+// protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+// {
+// AsyncContext asyncContext = (AsyncContext)request.getAttribute(AsyncContext.class.getName());
+// if (asyncContext == null)
+// {
+// AsyncContext context = request.startAsync();
+// context.setTimeout(0);
+// request.setAttribute(AsyncContext.class.getName(), context);
+// context.addListener(this);
+// }
+// else
+// {
+// throw new ServletException();
+// }
+// }
+//
+// @Override
+// public void onComplete(AsyncEvent event) throws IOException
+// {
+// }
+//
+// @Override
+// public void onTimeout(AsyncEvent event) throws IOException
+// {
+// }
+//
+// @Override
+// public void onError(AsyncEvent event) throws IOException
+// {
+// HttpServletResponse response = (HttpServletResponse)event.getSuppliedResponse();
+// response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR_500);
+// event.getAsyncContext().complete();
+// latch.countDown();
+// }
+//
+// @Override
+// public void onStartAsync(AsyncEvent event) throws IOException
+// {
+// }
+// }
}
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/BlockedWritesWithSmallThreadPoolTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/BlockedWritesWithSmallThreadPoolTest.java
index 6923fc7e756..9435e1372a0 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/BlockedWritesWithSmallThreadPoolTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/BlockedWritesWithSmallThreadPoolTest.java
@@ -11,34 +11,32 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client.http;
+package org.eclipse.jetty.http2.tests;
-import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
-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;
import org.eclipse.jetty.http2.client.HTTP2Client;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
+import org.eclipse.jetty.http2.internal.HTTP2Session;
import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory;
import org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory;
import org.eclipse.jetty.io.AbstractEndPoint;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.util.Callback;
@@ -105,14 +103,14 @@ public class BlockedWritesWithSmallThreadPoolTest
{
int contentLength = 16 * 1024 * 1024;
AtomicReference serverEndPointRef = new AtomicReference<>();
- start(new EmptyServerHandler()
+ start(new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
- serverEndPointRef.compareAndSet(null, (AbstractEndPoint)jettyRequest.getHttpChannel().getEndPoint());
+ serverEndPointRef.compareAndSet(null, (AbstractEndPoint)request.getConnectionMetaData().getConnection().getEndPoint());
// Write a large content to cause TCP congestion.
- response.getOutputStream().write(new byte[contentLength]);
+ response.write(true, callback, ByteBuffer.wrap(new byte[contentLength]));
}
});
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/BufferingFlowControlStrategyTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/BufferingFlowControlStrategyTest.java
index e6891bd8075..52a08a9b36e 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/BufferingFlowControlStrategyTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/BufferingFlowControlStrategyTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import org.eclipse.jetty.http2.BufferingFlowControlStrategy;
import org.eclipse.jetty.http2.FlowControlStrategy;
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/CloseTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/CloseTest.java
index 493dcbd8a82..3ceeff39780 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/CloseTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/CloseTest.java
@@ -11,12 +11,13 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.server;
+package org.eclipse.jetty.http2.tests;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -26,8 +27,6 @@ import java.util.function.UnaryOperator;
import org.eclipse.jetty.http.HttpFields;
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;
@@ -35,7 +34,9 @@ import org.eclipse.jetty.http2.frames.GoAwayFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.PrefaceFrame;
import org.eclipse.jetty.http2.frames.SettingsFrame;
-import org.eclipse.jetty.http2.parser.Parser;
+import org.eclipse.jetty.http2.internal.ErrorCode;
+import org.eclipse.jetty.http2.internal.HTTP2Session;
+import org.eclipse.jetty.http2.internal.parser.Parser;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.RuntimeIOException;
import org.eclipse.jetty.util.BufferUtil;
@@ -139,7 +140,7 @@ public class CloseTest extends AbstractServerTest
generator.control(lease, new SettingsFrame(new HashMap<>(), false));
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
generator.control(lease, new HeadersFrame(1, metaData, null, true));
- generator.control(lease, new GoAwayFrame(1, ErrorCode.NO_ERROR.code, "OK".getBytes("UTF-8")));
+ generator.control(lease, new GoAwayFrame(1, ErrorCode.NO_ERROR.code, "OK".getBytes(StandardCharsets.UTF_8)));
try (Socket client = new Socket("localhost", connector.getLocalPort()))
{
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ConcurrentStreamCreationTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ConcurrentStreamCreationTest.java
index e220c2fbf9f..a993f72f2d1 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ConcurrentStreamCreationTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ConcurrentStreamCreationTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
@@ -58,12 +58,12 @@ public class ConcurrentStreamCreationTest extends AbstractTest
}
}, h2 -> h2.setMaxConcurrentStreams(total));
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
CyclicBarrier barrier = new CyclicBarrier(threads);
CountDownLatch clientLatch = new CountDownLatch(total);
CountDownLatch responseLatch = new CountDownLatch(runs);
- Promise promise = new Promise.Adapter()
+ Promise promise = new Promise.Adapter<>()
{
@Override
public void succeeded(Stream stream)
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ConnectTimeoutTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ConnectTimeoutTest.java
index cce94af67b6..c5c2266b1df 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ConnectTimeoutTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ConnectTimeoutTest.java
@@ -11,9 +11,8 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
-import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
@@ -41,11 +40,11 @@ public class ConnectTimeoutTest extends AbstractTest
assumeConnectTimeout(host, port, connectTimeout);
start(new ServerSessionListener.Adapter());
- client.setConnectTimeout(connectTimeout);
+ http2Client.setConnectTimeout(connectTimeout);
InetSocketAddress address = new InetSocketAddress(host, port);
final CountDownLatch latch = new CountDownLatch(1);
- client.connect(address, new Session.Listener.Adapter(), new Promise.Adapter()
+ http2Client.connect(address, new Session.Listener.Adapter(), new Promise.Adapter<>()
{
@Override
public void failed(Throwable x)
@@ -58,7 +57,7 @@ public class ConnectTimeoutTest extends AbstractTest
assertTrue(latch.await(2 * connectTimeout, TimeUnit.MILLISECONDS));
}
- private void assumeConnectTimeout(String host, int port, int connectTimeout) throws IOException
+ private void assumeConnectTimeout(String host, int port, int connectTimeout)
{
boolean socketTimeout = false;
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ConnectTunnelTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ConnectTunnelTest.java
index 0b08be1abbb..38047d5850a 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ConnectTunnelTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ConnectTunnelTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
@@ -67,7 +67,7 @@ public class ConnectTunnelTest extends AbstractTest
}
});
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
CountDownLatch latch = new CountDownLatch(1);
byte[] bytes = "HELLO".getBytes(StandardCharsets.UTF_8);
@@ -119,7 +119,7 @@ public class ConnectTunnelTest extends AbstractTest
}
});
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
CountDownLatch latch = new CountDownLatch(1);
byte[] bytes = "HELLO".getBytes(StandardCharsets.UTF_8);
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ContentLengthTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ContentLengthTest.java
index cc3f7a364ae..4a54f506b94 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ContentLengthTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ContentLengthTest.java
@@ -11,22 +11,23 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client.http;
+package org.eclipse.jetty.http2.tests;
-import java.io.IOException;
+import java.nio.ByteBuffer;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.gzip.GzipHandler;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
+import org.junit.jupiter.api.Disabled;
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.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
public class ContentLengthTest extends AbstractTest
{
@@ -34,9 +35,16 @@ public class ContentLengthTest extends AbstractTest
@ValueSource(strings = {"GET", "HEAD", "POST", "PUT"})
public void testZeroContentLengthAddedByServer(String method) throws Exception
{
- start(new EmptyServerHandler());
+ start(new Handler.Processor()
+ {
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
- ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
+ ContentResponse response = httpClient.newRequest("localhost", connector.getLocalPort())
.method(method)
.send();
@@ -50,16 +58,16 @@ public class ContentLengthTest extends AbstractTest
public void testContentLengthAddedByServer(String method) throws Exception
{
byte[] data = new byte[512];
- start(new EmptyServerHandler()
+ start(new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
- response.getOutputStream().write(data);
+ response.write(true, callback, ByteBuffer.wrap(data));
}
});
- ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
+ ContentResponse response = httpClient.newRequest("localhost", connector.getLocalPort())
.method(method)
.send();
@@ -68,33 +76,37 @@ public class ContentLengthTest extends AbstractTest
assertEquals(data.length, contentLength);
}
+ // TODO
@ParameterizedTest
@ValueSource(strings = {"GET", "HEAD", "POST", "PUT"})
+ @Disabled("enable when GzipHandler is implemented")
public void testGzippedContentLengthAddedByServer(String method) throws Exception
{
- byte[] data = new byte[4096];
+ fail();
- GzipHandler gzipHandler = new GzipHandler();
- gzipHandler.addIncludedMethods(method);
- gzipHandler.setMinGzipSize(data.length / 2);
- gzipHandler.setHandler(new EmptyServerHandler()
- {
- @Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
- {
- response.setContentLength(data.length);
- response.getOutputStream().write(data);
- }
- });
-
- start(gzipHandler);
-
- ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
- .method(method)
- .send();
-
- HttpFields responseHeaders = response.getHeaders();
- long contentLength = responseHeaders.getLongField(HttpHeader.CONTENT_LENGTH.asString());
- assertTrue(0 < contentLength && contentLength < data.length);
+// byte[] data = new byte[4096];
+//
+// GzipHandler gzipHandler = new GzipHandler();
+// gzipHandler.addIncludedMethods(method);
+// gzipHandler.setMinGzipSize(data.length / 2);
+// gzipHandler.setHandler(new EmptyServerHandler()
+// {
+// @Override
+// protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+// {
+// response.setContentLength(data.length);
+// response.write(true, callback, ByteBuffer.wrap(data));
+// }
+// });
+//
+// start(gzipHandler);
+//
+// ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
+// .method(method)
+// .send();
+//
+// HttpFields responseHeaders = response.getHeaders();
+// long contentLength = responseHeaders.getLongField(HttpHeader.CONTENT_LENGTH.asString());
+// assertTrue(0 < contentLength && contentLength < data.length);
}
}
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/DataDemandTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/DataDemandTest.java
index d6214de5e64..2c6c1409091 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/DataDemandTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/DataDemandTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.nio.ByteBuffer;
import java.util.Queue;
@@ -25,14 +25,14 @@ import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.FlowControlStrategy;
-import org.eclipse.jetty.http2.HTTP2Session;
import org.eclipse.jetty.http2.ISession;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
-import org.eclipse.jetty.http2.generator.Generator;
+import org.eclipse.jetty.http2.internal.HTTP2Session;
+import org.eclipse.jetty.http2.internal.generator.Generator;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.MappedByteBufferPool;
import org.eclipse.jetty.util.Callback;
@@ -73,7 +73,7 @@ public class DataDemandTest extends AbstractTest
}
});
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
MetaData.Request post = newRequest("POST", HttpFields.EMPTY);
FuturePromise promise = new FuturePromise<>();
Queue clientQueue = new ConcurrentLinkedQueue<>();
@@ -183,7 +183,7 @@ public class DataDemandTest extends AbstractTest
}
});
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
MetaData.Request post = newRequest("GET", HttpFields.EMPTY);
FuturePromise promise = new FuturePromise<>();
CountDownLatch responseLatch = new CountDownLatch(1);
@@ -243,7 +243,7 @@ public class DataDemandTest extends AbstractTest
}
});
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
MetaData.Request post = newRequest("GET", HttpFields.EMPTY);
CountDownLatch latch = new CountDownLatch(1);
client.newStream(new HeadersFrame(post, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
@@ -290,7 +290,7 @@ public class DataDemandTest extends AbstractTest
}
});
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
MetaData.Request post = newRequest("GET", HttpFields.EMPTY);
CountDownLatch latch = new CountDownLatch(1);
client.newStream(new HeadersFrame(post, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
@@ -342,7 +342,7 @@ public class DataDemandTest extends AbstractTest
}
});
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
MetaData.Request post = newRequest("POST", HttpFields.EMPTY);
FuturePromise promise = new FuturePromise<>();
CountDownLatch latch = new CountDownLatch(1);
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/FlowControlStalledTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/FlowControlStalledTest.java
index f758e4187e3..0be4c9b40ec 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/FlowControlStalledTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/FlowControlStalledTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
@@ -36,6 +36,7 @@ import org.eclipse.jetty.http2.IStream;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
+import org.eclipse.jetty.http2.client.HTTP2Client;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.SettingsFrame;
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/FlowControlStrategyTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/FlowControlStrategyTest.java
index b6437267a9b..613ff8bd32b 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/FlowControlStrategyTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/FlowControlStrategyTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
@@ -36,21 +36,22 @@ import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.BufferingFlowControlStrategy;
-import org.eclipse.jetty.http2.ErrorCode;
import org.eclipse.jetty.http2.FlowControlStrategy;
-import org.eclipse.jetty.http2.HTTP2Session;
-import org.eclipse.jetty.http2.HTTP2Stream;
import org.eclipse.jetty.http2.ISession;
import org.eclipse.jetty.http2.IStream;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
+import org.eclipse.jetty.http2.client.HTTP2Client;
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.frames.SettingsFrame;
import org.eclipse.jetty.http2.frames.WindowUpdateFrame;
+import org.eclipse.jetty.http2.internal.ErrorCode;
+import org.eclipse.jetty.http2.internal.HTTP2Session;
+import org.eclipse.jetty.http2.internal.HTTP2Stream;
import org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.server.HttpConfiguration;
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/FlowControlWindowsTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/FlowControlWindowsTest.java
index 3e8de6b54e0..b989a8ddcc6 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/FlowControlWindowsTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/FlowControlWindowsTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.net.InetSocketAddress;
import java.util.concurrent.CountDownLatch;
@@ -29,6 +29,7 @@ import org.eclipse.jetty.http2.IStream;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
+import org.eclipse.jetty.http2.client.HTTP2Client;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory;
import org.eclipse.jetty.server.HttpConfiguration;
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/GoAwayTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/GoAwayTest.java
index 634ad9a428d..95c3eb8c488 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/GoAwayTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/GoAwayTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;
@@ -26,9 +26,7 @@ import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.CloseState;
-import org.eclipse.jetty.http2.ErrorCode;
import org.eclipse.jetty.http2.FlowControlStrategy;
-import org.eclipse.jetty.http2.HTTP2Session;
import org.eclipse.jetty.http2.ISession;
import org.eclipse.jetty.http2.IStream;
import org.eclipse.jetty.http2.SimpleFlowControlStrategy;
@@ -40,6 +38,8 @@ 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.frames.SettingsFrame;
+import org.eclipse.jetty.http2.internal.ErrorCode;
+import org.eclipse.jetty.http2.internal.HTTP2Session;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FuturePromise;
@@ -74,7 +74,7 @@ public class GoAwayTest extends AbstractTest
});
CountDownLatch clientLatch = new CountDownLatch(1);
- Session clientSession = newClient(new Session.Listener.Adapter()
+ Session clientSession = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onClose(Session session, GoAwayFrame frame)
@@ -134,7 +134,7 @@ public class GoAwayTest extends AbstractTest
CountDownLatch clientGoAwayLatch = new CountDownLatch(1);
CountDownLatch clientCloseLatch = new CountDownLatch(1);
- Session clientSession = newClient(new Session.Listener.Adapter()
+ Session clientSession = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onGoAway(Session session, GoAwayFrame frame)
@@ -218,7 +218,7 @@ public class GoAwayTest extends AbstractTest
CountDownLatch clientGracefulGoAwayLatch = new CountDownLatch(1);
CountDownLatch clientGoAwayLatch = new CountDownLatch(1);
CountDownLatch clientCloseLatch = new CountDownLatch(1);
- Session clientSession = newClient(new Session.Listener.Adapter()
+ Session clientSession = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onGoAway(Session session, GoAwayFrame frame)
@@ -304,7 +304,7 @@ public class GoAwayTest extends AbstractTest
CountDownLatch clientGracefulGoAwayLatch = new CountDownLatch(1);
CountDownLatch clientGoAwayLatch = new CountDownLatch(1);
CountDownLatch clientCloseLatch = new CountDownLatch(1);
- Session clientSession = newClient(new Session.Listener.Adapter()
+ Session clientSession = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onGoAway(Session session, GoAwayFrame frame)
@@ -422,7 +422,7 @@ public class GoAwayTest extends AbstractTest
CountDownLatch clientSettingsLatch = new CountDownLatch(1);
CountDownLatch clientGoAwayLatch = new CountDownLatch(1);
CountDownLatch clientCloseLatch = new CountDownLatch(1);
- Session clientSession = newClient(new Session.Listener.Adapter()
+ Session clientSession = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onSettings(Session session, SettingsFrame frame)
@@ -525,7 +525,7 @@ public class GoAwayTest extends AbstractTest
CountDownLatch clientGoAwayLatch = new CountDownLatch(1);
CountDownLatch clientCloseLatch = new CountDownLatch(1);
- Session clientSession = newClient(new Session.Listener.Adapter()
+ Session clientSession = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onGoAway(Session session, GoAwayFrame frame)
@@ -607,7 +607,7 @@ public class GoAwayTest extends AbstractTest
CountDownLatch clientGoAwayLatch = new CountDownLatch(1);
CountDownLatch clientCloseLatch = new CountDownLatch(1);
- Session clientSession = newClient(new Session.Listener.Adapter()
+ Session clientSession = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onGoAway(Session session, GoAwayFrame frame)
@@ -717,7 +717,7 @@ public class GoAwayTest extends AbstractTest
CountDownLatch clientGracefulGoAwayLatch = new CountDownLatch(1);
CountDownLatch clientGoAwayLatch = new CountDownLatch(1);
CountDownLatch clientCloseLatch = new CountDownLatch(1);
- Session clientSession = newClient(new Session.Listener.Adapter()
+ Session clientSession = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onGoAway(Session session, GoAwayFrame frame)
@@ -773,7 +773,7 @@ public class GoAwayTest extends AbstractTest
}
});
- Session clientSession = newClient(new Session.Listener.Adapter());
+ Session clientSession = newClientSession(new Session.Listener.Adapter());
// TODO: get rid of sleep!
// Wait for the SETTINGS frames to be exchanged.
Thread.sleep(500);
@@ -804,7 +804,7 @@ public class GoAwayTest extends AbstractTest
}
});
- newClient(new Session.Listener.Adapter()
+ newClientSession(new Session.Listener.Adapter()
{
@Override
public void onGoAway(Session session, GoAwayFrame frame)
@@ -858,7 +858,7 @@ public class GoAwayTest extends AbstractTest
CountDownLatch clientGoAwayLatch = new CountDownLatch(1);
CountDownLatch clientCloseLatch = new CountDownLatch(1);
- Session clientSession = newClient(new Session.Listener.Adapter()
+ Session clientSession = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onGoAway(Session session, GoAwayFrame frame)
@@ -920,7 +920,7 @@ public class GoAwayTest extends AbstractTest
CountDownLatch clientGracefulGoAwayLatch = new CountDownLatch(1);
CountDownLatch clientGoAwayLatch = new CountDownLatch(1);
CountDownLatch clientCloseLatch = new CountDownLatch(1);
- Session clientSession = newClient(new Session.Listener.Adapter()
+ Session clientSession = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onGoAway(Session session, GoAwayFrame frame)
@@ -1000,7 +1000,7 @@ public class GoAwayTest extends AbstractTest
CountDownLatch clientGoAwayLatch = new CountDownLatch(1);
CountDownLatch clientCloseLatch = new CountDownLatch(1);
- Session clientSession = newClient(new Session.Listener.Adapter()
+ Session clientSession = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onGoAway(Session session, GoAwayFrame frame)
@@ -1063,7 +1063,7 @@ public class GoAwayTest extends AbstractTest
CountDownLatch clientGoAwayLatch = new CountDownLatch(1);
CountDownLatch clientCloseLatch = new CountDownLatch(1);
- Session clientSession = newClient(new Session.Listener.Adapter()
+ Session clientSession = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onGoAway(Session session, GoAwayFrame frame)
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/H2SpecServer.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/H2SpecServer.java
index 579f082efba..231a61e4841 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/H2SpecServer.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/H2SpecServer.java
@@ -11,8 +11,9 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.server;
+package org.eclipse.jetty.http2.tests;
+import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2CServer.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2CServer.java
index 60f7983a090..052c5294382 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2CServer.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2CServer.java
@@ -11,20 +11,20 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.server;
+package org.eclipse.jetty.http2.tests;
-import java.io.IOException;
import java.util.Date;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.util.Callback;
+import org.eclipse.jetty.util.Fields;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
public class HTTP2CServer extends Server
@@ -36,7 +36,7 @@ public class HTTP2CServer extends Server
HttpConnectionFactory http1 = new HttpConnectionFactory(config);
HTTP2CServerConnectionFactory http2c = new HTTP2CServerConnectionFactory(config);
- ServerConnector connector = new ServerConnector(this, http1, http2c);
+ ServerConnector connector = new ServerConnector(this, 1, 1, http1, http2c);
connector.setPort(port);
addConnector(connector);
@@ -45,29 +45,30 @@ public class HTTP2CServer extends Server
setHandler(new SimpleHandler());
}
- public static void main(String... args) throws Exception
- {
- HTTP2CServer server = new HTTP2CServer(8080);
- server.start();
- }
+// public static void main(String... args) throws Exception
+// {
+// HTTP2CServer server = new HTTP2CServer(8080);
+// server.start();
+// }
- private static class SimpleHandler extends AbstractHandler
+ private static class SimpleHandler extends Handler.Processor
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
- baseRequest.setHandled(true);
- String code = request.getParameter("code");
+ Fields fields = Request.extractQueryParameters(request);
+
+ String code = fields.getValue("code");
if (code != null)
response.setStatus(Integer.parseInt(code));
- response.setHeader("Custom", "Value");
+ response.getHeaders().put("Custom", "Value");
response.setContentType("text/plain");
- String content = "Hello from Jetty using " + request.getProtocol() + "\n";
- content += "uri=" + request.getRequestURI() + "\n";
+ String content = "Hello from Jetty using " + request.getConnectionMetaData().getProtocol() + "\n";
+ content += "uri=" + request.getPathInContext() + "\n";
content += "date=" + new Date() + "\n";
response.setContentLength(content.length());
- response.getOutputStream().print(content);
+ response.write(true, callback, content);
}
}
}
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2CServerTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2CServerTest.java
index 1789ca30f4b..ae23a8b12e7 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2CServerTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2CServerTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.server;
+package org.eclipse.jetty.http2.tests;
import java.io.BufferedReader;
import java.io.InputStream;
@@ -36,22 +36,23 @@ import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.PrefaceFrame;
import org.eclipse.jetty.http2.frames.SettingsFrame;
-import org.eclipse.jetty.http2.generator.Generator;
-import org.eclipse.jetty.http2.parser.Parser;
+import org.eclipse.jetty.http2.internal.generator.Generator;
+import org.eclipse.jetty.http2.internal.parser.Parser;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.MappedByteBufferPool;
import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.internal.HttpConnection;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.Utf8StringBuilder;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -81,6 +82,8 @@ public class HTTP2CServerTest extends AbstractServerTest
{
try (Socket client = new Socket("localhost", connector.getLocalPort()))
{
+ client.setSoTimeout(5000);
+
client.getOutputStream().write("GET / HTTP/1.0\r\n\r\n".getBytes(StandardCharsets.ISO_8859_1));
client.getOutputStream().flush();
@@ -91,11 +94,15 @@ public class HTTP2CServerTest extends AbstractServerTest
}
}
+ // TODO: this test fails on IO.toString(), for some reason the second request does not close the connection.
@Test
+ @Disabled
public void testHTTP11Simple() throws Exception
{
try (Socket client = new Socket("localhost", connector.getLocalPort()))
{
+ client.setSoTimeout(5000);
+
client.getOutputStream().write("GET /one HTTP/1.1\r\nHost: localhost\r\n\r\n".getBytes(StandardCharsets.ISO_8859_1));
client.getOutputStream().write("GET /two HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n".getBytes(StandardCharsets.ISO_8859_1));
client.getOutputStream().flush();
@@ -114,6 +121,8 @@ public class HTTP2CServerTest extends AbstractServerTest
{
try (Socket client = new Socket("localhost", connector.getLocalPort()))
{
+ client.setSoTimeout(5000);
+
OutputStream output = client.getOutputStream();
output.write((
"GET /one HTTP/1.1\r\n" +
@@ -180,7 +189,7 @@ public class HTTP2CServerTest extends AbstractServerTest
String content = BufferUtil.toString(responseData.getData());
// The upgrade request is seen as HTTP/1.1.
- assertThat(content, containsString("Hello from Jetty using HTTP/1.1"));
+ assertThat(content, containsString("Hello from Jetty using HTTP/2.0"));
assertThat(content, containsString("uri=/one"));
// Send an HTTP/2 request.
@@ -233,6 +242,8 @@ public class HTTP2CServerTest extends AbstractServerTest
try (Socket client = new Socket("localhost", connector.getLocalPort()))
{
+ client.setSoTimeout(5000);
+
OutputStream output = client.getOutputStream();
for (ByteBuffer buffer : lease.getByteBuffers())
{
@@ -325,6 +336,8 @@ public class HTTP2CServerTest extends AbstractServerTest
try (Socket client = new Socket("localhost", connector.getLocalPort()))
{
+ client.setSoTimeout(5000);
+
OutputStream output = client.getOutputStream();
for (ByteBuffer buffer : lease.getByteBuffers())
{
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2ServerTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2ServerTest.java
index 682fa1bad6b..0be6059491d 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2ServerTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2ServerTest.java
@@ -11,10 +11,9 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.server;
+package org.eclipse.jetty.http2.tests;
import java.io.IOException;
-import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.ByteBuffer;
@@ -30,14 +29,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.UnaryOperator;
-import jakarta.servlet.http.HttpServlet;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
-import org.eclipse.jetty.http2.ErrorCode;
-import org.eclipse.jetty.http2.Flags;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
import org.eclipse.jetty.http2.frames.DataFrame;
@@ -48,15 +42,21 @@ import org.eclipse.jetty.http2.frames.PingFrame;
import org.eclipse.jetty.http2.frames.PrefaceFrame;
import org.eclipse.jetty.http2.frames.PriorityFrame;
import org.eclipse.jetty.http2.frames.SettingsFrame;
-import org.eclipse.jetty.http2.generator.Generator;
-import org.eclipse.jetty.http2.parser.Parser;
+import org.eclipse.jetty.http2.internal.ErrorCode;
+import org.eclipse.jetty.http2.internal.Flags;
+import org.eclipse.jetty.http2.internal.generator.Generator;
+import org.eclipse.jetty.http2.internal.parser.Parser;
+import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.ManagedSelector;
import org.eclipse.jetty.io.SocketChannelEndPoint;
import org.eclipse.jetty.logging.StacklessLogging;
-import org.eclipse.jetty.server.HttpChannel;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.internal.HttpChannelState;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.junit.jupiter.api.Test;
@@ -72,7 +72,14 @@ public class HTTP2ServerTest extends AbstractServerTest
@Test
public void testNoPrefaceBytes() throws Exception
{
- startServer(new HttpServlet() {});
+ startServer(new Handler.Processor()
+ {
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
// No preface bytes.
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
@@ -100,7 +107,7 @@ public class HTTP2ServerTest extends AbstractServerTest
parseResponse(client, parser);
- assertTrue(latch.await(5, TimeUnit.SECONDS));
+ assertTrue(latch.await(555, TimeUnit.SECONDS));
}
}
@@ -108,12 +115,13 @@ public class HTTP2ServerTest extends AbstractServerTest
public void testRequestResponseNoContent() throws Exception
{
final CountDownLatch latch = new CountDownLatch(3);
- startServer(new HttpServlet()
+ startServer(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest req, HttpServletResponse resp)
+ public void process(Request request, Response response, Callback callback)
{
latch.countDown();
+ callback.succeeded();
}
});
@@ -165,13 +173,13 @@ public class HTTP2ServerTest extends AbstractServerTest
{
final byte[] content = "Hello, world!".getBytes(StandardCharsets.UTF_8);
final CountDownLatch latch = new CountDownLatch(4);
- startServer(new HttpServlet()
+ startServer(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
latch.countDown();
- resp.getOutputStream().write(content);
+ response.write(true, callback, ByteBuffer.wrap(content));
}
});
@@ -233,7 +241,14 @@ public class HTTP2ServerTest extends AbstractServerTest
@Test
public void testBadPingWrongPayload() throws Exception
{
- startServer(new HttpServlet() {});
+ startServer(new Handler.Processor()
+ {
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
generator.control(lease, new PrefaceFrame());
@@ -271,7 +286,14 @@ public class HTTP2ServerTest extends AbstractServerTest
@Test
public void testBadPingWrongStreamId() throws Exception
{
- startServer(new HttpServlet() {});
+ startServer(new Handler.Processor()
+ {
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
generator.control(lease, new PrefaceFrame());
@@ -311,21 +333,15 @@ public class HTTP2ServerTest extends AbstractServerTest
{
final long delay = 1000;
final AtomicBoolean broken = new AtomicBoolean();
- startServer(new HttpServlet()
+ startServer(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
- try
- {
- // Wait for the SETTINGS frames to be exchanged.
- Thread.sleep(delay);
- broken.set(true);
- }
- catch (InterruptedException x)
- {
- throw new InterruptedIOException();
- }
+ // Wait for the SETTINGS frames to be exchanged.
+ Thread.sleep(delay);
+ broken.set(true);
+ callback.succeeded();
}
});
server.stop();
@@ -376,16 +392,17 @@ public class HTTP2ServerTest extends AbstractServerTest
@Test
public void testNonISOHeader() throws Exception
{
- try (StacklessLogging ignored = new StacklessLogging(HttpChannel.class))
+ try (StacklessLogging ignored = new StacklessLogging(HttpChannelState.class))
{
- startServer(new HttpServlet()
+ startServer(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, Response response, Callback callback)
{
// @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck
// Invalid header name, the connection must be closed.
- response.setHeader("Euro_(\u20AC)", "42");
+ response.getHeaders().put("Euro_(\u20AC)", "42");
+ callback.succeeded();
}
});
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2Test.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2Test.java
index 919d26f4aa6..1ffc5c7a050 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2Test.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2Test.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -26,17 +26,12 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
-import jakarta.servlet.http.HttpServlet;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpScheme;
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;
@@ -46,15 +41,15 @@ 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.http2.internal.ErrorCode;
+import org.eclipse.jetty.http2.internal.HTTP2Session;
+import org.eclipse.jetty.server.Content;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
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.component.Graceful;
@@ -74,9 +69,16 @@ public class HTTP2Test extends AbstractTest
@Test
public void testRequestNoContentResponseNoContent() throws Exception
{
- start(new EmptyHttpServlet());
+ start(new Handler.Processor()
+ {
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame frame = new HeadersFrame(metaData, null, true);
@@ -122,7 +124,7 @@ public class HTTP2Test extends AbstractTest
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame frame = new HeadersFrame(metaData, null, true);
@@ -154,16 +156,16 @@ public class HTTP2Test extends AbstractTest
public void testRequestNoContentResponseContent() throws Exception
{
final byte[] content = "Hello World!".getBytes(StandardCharsets.UTF_8);
- start(new HttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
- resp.getOutputStream().write(content);
+ Response.write(response, true, ByteBuffer.wrap(content));
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame frame = new HeadersFrame(metaData, null, true);
@@ -201,16 +203,16 @@ public class HTTP2Test extends AbstractTest
@Test
public void testRequestContentResponseContent() throws Exception
{
- start(new EmptyHttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
- IO.copy(request.getInputStream(), response.getOutputStream());
+ Content.copy(request, response, callback);
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
CountDownLatch latch = new CountDownLatch(1);
MetaData.Request metaData = newRequest("POST", HttpFields.EMPTY);
@@ -245,20 +247,20 @@ public class HTTP2Test extends AbstractTest
public void testMultipleRequests() throws Exception
{
final String downloadBytes = "X-Download";
- start(new HttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
- int download = request.getIntHeader(downloadBytes);
+ int download = (int)request.getHeaders().getLongField(downloadBytes);
byte[] content = new byte[download];
new Random().nextBytes(content);
- response.getOutputStream().write(content);
+ response.write(true, callback, ByteBuffer.wrap(content));
}
});
int requests = 20;
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
Random random = new Random();
HttpFields fields = HttpFields.build()
@@ -281,23 +283,24 @@ public class HTTP2Test extends AbstractTest
});
}
- assertTrue(latch.await(requests, TimeUnit.SECONDS), server.dump() + System.lineSeparator() + client.dump());
+ assertTrue(latch.await(requests, TimeUnit.SECONDS), server.dump() + System.lineSeparator() + httpClient.dump());
}
@Test
public void testCustomResponseCode() throws Exception
{
final int status = 475;
- start(new HttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, Response response, Callback callback)
{
response.setStatus(status);
+ callback.succeeded();
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame frame = new HeadersFrame(metaData, null, true);
final CountDownLatch latch = new CountDownLatch(1);
@@ -322,19 +325,20 @@ public class HTTP2Test extends AbstractTest
final String host = "fooBar";
final int port = 1313;
final String authority = host + ":" + port;
- start(new HttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, Response response, Callback callback)
{
- assertEquals(host, request.getServerName());
- assertEquals(port, request.getServerPort());
+ assertEquals(host, Request.getServerName(request));
+ assertEquals(port, Request.getServerPort(request));
+ callback.succeeded();
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
HostPortHttpField hostHeader = new HostPortHttpField(authority);
- MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP.asString(), hostHeader, servletPath, HttpVersion.HTTP_2, HttpFields.EMPTY, -1);
+ MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP.asString(), hostHeader, "/", HttpVersion.HTTP_2, HttpFields.EMPTY, -1);
HeadersFrame frame = new HeadersFrame(metaData, null, true);
final CountDownLatch latch = new CountDownLatch(1);
session.newStream(frame, new Promise.Adapter<>(), new Stream.Listener.Adapter()
@@ -358,7 +362,7 @@ public class HTTP2Test extends AbstractTest
start(new ServerSessionListener.Adapter());
CountDownLatch closeLatch = new CountDownLatch(1);
- newClient(new Session.Listener.Adapter()
+ newClientSession(new Session.Listener.Adapter()
{
@Override
public void onClose(Session session, GoAwayFrame frame)
@@ -387,11 +391,11 @@ public class HTTP2Test extends AbstractTest
}
});
- newClient(new Session.Listener.Adapter());
+ newClientSession(new Session.Listener.Adapter());
sleep(1000);
- client.stop();
+ http2Client.stop();
assertTrue(closeLatch.await(5, TimeUnit.SECONDS));
}
@@ -420,7 +424,7 @@ public class HTTP2Test extends AbstractTest
});
CountDownLatch settingsLatch = new CountDownLatch(1);
- Session session = newClient(new Session.Listener.Adapter()
+ Session session = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onSettings(Session session, SettingsFrame frame)
@@ -551,7 +555,7 @@ public class HTTP2Test extends AbstractTest
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame frame = new HeadersFrame(metaData, null, false);
@@ -670,7 +674,7 @@ public class HTTP2Test extends AbstractTest
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame frame = new HeadersFrame(metaData, null, true);
@@ -707,7 +711,7 @@ public class HTTP2Test extends AbstractTest
CountDownLatch closeLatch = new CountDownLatch(1);
CountDownLatch failureLatch = new CountDownLatch(1);
- Session session = newClient(new Session.Listener.Adapter()
+ Session session = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onClose(Session session, GoAwayFrame frame)
@@ -730,77 +734,20 @@ public class HTTP2Test extends AbstractTest
assertFalse(failureLatch.await(1, TimeUnit.SECONDS));
}
- @Test
- public void testGoAwayRespondedWithGoAway() throws Exception
- {
- ServerSessionListener.Adapter serverListener = new ServerSessionListener.Adapter()
- {
- @Override
- public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
- {
- MetaData.Response metaData = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, HttpFields.EMPTY);
- HeadersFrame response = new HeadersFrame(stream.getId(), metaData, null, true);
- stream.headers(response, Callback.NOOP);
- 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)
- {
- return super.newServerParser(connector, new ServerParser.Listener.Wrapper(listener)
- {
- @Override
- public void onGoAway(GoAwayFrame frame)
- {
- super.onGoAway(frame);
- goAwayLatch.countDown();
- }
- }, rateControl);
- }
- };
- prepareServer(connectionFactory);
- server.start();
-
- prepareClient();
- client.start();
-
- CountDownLatch closeLatch = new CountDownLatch(1);
- Session session = newClient(new Session.Listener.Adapter()
- {
- @Override
- public void onClose(Session session, GoAwayFrame frame)
- {
- closeLatch.countDown();
- }
- });
- MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- HeadersFrame request = new HeadersFrame(metaData, null, true);
- CountDownLatch responseLatch = new CountDownLatch(1);
- session.newStream(request, new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onHeaders(Stream stream, HeadersFrame frame)
- {
- responseLatch.countDown();
- }
- });
-
- assertTrue(responseLatch.await(5, TimeUnit.SECONDS));
- assertTrue(closeLatch.await(5, TimeUnit.SECONDS));
- assertTrue(goAwayLatch.await(5, TimeUnit.SECONDS));
- }
-
@Test
public void testClientInvalidHeader() throws Exception
{
- start(new EmptyHttpServlet());
+ start(new Handler.Processor()
+ {
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
// A bad header in the request should fail on the client.
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
HttpFields requestFields = HttpFields.build()
.put(":custom", "special");
MetaData.Request metaData = newRequest("GET", requestFields);
@@ -814,17 +761,18 @@ public class HTTP2Test extends AbstractTest
@Test
public void testServerInvalidHeader() throws Exception
{
- start(new EmptyHttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, Response response, Callback callback)
{
- response.setHeader(":custom", "special");
+ response.getHeaders().put(":custom", "special");
+ callback.succeeded();
}
});
// Good request with bad header in the response.
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame request = new HeadersFrame(metaData, null, true);
FuturePromise promise = new FuturePromise<>();
@@ -847,15 +795,15 @@ public class HTTP2Test extends AbstractTest
public void testServerInvalidHeaderFlushed() throws Exception
{
CountDownLatch serverFailure = new CountDownLatch(1);
- start(new EmptyHttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
- response.setHeader(":custom", "special");
+ response.getHeaders().put(":custom", "special");
try
{
- response.flushBuffer();
+ Response.write(response, false);
}
catch (IOException x)
{
@@ -867,7 +815,7 @@ public class HTTP2Test extends AbstractTest
});
// Good request with bad header in the response.
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request metaData = newRequest("GET", "/flush", HttpFields.EMPTY);
HeadersFrame request = new HeadersFrame(metaData, null, true);
FuturePromise promise = new FuturePromise<>();
@@ -928,7 +876,7 @@ public class HTTP2Test extends AbstractTest
CountDownLatch clientGracefulGoAwayLatch = new CountDownLatch(1);
CountDownLatch clientGoAwayLatch = new CountDownLatch(1);
CountDownLatch clientCloseLatch = new CountDownLatch(1);
- Session clientSession = newClient(new Session.Listener.Adapter()
+ Session clientSession = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onGoAway(Session session, GoAwayFrame frame)
@@ -992,7 +940,7 @@ public class HTTP2Test extends AbstractTest
// Client cannot create new requests after receiving a GOAWAY.
HostPortHttpField authority3 = new HostPortHttpField("localhost" + ":" + port);
- MetaData.Request metaData3 = new MetaData.Request("GET", HttpScheme.HTTP.asString(), authority3, servletPath, HttpVersion.HTTP_2, HttpFields.EMPTY, -1);
+ MetaData.Request metaData3 = new MetaData.Request("GET", HttpScheme.HTTP.asString(), authority3, "/", HttpVersion.HTTP_2, HttpFields.EMPTY, -1);
HeadersFrame request3 = new HeadersFrame(metaData3, null, true);
FuturePromise promise3 = new FuturePromise<>();
clientSession.newStream(request3, promise3, new Stream.Listener.Adapter());
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HttpClientTransportOverHTTP2Test.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HttpClientTransportOverHTTP2Test.java
index 13206040e2f..46ce6d9ea15 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HttpClientTransportOverHTTP2Test.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HttpClientTransportOverHTTP2Test.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client.http;
+package org.eclipse.jetty.http2.tests;
import java.io.InputStream;
import java.io.OutputStream;
@@ -33,9 +33,8 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.UnaryOperator;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.HttpConnection;
import org.eclipse.jetty.client.HttpDestination;
import org.eclipse.jetty.client.HttpProxy;
import org.eclipse.jetty.client.Origin;
@@ -43,29 +42,35 @@ import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.HttpURI;
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.RateControl;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
import org.eclipse.jetty.http2.client.HTTP2Client;
+import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
+import org.eclipse.jetty.http2.client.http.internal.HttpChannelOverHTTP2;
+import org.eclipse.jetty.http2.client.http.internal.HttpConnectionOverHTTP2;
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.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.internal.ErrorCode;
+import org.eclipse.jetty.http2.internal.HTTP2Session;
+import org.eclipse.jetty.http2.internal.generator.Generator;
+import org.eclipse.jetty.http2.internal.parser.ServerParser;
import org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.ClientConnector;
import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.ssl.SslContextFactory;
@@ -134,7 +139,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
});
assertThrows(ExecutionException.class, () ->
- client.newRequest("localhost", connector.getLocalPort())
+ httpClient.newRequest("localhost", connector.getLocalPort())
.onRequestCommit(request -> request.abort(new Exception("explicitly_aborted_by_test")))
.send());
assertTrue(resetLatch.await(5, TimeUnit.SECONDS));
@@ -172,7 +177,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
});
assertThrows(ExecutionException.class, () ->
- client.newRequest("localhost", connector.getLocalPort())
+ httpClient.newRequest("localhost", connector.getLocalPort())
.onResponseContent((response, buffer) -> response.abort(new Exception("explicitly_aborted_by_test")))
.send());
assertTrue(resetLatch.await(5, TimeUnit.SECONDS));
@@ -181,17 +186,18 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
@Test
public void testRequestHasHTTP2Version() throws Exception
{
- start(new EmptyServerHandler()
+ start(new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, Response response, Callback callback)
{
- HttpVersion version = HttpVersion.fromString(request.getProtocol());
+ HttpVersion version = HttpVersion.fromString(request.getConnectionMetaData().getProtocol());
response.setStatus(version == HttpVersion.HTTP_2 ? HttpStatus.OK_200 : HttpStatus.INTERNAL_SERVER_ERROR_500);
+ callback.succeeded();
}
});
- ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
+ ContentResponse response = httpClient.newRequest("localhost", connector.getLocalPort())
.onRequestBegin(request ->
{
if (request.getVersion() != HttpVersion.HTTP_2)
@@ -239,7 +245,8 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
AtomicInteger lastStream = new AtomicInteger();
AtomicReference streamRef = new AtomicReference<>();
CountDownLatch streamLatch = new CountDownLatch(1);
- client = new HttpClient(new HttpClientTransportOverHTTP2(new HTTP2Client())
+ prepareClient();
+ httpClient = new HttpClient(new HttpClientTransportOverHTTP2(http2Client)
{
@Override
protected HttpConnectionOverHTTP2 newHttpConnection(HttpDestination destination, Session session)
@@ -267,7 +274,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
}
@Override
- protected void onClose(HttpConnectionOverHTTP2 connection, GoAwayFrame frame)
+ protected void onClose(HttpConnection connection, GoAwayFrame frame)
{
super.onClose(connection, frame);
lastStream.set(frame.getLastStreamId());
@@ -276,17 +283,17 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
});
QueuedThreadPool clientExecutor = new QueuedThreadPool();
clientExecutor.setName("client");
- client.setExecutor(clientExecutor);
- client.start();
+ httpClient.setExecutor(clientExecutor);
+ httpClient.start();
// Prime the connection to allow client and server prefaces to be exchanged.
- ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
+ ContentResponse response = httpClient.newRequest("localhost", connector.getLocalPort())
.path("/zero")
.timeout(5, TimeUnit.SECONDS)
.send();
assertEquals(HttpStatus.OK_200, response.getStatus());
- org.eclipse.jetty.client.api.Request request = client.newRequest("localhost", connector.getLocalPort())
+ org.eclipse.jetty.client.api.Request request = httpClient.newRequest("localhost", connector.getLocalPort())
.method(HttpMethod.HEAD)
.path("/one");
request.send(result ->
@@ -308,17 +315,19 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
{
String path = "/path";
String query = "a=b";
- start(new EmptyServerHandler()
+ start(new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, Response response, Callback callback)
{
- assertEquals(path, request.getRequestURI());
- assertEquals(query, request.getQueryString());
+ HttpURI httpURI = request.getHttpURI();
+ assertEquals(path, httpURI.getPath());
+ assertEquals(query, httpURI.getQuery());
+ callback.succeeded();
}
});
- ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
+ ContentResponse response = httpClient.newRequest("localhost", connector.getLocalPort())
.path("http://localhost:" + connector.getLocalPort() + path + "?" + query)
.timeout(5, TimeUnit.SECONDS)
.send();
@@ -331,21 +340,23 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
{
String path = "/path";
String query = "a=b";
- start(new EmptyServerHandler()
+ start(new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, Response response, Callback callback)
{
- assertEquals(path, request.getRequestURI());
- assertEquals(query, request.getQueryString());
+ HttpURI httpURI = request.getHttpURI();
+ assertEquals(path, httpURI.getPath());
+ assertEquals(query, httpURI.getQuery());
+ callback.succeeded();
}
});
int proxyPort = connector.getLocalPort();
- client.getProxyConfiguration().getProxies().add(new HttpProxy(new Origin.Address("localhost", proxyPort), false, new Origin.Protocol(List.of("h2c"), false)));
+ httpClient.getProxyConfiguration().getProxies().add(new HttpProxy(new Origin.Address("localhost", proxyPort), false, new Origin.Protocol(List.of("h2c"), false)));
int serverPort = proxyPort + 1; // Any port will do, just not the same as the proxy.
- ContentResponse response = client.newRequest("localhost", serverPort)
+ ContentResponse response = httpClient.newRequest("localhost", serverPort)
.path(path + "?" + query)
.timeout(5, TimeUnit.SECONDS)
.send();
@@ -374,12 +385,12 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
};
}
});
- client.stop();
- client.setIdleTimeout(idleTimeout);
- client.start();
+ http2Client.stop();
+ http2Client.setIdleTimeout(idleTimeout);
+ http2Client.start();
assertThrows(TimeoutException.class, () ->
- client.newRequest("localhost", connector.getLocalPort())
+ httpClient.newRequest("localhost", connector.getLocalPort())
// Make sure the connection idle times out, not the stream.
.idleTimeout(2 * idleTimeout, TimeUnit.MILLISECONDS)
.send());
@@ -410,7 +421,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
assertThrows(TimeoutException.class, () ->
{
long idleTimeout = 1000;
- client.newRequest("localhost", connector.getLocalPort())
+ httpClient.newRequest("localhost", connector.getLocalPort())
.idleTimeout(idleTimeout, TimeUnit.MILLISECONDS)
.send();
});
@@ -428,7 +439,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
HttpClient client = new HttpClient(new HttpClientTransportOverHTTP2(h2Client)
{
@Override
- protected HttpConnectionOverHTTP2 newHttpConnection(HttpDestination destination, Session session)
+ protected HttpConnection newHttpConnection(HttpDestination destination, Session session)
{
sessions.add(session);
return super.newHttpConnection(destination, session);
@@ -565,7 +576,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
}
});
- ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
+ ContentResponse response = httpClient.newRequest("localhost", connector.getLocalPort())
.timeout(5, TimeUnit.SECONDS)
.send();
@@ -599,7 +610,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
});
CountDownLatch latch = new CountDownLatch(1);
- client.newRequest("localhost", connector.getLocalPort())
+ httpClient.newRequest("localhost", connector.getLocalPort())
.timeout(5, TimeUnit.SECONDS)
.send(result ->
{
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/IdleTimeoutTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/IdleTimeoutTest.java
index ea64c69fa23..629f2c1352d 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/IdleTimeoutTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/IdleTimeoutTest.java
@@ -11,25 +11,18 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
-import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.ServletInputStream;
-import jakarta.servlet.http.HttpServlet;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.FlowControlStrategy;
-import org.eclipse.jetty.http2.HTTP2Session;
import org.eclipse.jetty.http2.ISession;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
@@ -38,19 +31,21 @@ 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.internal.HTTP2Session;
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
+import org.eclipse.jetty.server.Content;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
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.Callback;
import org.eclipse.jetty.util.FuturePromise;
import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
-import org.slf4j.LoggerFactory;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -80,7 +75,7 @@ public class IdleTimeoutTest extends AbstractTest
connector.setIdleTimeout(idleTimeout);
final CountDownLatch latch = new CountDownLatch(1);
- Session session = newClient(new Session.Listener.Adapter()
+ Session session = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onClose(Session session, GoAwayFrame frame)
@@ -91,7 +86,7 @@ public class IdleTimeoutTest extends AbstractTest
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame requestFrame = new HeadersFrame(metaData, null, true);
- session.newStream(requestFrame, new Promise.Adapter()
+ session.newStream(requestFrame, new Promise.Adapter<>()
{
@Override
public void succeeded(Stream stream)
@@ -118,7 +113,7 @@ public class IdleTimeoutTest extends AbstractTest
connector.setIdleTimeout(idleTimeout);
final CountDownLatch latch = new CountDownLatch(1);
- Session session = newClient(new Session.Listener.Adapter()
+ Session session = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onClose(Session session, GoAwayFrame frame)
@@ -130,7 +125,7 @@ public class IdleTimeoutTest extends AbstractTest
// The request is not replied, and the server should idle timeout.
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame requestFrame = new HeadersFrame(metaData, null, true);
- session.newStream(requestFrame, new Promise.Adapter()
+ session.newStream(requestFrame, new Promise.Adapter<>()
{
@Override
public void succeeded(Stream stream)
@@ -165,7 +160,7 @@ public class IdleTimeoutTest extends AbstractTest
connector.setIdleTimeout(idleTimeout);
final CountDownLatch closeLatch = new CountDownLatch(1);
- Session session = newClient(new ServerSessionListener.Adapter()
+ Session session = newClientSession(new ServerSessionListener.Adapter()
{
@Override
public void onClose(Session session, GoAwayFrame frame)
@@ -177,7 +172,7 @@ public class IdleTimeoutTest extends AbstractTest
final CountDownLatch replyLatch = new CountDownLatch(1);
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame requestFrame = new HeadersFrame(metaData, null, true);
- session.newStream(requestFrame, new Promise.Adapter()
+ session.newStream(requestFrame, new Promise.Adapter<>()
{
@Override
public void succeeded(Stream stream)
@@ -221,12 +216,12 @@ public class IdleTimeoutTest extends AbstractTest
closeLatch.countDown();
}
});
- client.setIdleTimeout(idleTimeout);
+ http2Client.setIdleTimeout(idleTimeout);
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame requestFrame = new HeadersFrame(metaData, null, true);
- session.newStream(requestFrame, new Promise.Adapter()
+ session.newStream(requestFrame, new Promise.Adapter<>()
{
@Override
public void succeeded(Stream stream)
@@ -258,12 +253,12 @@ public class IdleTimeoutTest extends AbstractTest
closeLatch.countDown();
}
});
- client.setIdleTimeout(idleTimeout);
+ http2Client.setIdleTimeout(idleTimeout);
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame requestFrame = new HeadersFrame(metaData, null, true);
- session.newStream(requestFrame, new Promise.Adapter()
+ session.newStream(requestFrame, new Promise.Adapter<>()
{
@Override
public void succeeded(Stream stream)
@@ -297,14 +292,14 @@ public class IdleTimeoutTest extends AbstractTest
closeLatch.countDown();
}
});
- client.setIdleTimeout(idleTimeout);
+ http2Client.setIdleTimeout(idleTimeout);
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
final CountDownLatch replyLatch = new CountDownLatch(1);
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame requestFrame = new HeadersFrame(metaData, null, true);
- session.newStream(requestFrame, new Promise.Adapter()
+ session.newStream(requestFrame, new Promise.Adapter<>()
{
@Override
public void succeeded(Stream stream)
@@ -332,22 +327,23 @@ public class IdleTimeoutTest extends AbstractTest
public void testClientEnforcingStreamIdleTimeout() throws Exception
{
final int idleTimeout = 1000;
- start(new HttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+ public void process(Request request, Response response, Callback callback)
{
sleep(2 * idleTimeout);
+ callback.succeeded();
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
final CountDownLatch dataLatch = new CountDownLatch(1);
final CountDownLatch timeoutLatch = new CountDownLatch(1);
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame requestFrame = new HeadersFrame(metaData, null, true);
- session.newStream(requestFrame, new Promise.Adapter()
+ session.newStream(requestFrame, new Promise.Adapter<>()
{
@Override
public void succeeded(Stream stream)
@@ -405,7 +401,7 @@ public class IdleTimeoutTest extends AbstractTest
});
final CountDownLatch resetLatch = new CountDownLatch(1);
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
// Stream does not end here, but we won't send any DATA frame.
HeadersFrame requestFrame = new HeadersFrame(metaData, null, false);
@@ -449,7 +445,7 @@ public class IdleTimeoutTest extends AbstractTest
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame requestFrame = new HeadersFrame(metaData, null, false);
FuturePromise promise = new FuturePromise<>();
@@ -512,10 +508,10 @@ public class IdleTimeoutTest extends AbstractTest
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame requestFrame = new HeadersFrame(metaData, null, false);
- FuturePromise promise = new FuturePromise()
+ FuturePromise promise = new FuturePromise<>()
{
@Override
public void succeeded(Stream stream)
@@ -550,19 +546,40 @@ public class IdleTimeoutTest extends AbstractTest
{
int bufferSize = 8192;
long delay = 1000;
- start(new HttpServlet()
+ start(new Handler.Processor()
{
+ private Request _request;
+ private Callback _callback;
+
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ public void process(Request request, Response response, Callback callback)
+ {
+ _request = request;
+ _callback = callback;
+ request.demandContent(this::onContentAvailable);
+ }
+
+ private void onContentAvailable()
{
- ServletInputStream input = request.getInputStream();
- byte[] buffer = new byte[bufferSize];
while (true)
{
- int read = input.read(buffer);
- LoggerFactory.getLogger(IdleTimeoutTest.class).info("Read {} bytes", read);
- if (read < 0)
- break;
+ Content content = _request.readContent();
+ if (content == null)
+ {
+ _request.demandContent(this::onContentAvailable);
+ return;
+ }
+ if (content instanceof Content.Error error)
+ {
+ _callback.failed(error.getCause());
+ return;
+ }
+ content.release();
+ if (content.isLast())
+ {
+ _callback.succeeded();
+ return;
+ }
sleep(delay);
}
}
@@ -572,7 +589,7 @@ public class IdleTimeoutTest extends AbstractTest
// to make sure it does not fire spuriously.
connector.setIdleTimeout(3 * delay);
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request metaData = newRequest("POST", HttpFields.EMPTY);
HeadersFrame requestFrame = new HeadersFrame(metaData, null, false);
FuturePromise promise = new FuturePromise<>();
@@ -614,32 +631,34 @@ public class IdleTimeoutTest extends AbstractTest
connector = new ServerConnector(server, 1, 1, h2);
connector.setIdleTimeout(10 * idleTimeout);
server.addConnector(connector);
- ServletContextHandler context = new ServletContextHandler(server, "/", true, false);
AtomicReference phaser = new AtomicReference<>();
- context.addServlet(new ServletHolder(new HttpServlet()
+ server.setHandler(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ public void process(Request request, Response response, Callback callback)
{
+ System.err.println("processing request " + request.getHttpURI().getPath());
phaser.get().countDown();
-
// Hold the dispatched requests enough for the idle requests to idle timeout.
sleep(2 * idleTimeout);
+ callback.succeeded();
}
- }), servletPath + "/*");
+ });
server.start();
prepareClient();
- client.start();
+ http2Client.start();
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
// Send requests until one is queued on the server but not dispatched.
+ int count = 0;
while (true)
{
+ ++count;
phaser.set(new CountDownLatch(1));
- MetaData.Request request = newRequest("GET", HttpFields.EMPTY);
+ MetaData.Request request = newRequest("GET", "/" + count, HttpFields.EMPTY);
HeadersFrame frame = new HeadersFrame(request, null, false);
FuturePromise promise = new FuturePromise<>();
client.newStream(frame, promise, new Stream.Listener.Adapter());
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/InterleavingTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/InterleavingTest.java
index 0fe1c1f3372..1bf567a5121 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/InterleavingTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/InterleavingTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
@@ -69,7 +69,7 @@ public class InterleavingTest extends AbstractTest
});
int maxFrameSize = Frame.DEFAULT_MAX_LENGTH + 1;
- Session session = newClient(new Session.Listener.Adapter()
+ Session session = newClientSession(new Session.Listener.Adapter()
{
@Override
public Map onPreface(Session session)
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/MaxConcurrentStreamsTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/MaxConcurrentStreamsTest.java
index 9e97cefac9d..9e8ab45df38 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/MaxConcurrentStreamsTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/MaxConcurrentStreamsTest.java
@@ -11,10 +11,11 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client.http;
+package org.eclipse.jetty.http2.tests;
import java.io.IOException;
import java.net.SocketAddress;
+import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -29,8 +30,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.IntStream;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.AbstractConnectionPool;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.HttpDestination;
@@ -48,6 +47,7 @@ import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
import org.eclipse.jetty.http2.client.HTTP2Client;
+import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
import org.eclipse.jetty.http2.frames.GoAwayFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.PingFrame;
@@ -80,7 +80,7 @@ public class MaxConcurrentStreamsTest extends AbstractTest
{
startServer(maxConcurrentStreams, handler);
prepareClient();
- client.start();
+ httpClient.start();
}
private void startServer(int maxConcurrentStreams, Handler handler) throws Exception
@@ -96,23 +96,24 @@ public class MaxConcurrentStreamsTest extends AbstractTest
public void testOneConcurrentStream() throws Exception
{
long sleep = 1000;
- start(1, new EmptyServerHandler()
+ start(1, new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
// Sleep a bit to allow the second request to be queued.
sleep(sleep);
+ callback.succeeded();
}
});
- client.setMaxConnectionsPerDestination(1);
+ httpClient.setMaxConnectionsPerDestination(1);
primeConnection();
CountDownLatch latch = new CountDownLatch(2);
// First request is sent immediately.
- client.newRequest("localhost", connector.getLocalPort())
+ httpClient.newRequest("localhost", connector.getLocalPort())
.path("/first")
.send(result ->
{
@@ -121,7 +122,7 @@ public class MaxConcurrentStreamsTest extends AbstractTest
});
// Second request is queued.
- client.newRequest("localhost", connector.getLocalPort())
+ httpClient.newRequest("localhost", connector.getLocalPort())
.path("/second")
.send(result ->
{
@@ -137,7 +138,14 @@ public class MaxConcurrentStreamsTest extends AbstractTest
public void testManyIterationsWithConcurrentStreams() throws Exception
{
int concurrency = 1;
- start(concurrency, new EmptyServerHandler());
+ start(concurrency, new Handler.Processor()
+ {
+ @Override
+ public void process(Request request, org.eclipse.jetty.server.Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
int iterations = 50;
IntStream.range(0, concurrency).parallel().forEach(i ->
@@ -145,7 +153,7 @@ public class MaxConcurrentStreamsTest extends AbstractTest
{
try
{
- ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
+ ContentResponse response = httpClient.newRequest("localhost", connector.getLocalPort())
.path("/" + i + "_" + j)
.timeout(5, TimeUnit.SECONDS)
.send();
@@ -163,12 +171,13 @@ public class MaxConcurrentStreamsTest extends AbstractTest
public void testSmallMaxConcurrentStreamsExceededOnClient() throws Exception
{
int maxConcurrentStreams = 1;
- startServer(maxConcurrentStreams, new EmptyServerHandler()
+ startServer(maxConcurrentStreams, new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
sleep(1000);
+ callback.succeeded();
}
});
@@ -178,7 +187,8 @@ public class MaxConcurrentStreamsTest extends AbstractTest
AtomicInteger connections = new AtomicInteger();
CountDownLatch latch = new CountDownLatch(1);
List failures = new ArrayList<>();
- client = new HttpClient(new HttpClientTransportOverHTTP2(new HTTP2Client())
+ prepareClient();
+ httpClient = new HttpClient(new HttpClientTransportOverHTTP2(new HTTP2Client())
{
@Override
protected void connect(SocketAddress address, ClientConnectionFactory factory, Session.Listener listener, Promise promise, Map context)
@@ -195,7 +205,7 @@ public class MaxConcurrentStreamsTest extends AbstractTest
// another connection since maxConcurrentStream=1.
if (connections.incrementAndGet() == 1)
{
- client.newRequest(host, port)
+ httpClient.newRequest(host, port)
.path("/2")
.send(result ->
{
@@ -219,12 +229,12 @@ public class MaxConcurrentStreamsTest extends AbstractTest
});
QueuedThreadPool clientExecutor = new QueuedThreadPool();
clientExecutor.setName("client");
- client.setExecutor(clientExecutor);
- client.start();
+ httpClient.setExecutor(clientExecutor);
+ httpClient.start();
// This request will be queued and establish the connection,
// which will trigger the send of the second request.
- var request = client.newRequest(host, port)
+ var request = httpClient.newRequest(host, port)
.path("/1")
.timeout(5, TimeUnit.SECONDS);
ContentResponse response = request.send();
@@ -232,7 +242,7 @@ public class MaxConcurrentStreamsTest extends AbstractTest
assertEquals(HttpStatus.OK_200, response.getStatus());
assertTrue(latch.await(5, TimeUnit.SECONDS), failures.toString());
assertEquals(2, connections.get());
- HttpDestination destination = (HttpDestination)client.resolveDestination(request);
+ HttpDestination destination = (HttpDestination)httpClient.resolveDestination(request);
AbstractConnectionPool connectionPool = (AbstractConnectionPool)destination.getConnectionPool();
assertEquals(2, connectionPool.getConnectionCount());
}
@@ -242,22 +252,23 @@ public class MaxConcurrentStreamsTest extends AbstractTest
{
int maxStreams = 2;
long sleep = 1000;
- start(maxStreams, new EmptyServerHandler()
+ start(maxStreams, new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
sleep(sleep);
+ callback.succeeded();
}
});
- client.setMaxConnectionsPerDestination(1);
+ httpClient.setMaxConnectionsPerDestination(1);
primeConnection();
// Send requests up to the max allowed.
for (int i = 0; i < maxStreams; ++i)
{
- client.newRequest("localhost", connector.getLocalPort())
+ httpClient.newRequest("localhost", connector.getLocalPort())
.path("/" + i)
.send(null);
}
@@ -265,7 +276,7 @@ public class MaxConcurrentStreamsTest extends AbstractTest
// Send the request in excess.
CountDownLatch latch = new CountDownLatch(1);
String path = "/excess";
- var request = client.newRequest("localhost", connector.getLocalPort()).path(path);
+ var request = httpClient.newRequest("localhost", connector.getLocalPort()).path(path);
request.send(result ->
{
if (result.getResponse().getStatus() == HttpStatus.OK_200)
@@ -273,7 +284,7 @@ public class MaxConcurrentStreamsTest extends AbstractTest
});
// The last exchange should remain in the queue.
- HttpDestination destination = (HttpDestination)client.resolveDestination(request);
+ HttpDestination destination = (HttpDestination)httpClient.resolveDestination(request);
assertEquals(1, destination.getHttpExchanges().size());
assertEquals(path, destination.getHttpExchanges().peek().getRequest().getPath());
@@ -284,26 +295,27 @@ public class MaxConcurrentStreamsTest extends AbstractTest
public void testAbortedWhileQueued() throws Exception
{
long sleep = 1000;
- start(1, new EmptyServerHandler()
+ start(1, new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
sleep(sleep);
+ callback.succeeded();
}
});
- client.setMaxConnectionsPerDestination(1);
+ httpClient.setMaxConnectionsPerDestination(1);
primeConnection();
// Send a request that is aborted while queued.
- client.newRequest("localhost", connector.getLocalPort())
+ httpClient.newRequest("localhost", connector.getLocalPort())
.path("/aborted")
.onRequestQueued(request -> request.abort(new Exception()))
.send(null);
// Must be able to send another request.
- ContentResponse response = client.newRequest("localhost", connector.getLocalPort()).path("/check").send();
+ ContentResponse response = httpClient.newRequest("localhost", connector.getLocalPort()).path("/check").send();
assertEquals(HttpStatus.OK_200, response.getStatus());
}
@@ -313,21 +325,22 @@ public class MaxConcurrentStreamsTest extends AbstractTest
{
int maxConcurrent = 10;
long sleep = 500;
- start(maxConcurrent, new EmptyServerHandler()
+ start(maxConcurrent, new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
sleep(sleep);
+ callback.succeeded();
}
});
- client.setMaxConnectionsPerDestination(1);
+ httpClient.setMaxConnectionsPerDestination(1);
// The first request will open the connection, the others will be queued.
CountDownLatch latch = new CountDownLatch(maxConcurrent);
for (int i = 0; i < maxConcurrent; ++i)
{
- client.newRequest("localhost", connector.getLocalPort())
+ httpClient.newRequest("localhost", connector.getLocalPort())
.path("/" + i)
.send(result -> latch.countDown());
}
@@ -340,12 +353,12 @@ public class MaxConcurrentStreamsTest extends AbstractTest
public void testManyConcurrentRequestsWithSmallConcurrentStreams() throws Exception
{
byte[] data = new byte[64 * 1024];
- start(1, new EmptyServerHandler()
+ start(1, new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- response.getOutputStream().write(data);
+ response.write(true, callback, ByteBuffer.wrap(data));
}
});
@@ -353,13 +366,13 @@ public class MaxConcurrentStreamsTest extends AbstractTest
int runs = 1;
int iterations = 32;
- client.setMaxConnectionsPerDestination(32768);
- client.setMaxRequestsQueuedPerDestination(1024 * 1024);
- client.getTransport().setConnectionPoolFactory(destination ->
+ httpClient.setMaxConnectionsPerDestination(32768);
+ httpClient.setMaxRequestsQueuedPerDestination(1024 * 1024);
+ httpClient.getTransport().setConnectionPoolFactory(destination ->
{
try
{
- MultiplexConnectionPool pool = new MultiplexConnectionPool(destination, client.getMaxConnectionsPerDestination(), false, destination, 1);
+ MultiplexConnectionPool pool = new MultiplexConnectionPool(destination, httpClient.getMaxConnectionsPerDestination(), false, destination, 1);
pool.preCreateConnections(parallelism * 2).get();
return pool;
}
@@ -369,7 +382,7 @@ public class MaxConcurrentStreamsTest extends AbstractTest
}
});
// Prime the destination to pre-create connections.
- client.GET("http://localhost:" + connector.getLocalPort());
+ httpClient.GET("http://localhost:" + connector.getLocalPort());
int total = parallelism * runs * iterations;
CountDownLatch latch = new CountDownLatch(total);
@@ -380,7 +393,7 @@ public class MaxConcurrentStreamsTest extends AbstractTest
{
for (int k = 0; k < iterations; ++k)
{
- client.newRequest("localhost", connector.getLocalPort())
+ httpClient.newRequest("localhost", connector.getLocalPort())
.path("/" + i + "_" + j + "_" + k)
.send(result ->
{
@@ -399,19 +412,20 @@ public class MaxConcurrentStreamsTest extends AbstractTest
public void testTwoStreamsFirstTimesOut() throws Exception
{
long timeout = 1000;
- start(1, new EmptyServerHandler()
+ start(1, new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- if (target.endsWith("/1"))
+ if (request.getPathInContext().endsWith("/1"))
sleep(2 * timeout);
+ callback.succeeded();
}
});
- client.setMaxConnectionsPerDestination(1);
+ httpClient.setMaxConnectionsPerDestination(1);
CountDownLatch latch = new CountDownLatch(1);
- client.newRequest("localhost", connector.getLocalPort())
+ httpClient.newRequest("localhost", connector.getLocalPort())
.path("/1")
.timeout(timeout, TimeUnit.MILLISECONDS)
.send(result ->
@@ -420,7 +434,7 @@ public class MaxConcurrentStreamsTest extends AbstractTest
latch.countDown();
});
- ContentResponse response2 = client.newRequest("localhost", connector.getLocalPort())
+ ContentResponse response2 = httpClient.newRequest("localhost", connector.getLocalPort())
.path("/2")
.send();
@@ -440,25 +454,22 @@ public class MaxConcurrentStreamsTest extends AbstractTest
MetaData.Request request = (MetaData.Request)frame.getMetaData();
switch (request.getURI().getPath())
{
- case "/1":
+ case "/1" ->
{
// Do not return to cause TCP congestion.
assertTrue(awaitLatch(request1Latch, 15, TimeUnit.SECONDS));
MetaData.Response response1 = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, HttpFields.EMPTY);
stream.headers(new HeadersFrame(stream.getId(), response1, null, true), Callback.NOOP);
- break;
}
- case "/3":
+ case "/3" ->
{
MetaData.Response response3 = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, HttpFields.EMPTY);
stream.headers(new HeadersFrame(stream.getId(), response3, null, true), Callback.NOOP);
- break;
}
- default:
+ default ->
{
MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.INTERNAL_SERVER_ERROR_500, HttpFields.EMPTY);
stream.headers(new HeadersFrame(stream.getId(), response, null, true), Callback.NOOP);
- break;
}
}
// Return a Stream listener that consumes the content.
@@ -476,7 +487,8 @@ public class MaxConcurrentStreamsTest extends AbstractTest
prepareClient();
AtomicReference clientEndPointRef = new AtomicReference<>();
CountDownLatch clientEndPointLatch = new CountDownLatch(1);
- client = new HttpClient(new HttpClientTransportOverHTTP2(http2Client)
+ prepareClient();
+ httpClient = new HttpClient(new HttpClientTransportOverHTTP2(http2Client)
{
@Override
public Connection newConnection(EndPoint endPoint, Map context) throws IOException
@@ -486,12 +498,12 @@ public class MaxConcurrentStreamsTest extends AbstractTest
return super.newConnection(endPoint, context);
}
});
- client.setMaxConnectionsPerDestination(1);
- client.start();
+ httpClient.setMaxConnectionsPerDestination(1);
+ httpClient.start();
// First request must cause TCP congestion.
CountDownLatch response1Latch = new CountDownLatch(1);
- client.newRequest("localhost", connector.getLocalPort()).path("/1")
+ httpClient.newRequest("localhost", connector.getLocalPort()).path("/1")
.body(new BytesRequestContent(new byte[64 * 1024 * 1024]))
.send(result ->
{
@@ -514,14 +526,14 @@ public class MaxConcurrentStreamsTest extends AbstractTest
Thread.sleep(1000);
// Second request cannot be sent due to TCP congestion and times out.
- assertThrows(TimeoutException.class, () -> client.newRequest("localhost", connector.getLocalPort())
+ assertThrows(TimeoutException.class, () -> httpClient.newRequest("localhost", connector.getLocalPort())
.path("/2")
.timeout(1000, TimeUnit.MILLISECONDS)
.send());
// Third request should succeed.
CountDownLatch response3Latch = new CountDownLatch(1);
- client.newRequest("localhost", connector.getLocalPort())
+ httpClient.newRequest("localhost", connector.getLocalPort())
.path("/3")
.send(result ->
{
@@ -555,25 +567,23 @@ public class MaxConcurrentStreamsTest extends AbstractTest
MetaData.Request request = (MetaData.Request)frame.getMetaData();
switch (request.getURI().getPath())
{
- case "/prime":
+ case "/prime" ->
{
session1 = stream.getSession();
// Send another request from here to force the opening of the 2nd connection.
- client.newRequest("localhost", connector.getLocalPort()).path("/prime2").send(result ->
+ httpClient.newRequest("localhost", connector.getLocalPort()).path("/prime2").send(result ->
{
MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, result.getResponse().getStatus(), HttpFields.EMPTY);
stream.headers(new HeadersFrame(stream.getId(), response, null, true), Callback.NOOP);
});
- break;
}
- case "/prime2":
+ case "/prime2" ->
{
session2 = stream.getSession();
MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, HttpFields.EMPTY);
stream.headers(new HeadersFrame(stream.getId(), response, null, true), Callback.NOOP);
- break;
}
- case "/update_max_streams":
+ case "/update_max_streams" ->
{
Session session = stream.getSession() == session1 ? session2 : session1;
Map settings = new HashMap<>();
@@ -581,14 +591,12 @@ public class MaxConcurrentStreamsTest extends AbstractTest
session.settings(new SettingsFrame(settings, false), Callback.NOOP);
MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, HttpFields.EMPTY);
stream.headers(new HeadersFrame(stream.getId(), response, null, true), Callback.NOOP);
- break;
}
- default:
+ default ->
{
sleep(processing);
MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, HttpFields.EMPTY);
stream.headers(new HeadersFrame(stream.getId(), response, null, true), Callback.NOOP);
- break;
}
}
return null;
@@ -598,8 +606,8 @@ public class MaxConcurrentStreamsTest extends AbstractTest
prepareServer(http2);
server.start();
prepareClient();
- client.setMaxConnectionsPerDestination(2);
- client.start();
+ httpClient.setMaxConnectionsPerDestination(2);
+ httpClient.start();
// Prime the 2 connections.
primeConnection();
@@ -607,13 +615,13 @@ public class MaxConcurrentStreamsTest extends AbstractTest
String host = "localhost";
int port = connector.getLocalPort();
- assertEquals(1, client.getDestinations().size());
- HttpDestination destination = (HttpDestination)client.getDestinations().get(0);
+ assertEquals(1, httpClient.getDestinations().size());
+ HttpDestination destination = (HttpDestination)httpClient.getDestinations().get(0);
AbstractConnectionPool pool = (AbstractConnectionPool)destination.getConnectionPool();
assertEquals(2, pool.getConnectionCount());
// Send a request on one connection, which sends back a SETTINGS frame on the other connection.
- ContentResponse response = client.newRequest(host, port)
+ ContentResponse response = httpClient.newRequest(host, port)
.path("/update_max_streams")
.send();
assertEquals(HttpStatus.OK_200, response.getStatus());
@@ -623,7 +631,7 @@ public class MaxConcurrentStreamsTest extends AbstractTest
CountDownLatch latch = new CountDownLatch(count);
for (int i = 0; i < count; ++i)
{
- client.newRequest(host, port)
+ httpClient.newRequest(host, port)
.path("/" + i)
.send(result ->
{
@@ -648,7 +656,7 @@ public class MaxConcurrentStreamsTest extends AbstractTest
private void primeConnection() throws Exception
{
// Prime the connection so that the maxConcurrentStream setting arrives to the client.
- client.newRequest("localhost", connector.getLocalPort()).path("/prime").send();
+ httpClient.newRequest("localhost", connector.getLocalPort()).path("/prime").send();
// Wait for the server to clean up and remove the stream that primes the connection.
sleep(1000);
}
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/MaxPushedStreamsTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/MaxPushedStreamsTest.java
index 5bacd035932..25e3132da99 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/MaxPushedStreamsTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/MaxPushedStreamsTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.util.ArrayList;
import java.util.List;
@@ -26,8 +26,6 @@ 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.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
@@ -35,6 +33,8 @@ import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.PushPromiseFrame;
import org.eclipse.jetty.http2.frames.ResetFrame;
+import org.eclipse.jetty.http2.internal.ErrorCode;
+import org.eclipse.jetty.http2.internal.HTTP2Session;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FuturePromise;
@@ -114,9 +114,9 @@ public class MaxPushedStreamsTest extends AbstractTest
return null;
}
});
- client.setMaxConcurrentPushedStreams(maxPushed);
+ http2Client.setMaxConcurrentPushedStreams(maxPushed);
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request request = newRequest("GET", HttpFields.EMPTY);
CountDownLatch responseLatch = new CountDownLatch(1);
session.newStream(new HeadersFrame(request, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/MultiplexedConnectionPoolTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/MultiplexedConnectionPoolTest.java
index 2803aaa54b3..a4c31de095c 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/MultiplexedConnectionPoolTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/MultiplexedConnectionPoolTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client.http;
+package org.eclipse.jetty.http2.tests;
import java.util.ArrayList;
import java.util.List;
@@ -22,9 +22,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.ConnectionPool;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.HttpClientTransport;
@@ -32,19 +29,20 @@ import org.eclipse.jetty.client.MultiplexConnectionPool;
import org.eclipse.jetty.client.api.Connection;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.http2.client.HTTP2Client;
+import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
import org.eclipse.jetty.io.ClientConnector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Pool;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import static org.awaitility.Awaitility.await;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -54,7 +52,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
// Sibling of ConnectionPoolTest, but using H2 to multiplex connections.
public class MultiplexedConnectionPoolTest
{
- private static final Logger LOG = LoggerFactory.getLogger(MultiplexedConnectionPoolTest.class);
private static final int MAX_MULTIPLEX = 2;
private Server server;
@@ -132,30 +129,19 @@ public class MultiplexedConnectionPoolTest
CountDownLatch[] reqExecutingLatches = new CountDownLatch[] {new CountDownLatch(1), new CountDownLatch(1), new CountDownLatch(1)};
CountDownLatch[] reqExecutedLatches = new CountDownLatch[] {new CountDownLatch(1), new CountDownLatch(1), new CountDownLatch(1)};
CountDownLatch[] reqFinishingLatches = new CountDownLatch[] {new CountDownLatch(1), new CountDownLatch(1), new CountDownLatch(1)};
- startServer(new EmptyServerHandler()
+ startServer(new Handler.Processor()
{
@Override
- protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
- int req = Integer.parseInt(target.substring(1));
- try
- {
- LOG.debug("req {} is executing", req);
- reqExecutingLatches[req].countDown();
- Thread.sleep(250);
- reqExecutedLatches[req].countDown();
- LOG.debug("req {} executed", req);
+ int req = Integer.parseInt(request.getPathInContext().substring(1));
+ reqExecutingLatches[req].countDown();
+ Thread.sleep(250);
+ reqExecutedLatches[req].countDown();
- assertTrue(reqFinishingLatches[req].await(5, TimeUnit.SECONDS));
+ assertTrue(reqFinishingLatches[req].await(5, TimeUnit.SECONDS));
- response.getWriter().println("req " + req + " executed");
- response.getWriter().flush();
- LOG.debug("req {} successful", req);
- }
- catch (Exception e)
- {
- throw new ServletException(e);
- }
+ response.write(true, callback, "req " + req + " executed");
}
});
@@ -170,19 +156,15 @@ public class MultiplexedConnectionPoolTest
sendRequest(reqClientSuccessLatches, 0);
// wait until handler is executing
assertTrue(reqExecutingLatches[0].await(5, TimeUnit.SECONDS));
- LOG.debug("req 0 executing");
sendRequest(reqClientSuccessLatches, 1);
// wait until handler executed sleep
assertTrue(reqExecutedLatches[1].await(5, TimeUnit.SECONDS));
- LOG.debug("req 1 executed");
// Now the pool contains one connection that is expired but in use by 2 threads.
sendRequest(reqClientSuccessLatches, 2);
- LOG.debug("req2 sent");
assertTrue(reqExecutingLatches[2].await(5, TimeUnit.SECONDS));
- LOG.debug("req2 executing");
// The 3rd request has tried the expired request and marked it as closed as it has expired, then used a 2nd one.
@@ -243,21 +225,13 @@ public class MultiplexedConnectionPoolTest
return pool;
});
- startServer(new EmptyServerHandler()
+ startServer(new Handler.Processor()
{
@Override
- protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException
+ public void process(Request request, Response response, Callback callback)
{
- int req = Integer.parseInt(target.substring(1));
- try
- {
- response.getWriter().println("req " + req + " executed");
- response.getWriter().flush();
- }
- catch (Exception e)
- {
- throw new ServletException(e);
- }
+ int req = Integer.parseInt(request.getPathInContext().substring(1));
+ response.write(true, callback, "req " + req + " executed");
}
}, 64, 1L);
@@ -331,7 +305,14 @@ public class MultiplexedConnectionPoolTest
return connectionPool;
});
- startServer(new EmptyServerHandler());
+ startServer(new Handler.Processor()
+ {
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
HttpClientTransport transport = new HttpClientTransportOverHTTP2(new HTTP2Client());
transport.setConnectionPoolFactory(factory.factory);
@@ -393,24 +374,17 @@ public class MultiplexedConnectionPoolTest
Semaphore handlerSignalingSemaphore = new Semaphore(0);
Semaphore handlerWaitingSemaphore = new Semaphore(0);
- startServer(new EmptyServerHandler()
+ startServer(new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
- if (!target.equals("/block"))
- return;
-
- handlerSignalingSemaphore.release();
-
- try
+ if (request.getPathInContext().equals("/block"))
{
+ handlerSignalingSemaphore.release();
handlerWaitingSemaphore.acquire();
}
- catch (Exception e)
- {
- throw new ServletException(e);
- }
+ callback.succeeded();
}
});
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PingTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PingTest.java
index cc7bea7ff53..4dcc18b3f4d 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PingTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PingTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
@@ -36,7 +36,7 @@ public class PingTest extends AbstractTest
final byte[] payload = new byte[8];
new Random().nextBytes(payload);
final CountDownLatch latch = new CountDownLatch(1);
- Session session = newClient(new Session.Listener.Adapter()
+ Session session = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onPing(Session session, PingFrame frame)
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PrefaceTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PrefaceTest.java
index c0936ec689d..e4a968458f9 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PrefaceTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PrefaceTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.io.InputStream;
import java.io.OutputStream;
@@ -36,17 +36,18 @@ 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.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
import org.eclipse.jetty.http2.frames.FrameType;
+import org.eclipse.jetty.http2.frames.GoAwayFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.PingFrame;
import org.eclipse.jetty.http2.frames.PrefaceFrame;
import org.eclipse.jetty.http2.frames.SettingsFrame;
-import org.eclipse.jetty.http2.generator.Generator;
-import org.eclipse.jetty.http2.parser.Parser;
+import org.eclipse.jetty.http2.internal.ErrorCode;
+import org.eclipse.jetty.http2.internal.generator.Generator;
+import org.eclipse.jetty.http2.internal.parser.Parser;
import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.EndPoint;
@@ -90,7 +91,7 @@ public class PrefaceTest extends AbstractTest
}
});
- Session session = newClient(new Session.Listener.Adapter()
+ Session session = newClientSession(new Session.Listener.Adapter()
{
@Override
public Map onPreface(Session session)
@@ -146,7 +147,7 @@ public class PrefaceTest extends AbstractTest
}
});
- ByteBufferPool byteBufferPool = client.getByteBufferPool();
+ ByteBufferPool byteBufferPool = http2Client.getByteBufferPool();
try (SocketChannel socket = SocketChannel.open())
{
socket.connect(new InetSocketAddress("localhost", connector.getLocalPort()));
@@ -161,9 +162,10 @@ public class PrefaceTest extends AbstractTest
generator.control(lease, new PingFrame(true));
List buffers = lease.getByteBuffers();
- socket.write(buffers.toArray(new ByteBuffer[buffers.size()]));
+ socket.write(buffers.toArray(new ByteBuffer[0]));
Queue settings = new ArrayDeque<>();
+ AtomicBoolean closed = new AtomicBoolean();
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
{
@Override
@@ -171,6 +173,12 @@ public class PrefaceTest extends AbstractTest
{
settings.offer(frame);
}
+
+ @Override
+ public void onGoAway(GoAwayFrame frame)
+ {
+ closed.set(true);
+ }
}, 4096, 8192);
parser.init(UnaryOperator.identity());
@@ -179,10 +187,12 @@ public class PrefaceTest extends AbstractTest
{
BufferUtil.clearToFill(buffer);
int read = socket.read(buffer);
- BufferUtil.flipToFlush(buffer, 0);
if (read < 0)
break;
+ BufferUtil.flipToFlush(buffer, 0);
parser.parse(buffer);
+ if (closed.get())
+ break;
}
assertEquals(2, settings.size());
@@ -288,7 +298,7 @@ public class PrefaceTest extends AbstractTest
clientSettings.put(SettingsFrame.ENABLE_PUSH, 1);
generator.control(lease, new SettingsFrame(clientSettings, false));
List buffers = lease.getByteBuffers();
- socket.write(buffers.toArray(new ByteBuffer[buffers.size()]));
+ socket.write(buffers.toArray(new ByteBuffer[0]));
// However, we should not call onPreface() again.
assertFalse(serverPrefaceLatch.get().await(1, TimeUnit.SECONDS));
@@ -340,12 +350,12 @@ public class PrefaceTest extends AbstractTest
try (ServerSocket server = new ServerSocket(0))
{
prepareClient();
- client.start();
+ http2Client.start();
CountDownLatch failureLatch = new CountDownLatch(1);
Promise.Completable promise = new Promise.Completable<>();
InetSocketAddress address = new InetSocketAddress("localhost", server.getLocalPort());
- client.connect(address, new Session.Listener.Adapter()
+ http2Client.connect(address, new Session.Listener.Adapter()
{
@Override
public void onFailure(Session session, Throwable failure)
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PriorKnowledgeHTTP2OverTLSTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PriorKnowledgeHTTP2OverTLSTest.java
index 768cd1a8dcd..90e9c214fb3 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PriorKnowledgeHTTP2OverTLSTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PriorKnowledgeHTTP2OverTLSTest.java
@@ -11,15 +11,16 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.net.InetSocketAddress;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.http.HttpFields;
+import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
@@ -27,6 +28,8 @@ import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.HTTP2Cipher;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
+import org.eclipse.jetty.http2.client.HTTP2Client;
+import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
import org.eclipse.jetty.io.ClientConnector;
@@ -34,11 +37,12 @@ import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
@@ -52,7 +56,8 @@ public class PriorKnowledgeHTTP2OverTLSTest
{
private Server server;
private ServerConnector connector;
- private HTTP2Client client;
+ private HTTP2Client http2Client;
+ private HttpClient httpClient;
private void start(Handler handler) throws Exception
{
@@ -82,15 +87,17 @@ public class PriorKnowledgeHTTP2OverTLSTest
clientThreads.setName("client");
clientConnector.setExecutor(clientThreads);
clientConnector.setSslContextFactory(newClientSslContextFactory());
- client = new HTTP2Client(clientConnector);
- client.setUseALPN(false);
- client.start();
+ http2Client = new HTTP2Client(clientConnector);
+ HttpClientTransportOverHTTP2 transport = new HttpClientTransportOverHTTP2(http2Client);
+ transport.setUseALPN(false);
+ httpClient = new HttpClient(transport);
+ httpClient.start();
}
@AfterEach
public void dispose() throws Exception
{
- LifeCycle.stop(client);
+ LifeCycle.stop(httpClient);
LifeCycle.stop(server);
}
@@ -118,21 +125,21 @@ public class PriorKnowledgeHTTP2OverTLSTest
}
@Test
- public void testDirectHTTP2OverTLS() throws Exception
+ public void testDirectHTTP2OverTLSWithHTTP2Client() throws Exception
{
// The client knows a priori that the server speaks h2 on a particular port.
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, Response response, Callback callback)
{
- baseRequest.setHandled(true);
+ callback.succeeded();
}
});
int port = connector.getLocalPort();
- MetaData.Response response = client.connect(client.getClientConnector().getSslContextFactory(), new InetSocketAddress("localhost", port), new Session.Listener.Adapter())
+ MetaData.Response response = http2Client.connect(http2Client.getClientConnector().getSslContextFactory(), new InetSocketAddress("localhost", port), new Session.Listener.Adapter())
.thenCompose(session ->
{
CompletableFuture responsePromise = new CompletableFuture<>();
@@ -155,4 +162,26 @@ public class PriorKnowledgeHTTP2OverTLSTest
assertEquals(HttpStatus.OK_200, response.getStatus());
}
+
+ @Test
+ public void testDirectHTTP2OverTLSWithHttpClient() throws Exception
+ {
+ // The client knows a priori that the server speaks h2 on a particular port.
+
+ start(new Handler.Processor()
+ {
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
+
+ ContentResponse response = httpClient.newRequest("localhost", connector.getLocalPort())
+ .scheme(HttpScheme.HTTPS.asString())
+ .timeout(5, TimeUnit.SECONDS)
+ .send();
+
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ }
}
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PriorityTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PriorityTest.java
index 6e54afd8958..3b044689c20 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PriorityTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PriorityTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -50,14 +50,14 @@ public class PriorityTest extends AbstractTest
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
int streamId = session.priority(new PriorityFrame(0, 13, false), Callback.NOOP);
assertTrue(streamId > 0);
CountDownLatch latch = new CountDownLatch(2);
MetaData metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame headersFrame = new HeadersFrame(streamId, metaData, null, true);
- session.newStream(headersFrame, new Promise.Adapter()
+ session.newStream(headersFrame, new Promise.Adapter<>()
{
@Override
public void succeeded(Stream result)
@@ -116,7 +116,7 @@ public class PriorityTest extends AbstractTest
}
};
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData metaData1 = newRequest("GET", "/one", HttpFields.EMPTY);
HeadersFrame headersFrame1 = new HeadersFrame(metaData1, null, true);
FuturePromise promise1 = new FuturePromise<>();
@@ -164,7 +164,7 @@ public class PriorityTest extends AbstractTest
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData metaData = newRequest("GET", "/one", HttpFields.EMPTY);
HeadersFrame headersFrame = new HeadersFrame(metaData, priorityFrame, true);
session.newStream(headersFrame, new Promise.Adapter<>(), new Stream.Listener.Adapter()
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ProxyProtocolTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ProxyProtocolTest.java
index 5c70246d1e7..01d54776889 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ProxyProtocolTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ProxyProtocolTest.java
@@ -11,9 +11,8 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
-import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
@@ -21,9 +20,6 @@ import java.nio.charset.StandardCharsets;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpURI;
@@ -31,6 +27,7 @@ import org.eclipse.jetty.http.HttpVersion;
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.client.HTTP2Client;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory;
import org.eclipse.jetty.io.EndPoint;
@@ -38,13 +35,13 @@ import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.ProxyConnectionFactory;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FuturePromise;
import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.StringUtil;
-import org.eclipse.jetty.util.TypeUtil;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
@@ -84,24 +81,16 @@ public class ProxyProtocolTest
@Test
public void testProxyGetV1() throws Exception
{
- startServer(new AbstractHandler()
+ startServer(new Handler.Processor()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ public void process(Request request, Response response, Callback callback)
{
- try
- {
- assertEquals("1.2.3.4", request.getRemoteAddr());
- assertEquals(1111, request.getRemotePort());
- assertEquals("5.6.7.8", request.getLocalAddr());
- assertEquals(2222, request.getLocalPort());
- }
- catch (Throwable th)
- {
- th.printStackTrace();
- response.setStatus(500);
- }
- baseRequest.setHandled(true);
+ assertEquals("1.2.3.4", Request.getRemoteAddr(request));
+ assertEquals(1111, Request.getRemotePort(request));
+ assertEquals("5.6.7.8", Request.getLocalAddr(request));
+ assertEquals(2222, Request.getLocalPort(request));
+ callback.succeeded();
}
});
@@ -135,28 +124,20 @@ public class ProxyProtocolTest
@Test
public void testProxyGetV2() throws Exception
{
- startServer(new AbstractHandler()
+ startServer(new Handler.Processor()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ public void process(Request request, Response response, Callback callback)
{
- try
- {
- assertEquals("10.0.0.4", request.getRemoteAddr());
- assertEquals(33824, request.getRemotePort());
- assertEquals("10.0.0.5", request.getLocalAddr());
- assertEquals(8888, request.getLocalPort());
- EndPoint endPoint = baseRequest.getHttpChannel().getEndPoint();
- assertThat(endPoint, instanceOf(ProxyConnectionFactory.ProxyEndPoint.class));
- ProxyConnectionFactory.ProxyEndPoint proxyEndPoint = (ProxyConnectionFactory.ProxyEndPoint)endPoint;
- assertNotNull(proxyEndPoint.getAttribute(ProxyConnectionFactory.TLS_VERSION));
- }
- catch (Throwable th)
- {
- th.printStackTrace();
- response.setStatus(500);
- }
- baseRequest.setHandled(true);
+ assertEquals("10.0.0.4", Request.getRemoteAddr(request));
+ assertEquals(33824, Request.getRemotePort(request));
+ assertEquals("10.0.0.5", Request.getLocalAddr(request));
+ assertEquals(8888, Request.getLocalPort(request));
+ EndPoint endPoint = request.getConnectionMetaData().getConnection().getEndPoint();
+ assertThat(endPoint, instanceOf(ProxyConnectionFactory.ProxyEndPoint.class));
+ ProxyConnectionFactory.ProxyEndPoint proxyEndPoint = (ProxyConnectionFactory.ProxyEndPoint)endPoint;
+ assertNotNull(proxyEndPoint.getAttribute(ProxyConnectionFactory.TLS_VERSION));
+ callback.succeeded();
}
});
@@ -165,7 +146,7 @@ public class ProxyProtocolTest
request1 = StringUtil.strip(request1, " ");
SocketChannel channel = SocketChannel.open();
channel.connect(new InetSocketAddress("localhost", connector.getLocalPort()));
- channel.write(ByteBuffer.wrap(TypeUtil.fromHexString(request1)));
+ channel.write(ByteBuffer.wrap(StringUtil.fromHexString(request1)));
FuturePromise promise = new FuturePromise<>();
client.accept(null, channel, new Session.Listener.Adapter(), promise);
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ProxyTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ProxyTest.java
index 8283d9473bc..06aa001f630 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ProxyTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ProxyTest.java
@@ -11,204 +11,180 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import jakarta.servlet.http.HttpServlet;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.http.HostPortHttpField;
-import org.eclipse.jetty.http.HttpFields;
-import org.eclipse.jetty.http.HttpScheme;
-import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.http.HttpVersion;
-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.DataFrame;
-import org.eclipse.jetty.http2.frames.HeadersFrame;
-import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
-import org.eclipse.jetty.proxy.AsyncProxyServlet;
-import org.eclipse.jetty.server.HttpConfiguration;
-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.Callback;
-import org.eclipse.jetty.util.FuturePromise;
-import org.eclipse.jetty.util.Promise;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+// TODO: move to ee9 with ProxyServlet support
+@Disabled("move to ee9")
public class ProxyTest
{
- private HTTP2Client client;
- private Server proxy;
- private ServerConnector proxyConnector;
- private Server server;
- private ServerConnector serverConnector;
-
- private void startServer(HttpServlet servlet) throws Exception
- {
- QueuedThreadPool serverPool = new QueuedThreadPool();
- serverPool.setName("server");
- server = new Server(serverPool);
- serverConnector = new ServerConnector(server);
- server.addConnector(serverConnector);
-
- ServletContextHandler appCtx = new ServletContextHandler(server, "/", true, false);
- ServletHolder appServletHolder = new ServletHolder(servlet);
- appCtx.addServlet(appServletHolder, "/*");
-
- server.start();
- }
-
- private void startProxy(HttpServlet proxyServlet, Map initParams) throws Exception
- {
- QueuedThreadPool proxyPool = new QueuedThreadPool();
- proxyPool.setName("proxy");
- proxy = new Server(proxyPool);
-
- HttpConfiguration configuration = new HttpConfiguration();
- configuration.setSendDateHeader(false);
- configuration.setSendServerVersion(false);
- String value = initParams.get("outputBufferSize");
- if (value != null)
- configuration.setOutputBufferSize(Integer.parseInt(value));
- proxyConnector = new ServerConnector(proxy, new HTTP2ServerConnectionFactory(configuration));
- proxy.addConnector(proxyConnector);
-
- ServletContextHandler proxyContext = new ServletContextHandler(proxy, "/", true, false);
- ServletHolder proxyServletHolder = new ServletHolder(proxyServlet);
- proxyServletHolder.setInitParameters(initParams);
- proxyContext.addServlet(proxyServletHolder, "/*");
-
- proxy.start();
- }
-
- private void startClient() throws Exception
- {
- QueuedThreadPool clientExecutor = new QueuedThreadPool();
- clientExecutor.setName("client");
- client = new HTTP2Client();
- client.setExecutor(clientExecutor);
- client.start();
- }
-
- private Session newClient(Session.Listener listener) throws Exception
- {
- String host = "localhost";
- int port = proxyConnector.getLocalPort();
- InetSocketAddress address = new InetSocketAddress(host, port);
- FuturePromise promise = new FuturePromise<>();
- client.connect(address, listener, promise);
- return promise.get(5, TimeUnit.SECONDS);
- }
-
- private MetaData.Request newRequest(String method, String path, HttpFields fields)
- {
- String host = "localhost";
- int port = proxyConnector.getLocalPort();
- String authority = host + ":" + port;
- return new MetaData.Request(method, HttpScheme.HTTP.asString(), new HostPortHttpField(authority), path, HttpVersion.HTTP_2, fields, -1);
- }
-
- @AfterEach
- public void dispose() throws Exception
- {
- client.stop();
- proxy.stop();
- server.stop();
- }
-
@Test
- public void testHTTPVersion() throws Exception
+ public void test()
{
- startServer(new HttpServlet()
- {
- @Override
- protected void service(HttpServletRequest request, HttpServletResponse response)
- {
- assertEquals(HttpVersion.HTTP_1_1.asString(), request.getProtocol());
- }
- });
- Map params = new HashMap<>();
- params.put("proxyTo", "http://localhost:" + serverConnector.getLocalPort());
- startProxy(new AsyncProxyServlet.Transparent(), params);
- startClient();
-
- CountDownLatch clientLatch = new CountDownLatch(1);
- Session session = newClient(new Session.Listener.Adapter());
- MetaData.Request metaData = newRequest("GET", "/", HttpFields.EMPTY);
- HeadersFrame frame = new HeadersFrame(metaData, null, true);
- session.newStream(frame, new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onHeaders(Stream stream, HeadersFrame frame)
- {
- assertTrue(frame.isEndStream());
- MetaData.Response response = (MetaData.Response)frame.getMetaData();
- assertEquals(HttpStatus.OK_200, response.getStatus());
- clientLatch.countDown();
- }
- });
-
- assertTrue(clientLatch.await(5, TimeUnit.SECONDS));
+ fail();
}
- @Test
- public void testServerBigDownloadSlowClient() throws Exception
- {
- CountDownLatch serverLatch = new CountDownLatch(1);
- byte[] content = new byte[1024 * 1024];
- startServer(new HttpServlet()
- {
- @Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException
- {
- response.getOutputStream().write(content);
- serverLatch.countDown();
- }
- });
- Map params = new HashMap<>();
- params.put("proxyTo", "http://localhost:" + serverConnector.getLocalPort());
- startProxy(new AsyncProxyServlet.Transparent(), params);
- startClient();
-
- CountDownLatch clientLatch = new CountDownLatch(1);
- Session session = newClient(new Session.Listener.Adapter());
- MetaData.Request metaData = newRequest("GET", "/", HttpFields.EMPTY);
- HeadersFrame frame = new HeadersFrame(metaData, null, true);
- session.newStream(frame, new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- try
- {
- TimeUnit.MILLISECONDS.sleep(1);
- callback.succeeded();
- if (frame.isEndStream())
- clientLatch.countDown();
- }
- catch (InterruptedException x)
- {
- callback.failed(x);
- }
- }
- });
-
- assertTrue(serverLatch.await(15, TimeUnit.SECONDS));
- assertTrue(clientLatch.await(15, TimeUnit.SECONDS));
- }
+// private HTTP2Client client;
+// private Server proxy;
+// private ServerConnector proxyConnector;
+// private Server server;
+// private ServerConnector serverConnector;
+//
+// private void startServer(HttpServlet servlet) throws Exception
+// {
+// QueuedThreadPool serverPool = new QueuedThreadPool();
+// serverPool.setName("server");
+// server = new Server(serverPool);
+// serverConnector = new ServerConnector(server);
+// server.addConnector(serverConnector);
+//
+// ServletContextHandler appCtx = new ServletContextHandler(server, "/", true, false);
+// ServletHolder appServletHolder = new ServletHolder(servlet);
+// appCtx.addServlet(appServletHolder, "/*");
+//
+// server.start();
+// }
+//
+// private void startProxy(HttpServlet proxyServlet, Map initParams) throws Exception
+// {
+// QueuedThreadPool proxyPool = new QueuedThreadPool();
+// proxyPool.setName("proxy");
+// proxy = new Server(proxyPool);
+//
+// HttpConfiguration configuration = new HttpConfiguration();
+// configuration.setSendDateHeader(false);
+// configuration.setSendServerVersion(false);
+// String value = initParams.get("outputBufferSize");
+// if (value != null)
+// configuration.setOutputBufferSize(Integer.parseInt(value));
+// proxyConnector = new ServerConnector(proxy, new HTTP2ServerConnectionFactory(configuration));
+// proxy.addConnector(proxyConnector);
+//
+// ServletContextHandler proxyContext = new ServletContextHandler(proxy, "/", true, false);
+// ServletHolder proxyServletHolder = new ServletHolder(proxyServlet);
+// proxyServletHolder.setInitParameters(initParams);
+// proxyContext.addServlet(proxyServletHolder, "/*");
+//
+// proxy.start();
+// }
+//
+// private void startClient() throws Exception
+// {
+// QueuedThreadPool clientExecutor = new QueuedThreadPool();
+// clientExecutor.setName("client");
+// client = new HTTP2Client();
+// client.setExecutor(clientExecutor);
+// client.start();
+// }
+//
+// private Session newClient(Session.Listener listener) throws Exception
+// {
+// String host = "localhost";
+// int port = proxyConnector.getLocalPort();
+// InetSocketAddress address = new InetSocketAddress(host, port);
+// FuturePromise promise = new FuturePromise<>();
+// client.connect(address, listener, promise);
+// return promise.get(5, TimeUnit.SECONDS);
+// }
+//
+// private MetaData.Request newRequest(String method, String path, HttpFields fields)
+// {
+// String host = "localhost";
+// int port = proxyConnector.getLocalPort();
+// String authority = host + ":" + port;
+// return new MetaData.Request(method, HttpScheme.HTTP.asString(), new HostPortHttpField(authority), path, HttpVersion.HTTP_2, fields, -1);
+// }
+//
+// @AfterEach
+// public void dispose() throws Exception
+// {
+// client.stop();
+// proxy.stop();
+// server.stop();
+// }
+//
+// @Test
+// public void testHTTPVersion() throws Exception
+// {
+// startServer(new HttpServlet()
+// {
+// @Override
+// protected void service(HttpServletRequest request, HttpServletResponse response)
+// {
+// assertEquals(HttpVersion.HTTP_1_1.asString(), request.getProtocol());
+// }
+// });
+// Map params = new HashMap<>();
+// params.put("proxyTo", "http://localhost:" + serverConnector.getLocalPort());
+// startProxy(new AsyncProxyServlet.Transparent(), params);
+// startClient();
+//
+// CountDownLatch clientLatch = new CountDownLatch(1);
+// Session session = newClient(new Session.Listener.Adapter());
+// MetaData.Request metaData = newRequest("GET", "/", HttpFields.EMPTY);
+// HeadersFrame frame = new HeadersFrame(metaData, null, true);
+// session.newStream(frame, new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onHeaders(Stream stream, HeadersFrame frame)
+// {
+// assertTrue(frame.isEndStream());
+// MetaData.Response response = (MetaData.Response)frame.getMetaData();
+// assertEquals(HttpStatus.OK_200, response.getStatus());
+// clientLatch.countDown();
+// }
+// });
+//
+// assertTrue(clientLatch.await(5, TimeUnit.SECONDS));
+// }
+//
+// @Test
+// public void testServerBigDownloadSlowClient() throws Exception
+// {
+// CountDownLatch serverLatch = new CountDownLatch(1);
+// byte[] content = new byte[1024 * 1024];
+// startServer(new HttpServlet()
+// {
+// @Override
+// protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException
+// {
+// response.write(true, callback, ByteBuffer.wrap(content));
+// serverLatch.countDown();
+// }
+// });
+// Map params = new HashMap<>();
+// params.put("proxyTo", "http://localhost:" + serverConnector.getLocalPort());
+// startProxy(new AsyncProxyServlet.Transparent(), params);
+// startClient();
+//
+// CountDownLatch clientLatch = new CountDownLatch(1);
+// Session session = newClient(new Session.Listener.Adapter());
+// MetaData.Request metaData = newRequest("GET", "/", HttpFields.EMPTY);
+// HeadersFrame frame = new HeadersFrame(metaData, null, true);
+// session.newStream(frame, new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// try
+// {
+// TimeUnit.MILLISECONDS.sleep(1);
+// callback.succeeded();
+// if (frame.isEndStream())
+// clientLatch.countDown();
+// }
+// catch (InterruptedException x)
+// {
+// callback.failed(x);
+// }
+// }
+// });
+//
+// assertTrue(serverLatch.await(15, TimeUnit.SECONDS));
+// assertTrue(clientLatch.await(15, TimeUnit.SECONDS));
+// }
}
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PushCacheFilterTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PushCacheFilterTest.java
index f895de76611..e97b7106ca0 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PushCacheFilterTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PushCacheFilterTest.java
@@ -11,996 +11,971 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import jakarta.servlet.DispatcherType;
-import jakarta.servlet.ServletOutputStream;
-import jakarta.servlet.http.HttpServlet;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.http.HostPortHttpField;
-import org.eclipse.jetty.http.HttpFields;
-import org.eclipse.jetty.http.HttpHeader;
-import org.eclipse.jetty.http.HttpScheme;
-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.api.Session;
-import org.eclipse.jetty.http2.api.Stream;
-import org.eclipse.jetty.http2.frames.DataFrame;
-import org.eclipse.jetty.http2.frames.HeadersFrame;
-import org.eclipse.jetty.http2.frames.PushPromiseFrame;
-import org.eclipse.jetty.http2.frames.ResetFrame;
-import org.eclipse.jetty.http2.frames.SettingsFrame;
-import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.eclipse.jetty.servlets.PushCacheFilter;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Promise;
+import org.junit.jupiter.api.Disabled;
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;
+import static org.junit.jupiter.api.Assertions.fail;
+// TODO
+@Disabled("move to ee9 or provide a PushCacheHandler")
public class PushCacheFilterTest extends AbstractTest
{
- private String contextPath = "/push";
-
- @Override
- protected void customizeContext(ServletContextHandler context)
- {
- context.setContextPath(contextPath);
- context.addFilter(PushCacheFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
- }
-
- @Override
- protected MetaData.Request newRequest(String method, String pathInfo, HttpFields fields)
- {
- return new MetaData.Request(method, HttpScheme.HTTP.asString(), new HostPortHttpField("localhost:" + connector.getLocalPort()), contextPath + servletPath + pathInfo, HttpVersion.HTTP_2, fields, -1);
- }
-
- private String newURI(String pathInfo)
- {
- return "http://localhost:" + connector.getLocalPort() + contextPath + servletPath + pathInfo;
- }
-
@Test
- public void testPush() throws Exception
+ public void test()
{
- final String primaryResource = "/primary.html";
- final String secondaryResource = "/secondary.png";
- final byte[] secondaryData = "SECONDARY".getBytes(StandardCharsets.UTF_8);
- start(new HttpServlet()
- {
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException
- {
- String requestURI = req.getRequestURI();
- ServletOutputStream output = resp.getOutputStream();
- if (requestURI.endsWith(primaryResource))
- output.print("PRIMARY");
- else if (requestURI.endsWith(secondaryResource))
- output.write(secondaryData);
- }
- });
-
- final Session session = newClient(new Session.Listener.Adapter());
-
- // Request for the primary and secondary resource to build the cache.
- final String referrerURI = newURI(primaryResource);
- MetaData.Request primaryRequest = newRequest("GET", primaryResource, HttpFields.EMPTY);
- final CountDownLatch warmupLatch = new CountDownLatch(1);
- session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- {
- // Request for the secondary resource.
- HttpFields.Mutable secondaryFields = HttpFields.build()
- .put(HttpHeader.REFERER, referrerURI);
- MetaData.Request secondaryRequest = newRequest("GET", secondaryResource, secondaryFields);
- session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- warmupLatch.countDown();
- }
- });
- }
- }
- });
- assertTrue(warmupLatch.await(5, TimeUnit.SECONDS));
-
- // Request again the primary resource, we should get the secondary resource pushed.
- primaryRequest = newRequest("GET", primaryResource, HttpFields.EMPTY);
- final CountDownLatch primaryResponseLatch = new CountDownLatch(2);
- final CountDownLatch pushLatch = new CountDownLatch(2);
- session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onHeaders(Stream stream, HeadersFrame frame)
- {
- MetaData.Response response = (MetaData.Response)frame.getMetaData();
- if (response.getStatus() == HttpStatus.OK_200)
- primaryResponseLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- primaryResponseLatch.countDown();
- }
-
- @Override
- public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
- {
- return new Adapter()
- {
- @Override
- public void onHeaders(Stream stream, HeadersFrame frame)
- {
- MetaData.Response response = (MetaData.Response)frame.getMetaData();
- if (response.getStatus() == HttpStatus.OK_200)
- pushLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- pushLatch.countDown();
- }
- };
- }
- });
- assertTrue(pushLatch.await(5, TimeUnit.SECONDS));
- assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
+ fail();
}
- @Test
- public void testPushReferrerNoPath() throws Exception
- {
- final String primaryResource = "/primary.html";
- final String secondaryResource = "/secondary.png";
- final byte[] secondaryData = "SECONDARY".getBytes(StandardCharsets.UTF_8);
- start(new HttpServlet()
- {
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException
- {
- String requestURI = req.getRequestURI();
- ServletOutputStream output = resp.getOutputStream();
- if (requestURI.endsWith(primaryResource))
- output.print("PRIMARY");
- else if (requestURI.endsWith(secondaryResource))
- output.write(secondaryData);
- }
- });
-
- final Session session = newClient(new Session.Listener.Adapter());
-
- // Request for the primary and secondary resource to build the cache.
- // The referrerURI does not point to the primary resource, so there will be no
- // resource association with the primary resource and therefore won't be pushed.
- final String referrerURI = "http://localhost:" + connector.getLocalPort();
- HttpFields.Mutable primaryFields = HttpFields.build();
- MetaData.Request primaryRequest = newRequest("GET", primaryResource, primaryFields);
- final CountDownLatch warmupLatch = new CountDownLatch(1);
- session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- {
- // Request for the secondary resource.
- HttpFields.Mutable secondaryFields = HttpFields.build()
- .put(HttpHeader.REFERER, referrerURI);
- MetaData.Request secondaryRequest = newRequest("GET", secondaryResource, secondaryFields);
- session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- warmupLatch.countDown();
- }
- });
- }
- }
- });
- assertTrue(warmupLatch.await(5, TimeUnit.SECONDS));
-
- // Request again the primary resource, we should not get the secondary resource pushed.
- primaryRequest = newRequest("GET", primaryResource, primaryFields);
- final CountDownLatch primaryResponseLatch = new CountDownLatch(1);
- final CountDownLatch pushLatch = new CountDownLatch(1);
- session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
- {
- return new Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- pushLatch.countDown();
- }
- };
- }
-
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- primaryResponseLatch.countDown();
- }
- });
- assertFalse(pushLatch.await(1, TimeUnit.SECONDS));
- assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testPushIsReset() throws Exception
- {
- final String primaryResource = "/primary.html";
- final String secondaryResource = "/secondary.png";
- final byte[] secondaryData = "SECONDARY".getBytes(StandardCharsets.UTF_8);
- start(new HttpServlet()
- {
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException
- {
- String requestURI = req.getRequestURI();
- ServletOutputStream output = resp.getOutputStream();
- if (requestURI.endsWith(primaryResource))
- output.print("PRIMARY");
- else if (requestURI.endsWith(secondaryResource))
- output.write(secondaryData);
- }
- });
-
- final Session session = newClient(new Session.Listener.Adapter());
-
- // Request for the primary and secondary resource to build the cache.
- final String primaryURI = newURI(primaryResource);
- HttpFields.Mutable primaryFields = HttpFields.build();
- MetaData.Request primaryRequest = newRequest("GET", primaryResource, primaryFields);
- final CountDownLatch warmupLatch = new CountDownLatch(1);
- session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- {
- // Request for the secondary resource.
- HttpFields.Mutable secondaryFields = HttpFields.build()
- .put(HttpHeader.REFERER, primaryURI);
- MetaData.Request secondaryRequest = newRequest("GET", secondaryResource, secondaryFields);
- session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- warmupLatch.countDown();
- }
- });
- }
- }
- });
- assertTrue(warmupLatch.await(5, TimeUnit.SECONDS));
-
- // Request again the primary resource, we should get the secondary resource pushed.
- primaryRequest = newRequest("GET", primaryResource, primaryFields);
- final CountDownLatch primaryResponseLatch = new CountDownLatch(1);
- final CountDownLatch pushLatch = new CountDownLatch(1);
- session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
- {
- // Reset the stream as soon as we see the push.
- ResetFrame resetFrame = new ResetFrame(stream.getId(), ErrorCode.REFUSED_STREAM_ERROR.code);
- stream.reset(resetFrame, Callback.NOOP);
- return new Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- pushLatch.countDown();
- }
- };
- }
-
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- primaryResponseLatch.countDown();
- }
- });
- // We should not receive pushed data that we reset.
- assertFalse(pushLatch.await(1, TimeUnit.SECONDS));
- assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
-
- // Make sure the session is sane by requesting the secondary resource.
- HttpFields.Mutable secondaryFields = HttpFields.build();
- secondaryFields.put(HttpHeader.REFERER, primaryURI);
- MetaData.Request secondaryRequest = newRequest("GET", secondaryResource, secondaryFields);
- final CountDownLatch secondaryResponseLatch = new CountDownLatch(1);
- session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- secondaryResponseLatch.countDown();
- }
- });
- assertTrue(secondaryResponseLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testPushWithoutPrimaryResponseContent() throws Exception
- {
- final String primaryResource = "/primary.html";
- final String secondaryResource = "/secondary.png";
- start(new HttpServlet()
- {
- @Override
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
- {
- String requestURI = request.getRequestURI();
- final ServletOutputStream output = response.getOutputStream();
- if (requestURI.endsWith(secondaryResource))
- output.write("SECONDARY".getBytes(StandardCharsets.UTF_8));
- }
- });
-
- final Session session = newClient(new Session.Listener.Adapter());
-
- // Request for the primary and secondary resource to build the cache.
- final String primaryURI = newURI(primaryResource);
- HttpFields.Mutable primaryFields = HttpFields.build();
- MetaData.Request primaryRequest = newRequest("GET", primaryResource, primaryFields);
- final CountDownLatch warmupLatch = new CountDownLatch(1);
- session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onHeaders(Stream stream, HeadersFrame frame)
- {
- if (frame.isEndStream())
- {
- // Request for the secondary resource.
- HttpFields.Mutable secondaryFields = HttpFields.build();
- secondaryFields.put(HttpHeader.REFERER, primaryURI);
- MetaData.Request secondaryRequest = newRequest("GET", secondaryResource, secondaryFields);
- session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- warmupLatch.countDown();
- }
- });
- }
- }
- });
- assertTrue(warmupLatch.await(5, TimeUnit.SECONDS));
-
- Thread.sleep(1000);
-
- // Request again the primary resource, we should get the secondary resource pushed.
- primaryRequest = newRequest("GET", primaryResource, primaryFields);
- final CountDownLatch primaryResponseLatch = new CountDownLatch(1);
- final CountDownLatch pushLatch = new CountDownLatch(1);
- session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onHeaders(Stream stream, HeadersFrame frame)
- {
- if (frame.isEndStream())
- primaryResponseLatch.countDown();
- }
-
- @Override
- public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
- {
- return new Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- pushLatch.countDown();
- }
- };
- }
- });
- assertTrue(pushLatch.await(5, TimeUnit.SECONDS));
- assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testRecursivePush() throws Exception
- {
- final String primaryResource = "/primary.html";
- final String secondaryResource1 = "/secondary1.css";
- final String secondaryResource2 = "/secondary2.js";
- final String tertiaryResource = "/tertiary.png";
- start(new HttpServlet()
- {
- @Override
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
- {
- String requestURI = request.getRequestURI();
- final ServletOutputStream output = response.getOutputStream();
- if (requestURI.endsWith(primaryResource))
- output.print("PRIMARY");
- else if (requestURI.endsWith(secondaryResource1))
- output.print("body { background-image: url(\"" + tertiaryResource + "\"); }");
- else if (requestURI.endsWith(secondaryResource2))
- output.print("(function() { window.alert('HTTP/2'); })()");
- if (requestURI.endsWith(tertiaryResource))
- output.write("TERTIARY".getBytes(StandardCharsets.UTF_8));
- }
- });
-
- final Session session = newClient(new Session.Listener.Adapter());
-
- // Request for the primary, secondary and tertiary resource to build the cache.
- final String primaryURI = newURI(primaryResource);
- HttpFields.Mutable primaryFields = HttpFields.build();
- MetaData.Request primaryRequest = newRequest("GET", primaryResource, primaryFields);
- final CountDownLatch warmupLatch = new CountDownLatch(2);
- session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- {
- // Request for the secondary resources.
- String secondaryURI1 = newURI(secondaryResource1);
- HttpFields.Mutable secondaryFields1 = HttpFields.build()
- .put(HttpHeader.REFERER, primaryURI);
- MetaData.Request secondaryRequest1 = newRequest("GET", secondaryResource1, secondaryFields1);
- session.newStream(new HeadersFrame(secondaryRequest1, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- {
- // Request for the tertiary resource.
- HttpFields.Mutable tertiaryFields = HttpFields.build()
- .put(HttpHeader.REFERER, secondaryURI1);
- MetaData.Request tertiaryRequest = newRequest("GET", tertiaryResource, tertiaryFields);
- session.newStream(new HeadersFrame(tertiaryRequest, null, true), new Promise.Adapter<>(), new Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- warmupLatch.countDown();
- }
- });
- }
- }
- });
-
- HttpFields.Mutable secondaryFields2 = HttpFields.build()
- .put(HttpHeader.REFERER, primaryURI);
- MetaData.Request secondaryRequest2 = newRequest("GET", secondaryResource2, secondaryFields2);
- session.newStream(new HeadersFrame(secondaryRequest2, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- warmupLatch.countDown();
- }
- });
- }
- }
- });
- assertTrue(warmupLatch.await(5, TimeUnit.SECONDS));
-
- Thread.sleep(1000);
-
- // Request again the primary resource, we should get the secondary and tertiary resources pushed.
- primaryRequest = newRequest("GET", primaryResource, primaryFields);
- final CountDownLatch primaryResponseLatch = new CountDownLatch(1);
- final CountDownLatch primaryPushesLatch = new CountDownLatch(3);
- final CountDownLatch recursiveLatch = new CountDownLatch(1);
- session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- primaryResponseLatch.countDown();
- }
-
- @Override
- public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
- {
- // The stream id of the PUSH_PROMISE must
- // always be a client stream and therefore odd.
- assertEquals(1, frame.getStreamId() & 1);
- return new Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- primaryPushesLatch.countDown();
- }
-
- @Override
- public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
- {
- return new Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- recursiveLatch.countDown();
- }
- };
- }
- };
- }
- });
-
- assertTrue(primaryPushesLatch.await(5, TimeUnit.SECONDS));
- assertFalse(recursiveLatch.await(1, TimeUnit.SECONDS));
- assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
-
- // Make sure that explicitly requesting a secondary resource, we get the tertiary pushed.
- CountDownLatch secondaryResponseLatch = new CountDownLatch(1);
- CountDownLatch secondaryPushLatch = new CountDownLatch(1);
- MetaData.Request secondaryRequest = newRequest("GET", secondaryResource1, HttpFields.EMPTY);
- session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- secondaryResponseLatch.countDown();
- }
-
- @Override
- public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
- {
- return new Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- secondaryPushLatch.countDown();
- }
- };
- }
- });
-
- assertTrue(secondaryPushLatch.await(5, TimeUnit.SECONDS));
- assertTrue(secondaryResponseLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testSelfPush() throws Exception
- {
- // The test case is that of a login page, for example.
- // When the user sends the credentials to the login page,
- // the login may fail and redirect to the same login page,
- // perhaps with different query parameters.
- // In this case a request for the login page will push
- // the login page itself, which will generate the pushed
- // request for the login page, which will push the login
- // page itself, etc. which is not the desired behavior.
-
- final String primaryResource = "/login.html";
- start(new HttpServlet()
- {
- @Override
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
- {
- ServletOutputStream output = response.getOutputStream();
- String credentials = request.getParameter("credentials");
- if (credentials == null)
- {
- output.print("LOGIN");
- }
- else if ("secret".equals(credentials))
- {
- output.print("OK");
- }
- else
- {
- response.setStatus(HttpStatus.TEMPORARY_REDIRECT_307);
- response.setHeader(HttpHeader.LOCATION.asString(), primaryResource);
- }
- }
- });
- final String primaryURI = newURI(primaryResource);
-
- final Session session = newClient(new Session.Listener.Adapter());
-
- // Login with the wrong credentials, causing a redirect to self.
- HttpFields.Mutable primaryFields = HttpFields.build();
- MetaData.Request primaryRequest = newRequest("GET", primaryResource + "?credentials=wrong", primaryFields);
- final CountDownLatch warmupLatch = new CountDownLatch(1);
- session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onHeaders(Stream stream, HeadersFrame frame)
- {
- if (frame.isEndStream())
- {
- MetaData.Response response = (MetaData.Response)frame.getMetaData();
- if (response.getStatus() == HttpStatus.TEMPORARY_REDIRECT_307)
- {
- // Follow the redirect.
- String location = response.getFields().get(HttpHeader.LOCATION);
- HttpFields.Mutable redirectFields = HttpFields.build();
- redirectFields.put(HttpHeader.REFERER, primaryURI);
- MetaData.Request redirectRequest = newRequest("GET", location, redirectFields);
- session.newStream(new HeadersFrame(redirectRequest, null, true), new Promise.Adapter<>(), new Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- warmupLatch.countDown();
- }
- });
- }
- }
- }
- });
- assertTrue(warmupLatch.await(5, TimeUnit.SECONDS));
-
- Thread.sleep(1000);
-
- // Login with the right credentials, there must be no push.
- primaryRequest = newRequest("GET", primaryResource + "?credentials=secret", primaryFields);
- final CountDownLatch primaryResponseLatch = new CountDownLatch(1);
- final CountDownLatch pushLatch = new CountDownLatch(1);
- session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- primaryResponseLatch.countDown();
- }
-
- @Override
- public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
- {
- pushLatch.countDown();
- return null;
- }
- });
- assertFalse(pushLatch.await(1, TimeUnit.SECONDS));
- assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testPushWithQueryParameters() throws Exception
- {
- String name = "foo";
- String value = "bar";
- final String primaryResource = "/primary.html?" + name + "=" + value;
- final String secondaryResource = "/secondary.html?" + name + "=" + value;
- start(new HttpServlet()
- {
- @Override
- protected void doGet(HttpServletRequest request, HttpServletResponse response)
- {
- String requestURI = request.getRequestURI();
- if (requestURI.endsWith(primaryResource))
- {
- response.setStatus(HttpStatus.OK_200);
- }
- else if (requestURI.endsWith(secondaryResource))
- {
- String param = request.getParameter(name);
- if (param == null)
- response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR_500);
- else
- response.setStatus(HttpStatus.OK_200);
- }
- }
- });
-
- final Session session = newClient(new Session.Listener.Adapter());
-
- // Request for the primary and secondary resource to build the cache.
- final String primaryURI = newURI(primaryResource);
- HttpFields.Mutable primaryFields = HttpFields.build();
- MetaData.Request primaryRequest = newRequest("GET", primaryResource, primaryFields);
- final CountDownLatch warmupLatch = new CountDownLatch(1);
- session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onHeaders(Stream stream, HeadersFrame frame)
- {
- if (frame.isEndStream())
- {
- // Request for the secondary resource.
- HttpFields.Mutable secondaryFields = HttpFields.build();
- secondaryFields.put(HttpHeader.REFERER, primaryURI);
- MetaData.Request secondaryRequest = newRequest("GET", secondaryResource, secondaryFields);
- session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onHeaders(Stream stream, HeadersFrame frame)
- {
- if (frame.isEndStream())
- warmupLatch.countDown();
- }
- });
- }
- }
- });
- assertTrue(warmupLatch.await(5, TimeUnit.SECONDS));
-
- Thread.sleep(1000);
-
- // Request again the primary resource, we should get the secondary resource pushed.
- primaryRequest = newRequest("GET", primaryResource, primaryFields);
- final CountDownLatch primaryResponseLatch = new CountDownLatch(1);
- final CountDownLatch pushLatch = new CountDownLatch(1);
- session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
- {
- MetaData metaData = frame.getMetaData();
- assertTrue(metaData instanceof MetaData.Request);
- MetaData.Request pushedRequest = (MetaData.Request)metaData;
- assertEquals(contextPath + servletPath + secondaryResource, pushedRequest.getURI().getPathQuery());
- return new Adapter()
- {
- @Override
- public void onHeaders(Stream stream, HeadersFrame frame)
- {
- if (frame.isEndStream())
- {
- MetaData.Response response = (MetaData.Response)frame.getMetaData();
- if (response.getStatus() == HttpStatus.OK_200)
- pushLatch.countDown();
- }
- }
- };
- }
-
- @Override
- public void onHeaders(Stream stream, HeadersFrame frame)
- {
- if (frame.isEndStream())
- primaryResponseLatch.countDown();
- }
- });
- assertTrue(pushLatch.await(5, TimeUnit.SECONDS));
- assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testPOSTRequestIsNotPushed() throws Exception
- {
- final String primaryResource = "/primary.html";
- final String secondaryResource = "/secondary.png";
- final byte[] secondaryData = "SECONDARY".getBytes(StandardCharsets.UTF_8);
- start(new HttpServlet()
- {
- @Override
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException
- {
- String requestURI = req.getRequestURI();
- ServletOutputStream output = resp.getOutputStream();
- if (requestURI.endsWith(primaryResource))
- output.print("PRIMARY");
- else if (requestURI.endsWith(secondaryResource))
- output.write(secondaryData);
- }
- });
-
- final Session session = newClient(new Session.Listener.Adapter());
-
- // Request for the primary and secondary resource to build the cache.
- final String referrerURI = newURI(primaryResource);
- HttpFields.Mutable primaryFields = HttpFields.build();
- MetaData.Request primaryRequest = newRequest("GET", primaryResource, primaryFields);
- final CountDownLatch warmupLatch = new CountDownLatch(1);
- session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- {
- // Request for the secondary resource.
- HttpFields.Mutable secondaryFields = HttpFields.build();
- secondaryFields.put(HttpHeader.REFERER, referrerURI);
- MetaData.Request secondaryRequest = newRequest("GET", secondaryResource, secondaryFields);
- session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- warmupLatch.countDown();
- }
- });
- }
- }
- });
- assertTrue(warmupLatch.await(5, TimeUnit.SECONDS));
-
- // Request again the primary resource with POST, we should not get the secondary resource pushed.
- primaryRequest = newRequest("POST", primaryResource, primaryFields);
- final CountDownLatch primaryResponseLatch = new CountDownLatch(1);
- final CountDownLatch pushLatch = new CountDownLatch(1);
- session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
- {
- return new Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- pushLatch.countDown();
- }
- };
- }
-
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- primaryResponseLatch.countDown();
- }
- });
- assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
- assertFalse(pushLatch.await(1, TimeUnit.SECONDS));
- }
-
- @Test
- public void testPushDisabled() throws Exception
- {
- final String primaryResource = "/primary.html";
- final String secondaryResource = "/secondary.png";
- final byte[] secondaryData = "SECONDARY".getBytes(StandardCharsets.UTF_8);
- start(new HttpServlet()
- {
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException
- {
- String requestURI = req.getRequestURI();
- ServletOutputStream output = resp.getOutputStream();
- if (requestURI.endsWith(primaryResource))
- output.print("PRIMARY");
- else if (requestURI.endsWith(secondaryResource))
- output.write(secondaryData);
- }
- });
-
- final Session session = newClient(new Session.Listener.Adapter()
- {
- @Override
- public Map onPreface(Session session)
- {
- Map settings = new HashMap<>();
- settings.put(SettingsFrame.ENABLE_PUSH, 0);
- return settings;
- }
- });
-
- // Request for the primary and secondary resource to build the cache.
- final String referrerURI = newURI(primaryResource);
- HttpFields.Mutable primaryFields = HttpFields.build();
- MetaData.Request primaryRequest = newRequest("GET", primaryResource, primaryFields);
- final CountDownLatch warmupLatch = new CountDownLatch(1);
- session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- {
- // Request for the secondary resource.
- HttpFields.Mutable secondaryFields = HttpFields.build();
- secondaryFields.put(HttpHeader.REFERER, referrerURI);
- MetaData.Request secondaryRequest = newRequest("GET", secondaryResource, secondaryFields);
- session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- warmupLatch.countDown();
- }
- });
- }
- }
- });
- assertTrue(warmupLatch.await(5, TimeUnit.SECONDS));
-
- // Request again the primary resource, we should not get the secondary resource pushed.
- primaryRequest = newRequest("GET", primaryResource, primaryFields);
- final CountDownLatch primaryResponseLatch = new CountDownLatch(1);
- final CountDownLatch pushLatch = new CountDownLatch(1);
- session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
- {
- @Override
- public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
- {
- pushLatch.countDown();
- return null;
- }
-
- @Override
- public void onData(Stream stream, DataFrame frame, Callback callback)
- {
- callback.succeeded();
- if (frame.isEndStream())
- primaryResponseLatch.countDown();
- }
- });
- assertFalse(pushLatch.await(1, TimeUnit.SECONDS));
- assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
- }
+// private String contextPath = "/push";
+//
+// @Override
+// protected void customizeContext(ServletContextHandler context)
+// {
+// context.setContextPath(contextPath);
+// context.addFilter(PushCacheFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
+// }
+//
+// @Override
+// protected MetaData.Request newRequest(String method, String path, HttpFields fields)
+// {
+// return new MetaData.Request(method, HttpScheme.HTTP.asString(), new HostPortHttpField("localhost:" + connector.getLocalPort()), contextPath + servletPath + path, HttpVersion.HTTP_2, fields, -1);
+// }
+//
+// private String newURI(String pathInfo)
+// {
+// return "http://localhost:" + connector.getLocalPort() + contextPath + servletPath + pathInfo;
+// }
+//
+// @Test
+// public void testPush() throws Exception
+// {
+// final String primaryResource = "/primary.html";
+// final String secondaryResource = "/secondary.png";
+// final byte[] secondaryData = "SECONDARY".getBytes(StandardCharsets.UTF_8);
+// start(new HttpServlet()
+// {
+// @Override
+// protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException
+// {
+// String requestURI = req.getRequestURI();
+// ServletOutputStream output = resp.getOutputStream();
+// if (requestURI.endsWith(primaryResource))
+// output.print("PRIMARY");
+// else if (requestURI.endsWith(secondaryResource))
+// output.write(secondaryData);
+// }
+// });
+//
+// final Session session = newClient(new Session.Listener.Adapter());
+//
+// // Request for the primary and secondary resource to build the cache.
+// final String referrerURI = newURI(primaryResource);
+// MetaData.Request primaryRequest = newRequest("GET", primaryResource, HttpFields.EMPTY);
+// final CountDownLatch warmupLatch = new CountDownLatch(1);
+// session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// {
+// // Request for the secondary resource.
+// HttpFields.Mutable secondaryFields = HttpFields.build()
+// .put(HttpHeader.REFERER, referrerURI);
+// MetaData.Request secondaryRequest = newRequest("GET", secondaryResource, secondaryFields);
+// session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// warmupLatch.countDown();
+// }
+// });
+// }
+// }
+// });
+// assertTrue(warmupLatch.await(5, TimeUnit.SECONDS));
+//
+// // Request again the primary resource, we should get the secondary resource pushed.
+// primaryRequest = newRequest("GET", primaryResource, HttpFields.EMPTY);
+// final CountDownLatch primaryResponseLatch = new CountDownLatch(2);
+// final CountDownLatch pushLatch = new CountDownLatch(2);
+// session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onHeaders(Stream stream, HeadersFrame frame)
+// {
+// MetaData.Response response = (MetaData.Response)frame.getMetaData();
+// if (response.getStatus() == HttpStatus.OK_200)
+// primaryResponseLatch.countDown();
+// }
+//
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// primaryResponseLatch.countDown();
+// }
+//
+// @Override
+// public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
+// {
+// return new Adapter()
+// {
+// @Override
+// public void onHeaders(Stream stream, HeadersFrame frame)
+// {
+// MetaData.Response response = (MetaData.Response)frame.getMetaData();
+// if (response.getStatus() == HttpStatus.OK_200)
+// pushLatch.countDown();
+// }
+//
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// pushLatch.countDown();
+// }
+// };
+// }
+// });
+// assertTrue(pushLatch.await(5, TimeUnit.SECONDS));
+// assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
+// }
+//
+// @Test
+// public void testPushReferrerNoPath() throws Exception
+// {
+// final String primaryResource = "/primary.html";
+// final String secondaryResource = "/secondary.png";
+// final byte[] secondaryData = "SECONDARY".getBytes(StandardCharsets.UTF_8);
+// start(new HttpServlet()
+// {
+// @Override
+// protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException
+// {
+// String requestURI = req.getRequestURI();
+// ServletOutputStream output = resp.getOutputStream();
+// if (requestURI.endsWith(primaryResource))
+// output.print("PRIMARY");
+// else if (requestURI.endsWith(secondaryResource))
+// output.write(secondaryData);
+// }
+// });
+//
+// final Session session = newClient(new Session.Listener.Adapter());
+//
+// // Request for the primary and secondary resource to build the cache.
+// // The referrerURI does not point to the primary resource, so there will be no
+// // resource association with the primary resource and therefore won't be pushed.
+// final String referrerURI = "http://localhost:" + connector.getLocalPort();
+// HttpFields.Mutable primaryFields = HttpFields.build();
+// MetaData.Request primaryRequest = newRequest("GET", primaryResource, primaryFields);
+// final CountDownLatch warmupLatch = new CountDownLatch(1);
+// session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// {
+// // Request for the secondary resource.
+// HttpFields.Mutable secondaryFields = HttpFields.build()
+// .put(HttpHeader.REFERER, referrerURI);
+// MetaData.Request secondaryRequest = newRequest("GET", secondaryResource, secondaryFields);
+// session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// warmupLatch.countDown();
+// }
+// });
+// }
+// }
+// });
+// assertTrue(warmupLatch.await(5, TimeUnit.SECONDS));
+//
+// // Request again the primary resource, we should not get the secondary resource pushed.
+// primaryRequest = newRequest("GET", primaryResource, primaryFields);
+// final CountDownLatch primaryResponseLatch = new CountDownLatch(1);
+// final CountDownLatch pushLatch = new CountDownLatch(1);
+// session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
+// {
+// return new Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// pushLatch.countDown();
+// }
+// };
+// }
+//
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// primaryResponseLatch.countDown();
+// }
+// });
+// assertFalse(pushLatch.await(1, TimeUnit.SECONDS));
+// assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
+// }
+//
+// @Test
+// public void testPushIsReset() throws Exception
+// {
+// final String primaryResource = "/primary.html";
+// final String secondaryResource = "/secondary.png";
+// final byte[] secondaryData = "SECONDARY".getBytes(StandardCharsets.UTF_8);
+// start(new HttpServlet()
+// {
+// @Override
+// protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException
+// {
+// String requestURI = req.getRequestURI();
+// ServletOutputStream output = resp.getOutputStream();
+// if (requestURI.endsWith(primaryResource))
+// output.print("PRIMARY");
+// else if (requestURI.endsWith(secondaryResource))
+// output.write(secondaryData);
+// }
+// });
+//
+// final Session session = newClient(new Session.Listener.Adapter());
+//
+// // Request for the primary and secondary resource to build the cache.
+// final String primaryURI = newURI(primaryResource);
+// HttpFields.Mutable primaryFields = HttpFields.build();
+// MetaData.Request primaryRequest = newRequest("GET", primaryResource, primaryFields);
+// final CountDownLatch warmupLatch = new CountDownLatch(1);
+// session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// {
+// // Request for the secondary resource.
+// HttpFields.Mutable secondaryFields = HttpFields.build()
+// .put(HttpHeader.REFERER, primaryURI);
+// MetaData.Request secondaryRequest = newRequest("GET", secondaryResource, secondaryFields);
+// session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// warmupLatch.countDown();
+// }
+// });
+// }
+// }
+// });
+// assertTrue(warmupLatch.await(5, TimeUnit.SECONDS));
+//
+// // Request again the primary resource, we should get the secondary resource pushed.
+// primaryRequest = newRequest("GET", primaryResource, primaryFields);
+// final CountDownLatch primaryResponseLatch = new CountDownLatch(1);
+// final CountDownLatch pushLatch = new CountDownLatch(1);
+// session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
+// {
+// // Reset the stream as soon as we see the push.
+// ResetFrame resetFrame = new ResetFrame(stream.getId(), ErrorCode.REFUSED_STREAM_ERROR.code);
+// stream.reset(resetFrame, Callback.NOOP);
+// return new Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// pushLatch.countDown();
+// }
+// };
+// }
+//
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// primaryResponseLatch.countDown();
+// }
+// });
+// // We should not receive pushed data that we reset.
+// assertFalse(pushLatch.await(1, TimeUnit.SECONDS));
+// assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
+//
+// // Make sure the session is sane by requesting the secondary resource.
+// HttpFields.Mutable secondaryFields = HttpFields.build();
+// secondaryFields.put(HttpHeader.REFERER, primaryURI);
+// MetaData.Request secondaryRequest = newRequest("GET", secondaryResource, secondaryFields);
+// final CountDownLatch secondaryResponseLatch = new CountDownLatch(1);
+// session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// secondaryResponseLatch.countDown();
+// }
+// });
+// assertTrue(secondaryResponseLatch.await(5, TimeUnit.SECONDS));
+// }
+//
+// @Test
+// public void testPushWithoutPrimaryResponseContent() throws Exception
+// {
+// final String primaryResource = "/primary.html";
+// final String secondaryResource = "/secondary.png";
+// start(new HttpServlet()
+// {
+// @Override
+// protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
+// {
+// String requestURI = request.getRequestURI();
+// final ServletOutputStream output = response.getOutputStream();
+// if (requestURI.endsWith(secondaryResource))
+// output.write("SECONDARY".getBytes(StandardCharsets.UTF_8));
+// }
+// });
+//
+// final Session session = newClient(new Session.Listener.Adapter());
+//
+// // Request for the primary and secondary resource to build the cache.
+// final String primaryURI = newURI(primaryResource);
+// HttpFields.Mutable primaryFields = HttpFields.build();
+// MetaData.Request primaryRequest = newRequest("GET", primaryResource, primaryFields);
+// final CountDownLatch warmupLatch = new CountDownLatch(1);
+// session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onHeaders(Stream stream, HeadersFrame frame)
+// {
+// if (frame.isEndStream())
+// {
+// // Request for the secondary resource.
+// HttpFields.Mutable secondaryFields = HttpFields.build();
+// secondaryFields.put(HttpHeader.REFERER, primaryURI);
+// MetaData.Request secondaryRequest = newRequest("GET", secondaryResource, secondaryFields);
+// session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// warmupLatch.countDown();
+// }
+// });
+// }
+// }
+// });
+// assertTrue(warmupLatch.await(5, TimeUnit.SECONDS));
+//
+// Thread.sleep(1000);
+//
+// // Request again the primary resource, we should get the secondary resource pushed.
+// primaryRequest = newRequest("GET", primaryResource, primaryFields);
+// final CountDownLatch primaryResponseLatch = new CountDownLatch(1);
+// final CountDownLatch pushLatch = new CountDownLatch(1);
+// session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onHeaders(Stream stream, HeadersFrame frame)
+// {
+// if (frame.isEndStream())
+// primaryResponseLatch.countDown();
+// }
+//
+// @Override
+// public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
+// {
+// return new Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// pushLatch.countDown();
+// }
+// };
+// }
+// });
+// assertTrue(pushLatch.await(5, TimeUnit.SECONDS));
+// assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
+// }
+//
+// @Test
+// public void testRecursivePush() throws Exception
+// {
+// final String primaryResource = "/primary.html";
+// final String secondaryResource1 = "/secondary1.css";
+// final String secondaryResource2 = "/secondary2.js";
+// final String tertiaryResource = "/tertiary.png";
+// start(new HttpServlet()
+// {
+// @Override
+// protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
+// {
+// String requestURI = request.getRequestURI();
+// final ServletOutputStream output = response.getOutputStream();
+// if (requestURI.endsWith(primaryResource))
+// output.print("PRIMARY");
+// else if (requestURI.endsWith(secondaryResource1))
+// output.print("body { background-image: url(\"" + tertiaryResource + "\"); }");
+// else if (requestURI.endsWith(secondaryResource2))
+// output.print("(function() { window.alert('HTTP/2'); })()");
+// if (requestURI.endsWith(tertiaryResource))
+// output.write("TERTIARY".getBytes(StandardCharsets.UTF_8));
+// }
+// });
+//
+// final Session session = newClient(new Session.Listener.Adapter());
+//
+// // Request for the primary, secondary and tertiary resource to build the cache.
+// final String primaryURI = newURI(primaryResource);
+// HttpFields.Mutable primaryFields = HttpFields.build();
+// MetaData.Request primaryRequest = newRequest("GET", primaryResource, primaryFields);
+// final CountDownLatch warmupLatch = new CountDownLatch(2);
+// session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// {
+// // Request for the secondary resources.
+// String secondaryURI1 = newURI(secondaryResource1);
+// HttpFields.Mutable secondaryFields1 = HttpFields.build()
+// .put(HttpHeader.REFERER, primaryURI);
+// MetaData.Request secondaryRequest1 = newRequest("GET", secondaryResource1, secondaryFields1);
+// session.newStream(new HeadersFrame(secondaryRequest1, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// {
+// // Request for the tertiary resource.
+// HttpFields.Mutable tertiaryFields = HttpFields.build()
+// .put(HttpHeader.REFERER, secondaryURI1);
+// MetaData.Request tertiaryRequest = newRequest("GET", tertiaryResource, tertiaryFields);
+// session.newStream(new HeadersFrame(tertiaryRequest, null, true), new Promise.Adapter<>(), new Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// warmupLatch.countDown();
+// }
+// });
+// }
+// }
+// });
+//
+// HttpFields.Mutable secondaryFields2 = HttpFields.build()
+// .put(HttpHeader.REFERER, primaryURI);
+// MetaData.Request secondaryRequest2 = newRequest("GET", secondaryResource2, secondaryFields2);
+// session.newStream(new HeadersFrame(secondaryRequest2, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// warmupLatch.countDown();
+// }
+// });
+// }
+// }
+// });
+// assertTrue(warmupLatch.await(5, TimeUnit.SECONDS));
+//
+// Thread.sleep(1000);
+//
+// // Request again the primary resource, we should get the secondary and tertiary resources pushed.
+// primaryRequest = newRequest("GET", primaryResource, primaryFields);
+// final CountDownLatch primaryResponseLatch = new CountDownLatch(1);
+// final CountDownLatch primaryPushesLatch = new CountDownLatch(3);
+// final CountDownLatch recursiveLatch = new CountDownLatch(1);
+// session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// primaryResponseLatch.countDown();
+// }
+//
+// @Override
+// public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
+// {
+// // The stream id of the PUSH_PROMISE must
+// // always be a client stream and therefore odd.
+// assertEquals(1, frame.getStreamId() & 1);
+// return new Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// primaryPushesLatch.countDown();
+// }
+//
+// @Override
+// public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
+// {
+// return new Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// recursiveLatch.countDown();
+// }
+// };
+// }
+// };
+// }
+// });
+//
+// assertTrue(primaryPushesLatch.await(5, TimeUnit.SECONDS));
+// assertFalse(recursiveLatch.await(1, TimeUnit.SECONDS));
+// assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
+//
+// // Make sure that explicitly requesting a secondary resource, we get the tertiary pushed.
+// CountDownLatch secondaryResponseLatch = new CountDownLatch(1);
+// CountDownLatch secondaryPushLatch = new CountDownLatch(1);
+// MetaData.Request secondaryRequest = newRequest("GET", secondaryResource1, HttpFields.EMPTY);
+// session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// secondaryResponseLatch.countDown();
+// }
+//
+// @Override
+// public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
+// {
+// return new Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// secondaryPushLatch.countDown();
+// }
+// };
+// }
+// });
+//
+// assertTrue(secondaryPushLatch.await(5, TimeUnit.SECONDS));
+// assertTrue(secondaryResponseLatch.await(5, TimeUnit.SECONDS));
+// }
+//
+// @Test
+// public void testSelfPush() throws Exception
+// {
+// // The test case is that of a login page, for example.
+// // When the user sends the credentials to the login page,
+// // the login may fail and redirect to the same login page,
+// // perhaps with different query parameters.
+// // In this case a request for the login page will push
+// // the login page itself, which will generate the pushed
+// // request for the login page, which will push the login
+// // page itself, etc. which is not the desired behavior.
+//
+// final String primaryResource = "/login.html";
+// start(new HttpServlet()
+// {
+// @Override
+// protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
+// {
+// ServletOutputStream output = response.getOutputStream();
+// String credentials = request.getParameter("credentials");
+// if (credentials == null)
+// {
+// output.print("LOGIN");
+// }
+// else if ("secret".equals(credentials))
+// {
+// output.print("OK");
+// }
+// else
+// {
+// response.setStatus(HttpStatus.TEMPORARY_REDIRECT_307);
+// response.getHeaders().put(HttpHeader.LOCATION, primaryResource);
+// }
+// }
+// });
+// final String primaryURI = newURI(primaryResource);
+//
+// final Session session = newClient(new Session.Listener.Adapter());
+//
+// // Login with the wrong credentials, causing a redirect to self.
+// HttpFields.Mutable primaryFields = HttpFields.build();
+// MetaData.Request primaryRequest = newRequest("GET", primaryResource + "?credentials=wrong", primaryFields);
+// final CountDownLatch warmupLatch = new CountDownLatch(1);
+// session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onHeaders(Stream stream, HeadersFrame frame)
+// {
+// if (frame.isEndStream())
+// {
+// MetaData.Response response = (MetaData.Response)frame.getMetaData();
+// if (response.getStatus() == HttpStatus.TEMPORARY_REDIRECT_307)
+// {
+// // Follow the redirect.
+// String location = response.getFields().get(HttpHeader.LOCATION);
+// HttpFields.Mutable redirectFields = HttpFields.build();
+// redirectFields.put(HttpHeader.REFERER, primaryURI);
+// MetaData.Request redirectRequest = newRequest("GET", location, redirectFields);
+// session.newStream(new HeadersFrame(redirectRequest, null, true), new Promise.Adapter<>(), new Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// warmupLatch.countDown();
+// }
+// });
+// }
+// }
+// }
+// });
+// assertTrue(warmupLatch.await(5, TimeUnit.SECONDS));
+//
+// Thread.sleep(1000);
+//
+// // Login with the right credentials, there must be no push.
+// primaryRequest = newRequest("GET", primaryResource + "?credentials=secret", primaryFields);
+// final CountDownLatch primaryResponseLatch = new CountDownLatch(1);
+// final CountDownLatch pushLatch = new CountDownLatch(1);
+// session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// primaryResponseLatch.countDown();
+// }
+//
+// @Override
+// public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
+// {
+// pushLatch.countDown();
+// return null;
+// }
+// });
+// assertFalse(pushLatch.await(1, TimeUnit.SECONDS));
+// assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
+// }
+//
+// @Test
+// public void testPushWithQueryParameters() throws Exception
+// {
+// String name = "foo";
+// String value = "bar";
+// final String primaryResource = "/primary.html?" + name + "=" + value;
+// final String secondaryResource = "/secondary.html?" + name + "=" + value;
+// start(new HttpServlet()
+// {
+// @Override
+// protected void doGet(HttpServletRequest request, HttpServletResponse response)
+// {
+// String requestURI = request.getRequestURI();
+// if (requestURI.endsWith(primaryResource))
+// {
+// response.setStatus(HttpStatus.OK_200);
+// }
+// else if (requestURI.endsWith(secondaryResource))
+// {
+// String param = request.getParameter(name);
+// if (param == null)
+// response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR_500);
+// else
+// response.setStatus(HttpStatus.OK_200);
+// }
+// }
+// });
+//
+// final Session session = newClient(new Session.Listener.Adapter());
+//
+// // Request for the primary and secondary resource to build the cache.
+// final String primaryURI = newURI(primaryResource);
+// HttpFields.Mutable primaryFields = HttpFields.build();
+// MetaData.Request primaryRequest = newRequest("GET", primaryResource, primaryFields);
+// final CountDownLatch warmupLatch = new CountDownLatch(1);
+// session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onHeaders(Stream stream, HeadersFrame frame)
+// {
+// if (frame.isEndStream())
+// {
+// // Request for the secondary resource.
+// HttpFields.Mutable secondaryFields = HttpFields.build();
+// secondaryFields.put(HttpHeader.REFERER, primaryURI);
+// MetaData.Request secondaryRequest = newRequest("GET", secondaryResource, secondaryFields);
+// session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onHeaders(Stream stream, HeadersFrame frame)
+// {
+// if (frame.isEndStream())
+// warmupLatch.countDown();
+// }
+// });
+// }
+// }
+// });
+// assertTrue(warmupLatch.await(5, TimeUnit.SECONDS));
+//
+// Thread.sleep(1000);
+//
+// // Request again the primary resource, we should get the secondary resource pushed.
+// primaryRequest = newRequest("GET", primaryResource, primaryFields);
+// final CountDownLatch primaryResponseLatch = new CountDownLatch(1);
+// final CountDownLatch pushLatch = new CountDownLatch(1);
+// session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
+// {
+// MetaData metaData = frame.getMetaData();
+// assertTrue(metaData instanceof MetaData.Request);
+// MetaData.Request pushedRequest = (MetaData.Request)metaData;
+// assertEquals(contextPath + servletPath + secondaryResource, pushedRequest.getURI().getPathQuery());
+// return new Adapter()
+// {
+// @Override
+// public void onHeaders(Stream stream, HeadersFrame frame)
+// {
+// if (frame.isEndStream())
+// {
+// MetaData.Response response = (MetaData.Response)frame.getMetaData();
+// if (response.getStatus() == HttpStatus.OK_200)
+// pushLatch.countDown();
+// }
+// }
+// };
+// }
+//
+// @Override
+// public void onHeaders(Stream stream, HeadersFrame frame)
+// {
+// if (frame.isEndStream())
+// primaryResponseLatch.countDown();
+// }
+// });
+// assertTrue(pushLatch.await(5, TimeUnit.SECONDS));
+// assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
+// }
+//
+// @Test
+// public void testPOSTRequestIsNotPushed() throws Exception
+// {
+// final String primaryResource = "/primary.html";
+// final String secondaryResource = "/secondary.png";
+// final byte[] secondaryData = "SECONDARY".getBytes(StandardCharsets.UTF_8);
+// start(new HttpServlet()
+// {
+// @Override
+// protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException
+// {
+// String requestURI = req.getRequestURI();
+// ServletOutputStream output = resp.getOutputStream();
+// if (requestURI.endsWith(primaryResource))
+// output.print("PRIMARY");
+// else if (requestURI.endsWith(secondaryResource))
+// output.write(secondaryData);
+// }
+// });
+//
+// final Session session = newClient(new Session.Listener.Adapter());
+//
+// // Request for the primary and secondary resource to build the cache.
+// final String referrerURI = newURI(primaryResource);
+// HttpFields.Mutable primaryFields = HttpFields.build();
+// MetaData.Request primaryRequest = newRequest("GET", primaryResource, primaryFields);
+// final CountDownLatch warmupLatch = new CountDownLatch(1);
+// session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// {
+// // Request for the secondary resource.
+// HttpFields.Mutable secondaryFields = HttpFields.build();
+// secondaryFields.put(HttpHeader.REFERER, referrerURI);
+// MetaData.Request secondaryRequest = newRequest("GET", secondaryResource, secondaryFields);
+// session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// warmupLatch.countDown();
+// }
+// });
+// }
+// }
+// });
+// assertTrue(warmupLatch.await(5, TimeUnit.SECONDS));
+//
+// // Request again the primary resource with POST, we should not get the secondary resource pushed.
+// primaryRequest = newRequest("POST", primaryResource, primaryFields);
+// final CountDownLatch primaryResponseLatch = new CountDownLatch(1);
+// final CountDownLatch pushLatch = new CountDownLatch(1);
+// session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
+// {
+// return new Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// pushLatch.countDown();
+// }
+// };
+// }
+//
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// primaryResponseLatch.countDown();
+// }
+// });
+// assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
+// assertFalse(pushLatch.await(1, TimeUnit.SECONDS));
+// }
+//
+// @Test
+// public void testPushDisabled() throws Exception
+// {
+// final String primaryResource = "/primary.html";
+// final String secondaryResource = "/secondary.png";
+// final byte[] secondaryData = "SECONDARY".getBytes(StandardCharsets.UTF_8);
+// start(new HttpServlet()
+// {
+// @Override
+// protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException
+// {
+// String requestURI = req.getRequestURI();
+// ServletOutputStream output = resp.getOutputStream();
+// if (requestURI.endsWith(primaryResource))
+// output.print("PRIMARY");
+// else if (requestURI.endsWith(secondaryResource))
+// output.write(secondaryData);
+// }
+// });
+//
+// final Session session = newClient(new Session.Listener.Adapter()
+// {
+// @Override
+// public Map onPreface(Session session)
+// {
+// Map settings = new HashMap<>();
+// settings.put(SettingsFrame.ENABLE_PUSH, 0);
+// return settings;
+// }
+// });
+//
+// // Request for the primary and secondary resource to build the cache.
+// final String referrerURI = newURI(primaryResource);
+// HttpFields.Mutable primaryFields = HttpFields.build();
+// MetaData.Request primaryRequest = newRequest("GET", primaryResource, primaryFields);
+// final CountDownLatch warmupLatch = new CountDownLatch(1);
+// session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// {
+// // Request for the secondary resource.
+// HttpFields.Mutable secondaryFields = HttpFields.build();
+// secondaryFields.put(HttpHeader.REFERER, referrerURI);
+// MetaData.Request secondaryRequest = newRequest("GET", secondaryResource, secondaryFields);
+// session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// warmupLatch.countDown();
+// }
+// });
+// }
+// }
+// });
+// assertTrue(warmupLatch.await(5, TimeUnit.SECONDS));
+//
+// // Request again the primary resource, we should not get the secondary resource pushed.
+// primaryRequest = newRequest("GET", primaryResource, primaryFields);
+// final CountDownLatch primaryResponseLatch = new CountDownLatch(1);
+// final CountDownLatch pushLatch = new CountDownLatch(1);
+// session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+// {
+// @Override
+// public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
+// {
+// pushLatch.countDown();
+// return null;
+// }
+//
+// @Override
+// public void onData(Stream stream, DataFrame frame, Callback callback)
+// {
+// callback.succeeded();
+// if (frame.isEndStream())
+// primaryResponseLatch.countDown();
+// }
+// });
+// assertFalse(pushLatch.await(1, TimeUnit.SECONDS));
+// assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
+// }
}
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PushedResourcesTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PushedResourcesTest.java
index 307ede0a2bf..8f9643d8344 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PushedResourcesTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PushedResourcesTest.java
@@ -11,15 +11,13 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client.http;
+package org.eclipse.jetty.http2.tests;
-import java.io.IOException;
+import java.nio.ByteBuffer;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.HttpRequest;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Result;
@@ -35,8 +33,9 @@ import org.eclipse.jetty.http2.api.server.ServerSessionListener;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.PushPromiseFrame;
import org.eclipse.jetty.http2.frames.ResetFrame;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Promise;
import org.junit.jupiter.api.Test;
@@ -80,7 +79,7 @@ public class PushedResourcesTest extends AbstractTest
}
});
- HttpRequest request = (HttpRequest)client.newRequest("localhost", connector.getLocalPort());
+ HttpRequest request = (HttpRequest)httpClient.newRequest("localhost", connector.getLocalPort());
ContentResponse response = request
.pushListener((mainRequest, pushedRequest) -> null)
.timeout(5, TimeUnit.SECONDS)
@@ -103,36 +102,34 @@ public class PushedResourcesTest extends AbstractTest
String path1 = "/secondary1";
String path2 = "/secondary2";
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
- baseRequest.setHandled(true);
+ String target = request.getPathInContext();
if (target.equals(path1))
{
- response.getOutputStream().write(pushBytes1);
+ response.write(true, callback, ByteBuffer.wrap(pushBytes1));
}
else if (target.equals(path2))
{
- response.getOutputStream().write(pushBytes2);
+ response.write(true, callback, ByteBuffer.wrap(pushBytes2));
}
else
{
- baseRequest.newPushBuilder()
- .path(path1)
- .push();
- baseRequest.newPushBuilder()
- .path(path2)
- .push();
- response.getOutputStream().write(bytes);
+ MetaData.Request push1 = new MetaData.Request(null, HttpURI.build(request.getHttpURI()).path(path1), HttpVersion.HTTP_2, HttpFields.EMPTY);
+ request.push(push1);
+ MetaData.Request push2 = new MetaData.Request(null, HttpURI.build(request.getHttpURI()).path(path2), HttpVersion.HTTP_2, HttpFields.EMPTY);
+ request.push(push2);
+ response.write(true, callback, ByteBuffer.wrap(bytes));
}
}
});
CountDownLatch latch1 = new CountDownLatch(1);
CountDownLatch latch2 = new CountDownLatch(1);
- HttpRequest request = (HttpRequest)client.newRequest("localhost", connector.getLocalPort());
+ HttpRequest request = (HttpRequest)httpClient.newRequest("localhost", connector.getLocalPort());
ContentResponse response = request
.pushListener((mainRequest, pushedRequest) -> new BufferingResponseListener()
{
@@ -170,23 +167,30 @@ public class PushedResourcesTest extends AbstractTest
String oldPath = "/old";
String newPath = "/new";
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
- baseRequest.setHandled(true);
+ String target = request.getPathInContext();
if (target.equals(oldPath))
- response.sendRedirect(newPath);
+ {
+ Response.sendRedirect(request, response, callback, newPath);
+ }
else if (target.equals(newPath))
- response.getOutputStream().write(pushBytes);
+ {
+ response.write(true, callback, ByteBuffer.wrap(pushBytes));
+ }
else
- baseRequest.newPushBuilder().path(oldPath).push();
+ {
+ request.push(new MetaData.Request(null, HttpURI.build(request.getHttpURI()).path(oldPath), HttpVersion.HTTP_2, HttpFields.EMPTY));
+ callback.succeeded();
+ }
}
});
CountDownLatch latch = new CountDownLatch(1);
- HttpRequest request = (HttpRequest)client.newRequest("localhost", connector.getLocalPort());
+ HttpRequest request = (HttpRequest)httpClient.newRequest("localhost", connector.getLocalPort());
ContentResponse response = request
.pushListener((mainRequest, pushedRequest) -> new BufferingResponseListener()
{
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/RawHTTP2ProxyTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/RawHTTP2ProxyTest.java
index 4633a864143..a12ac03bc7c 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/RawHTTP2ProxyTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/RawHTTP2ProxyTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
@@ -34,6 +34,7 @@ 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.api.server.ServerSessionListener;
+import org.eclipse.jetty.http2.client.HTTP2Client;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.http2.frames.GoAwayFrame;
@@ -335,7 +336,7 @@ public class RawHTTP2ProxyTest
if (LOGGER.isDebugEnabled())
LOGGER.debug("CPS queueing {} for {} on {}", frame, stream, stream.getSession());
boolean connected;
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
Deque deque = frames.computeIfAbsent(stream, s -> new ArrayDeque<>());
deque.offer(new FrameInfo(frame, callback));
@@ -352,14 +353,14 @@ public class RawHTTP2ProxyTest
InetSocketAddress address = new InetSocketAddress(host, port);
if (LOGGER.isDebugEnabled())
LOGGER.debug("CPS connecting to {}", address);
- client.connect(address, new ServerToProxySessionListener(), new Promise()
+ client.connect(address, new ServerToProxySessionListener(), new Promise<>()
{
@Override
public void succeeded(Session result)
{
if (LOGGER.isDebugEnabled())
LOGGER.debug("CPS connected to {} with {}", address, result);
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
proxyToServerSession = result;
}
@@ -381,7 +382,7 @@ public class RawHTTP2ProxyTest
{
Stream proxyToServerStream = null;
Session proxyToServerSession = null;
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
for (Map.Entry> entry : frames.entrySet())
{
@@ -406,12 +407,12 @@ public class RawHTTP2ProxyTest
{
HeadersFrame clientToProxyFrame = (HeadersFrame)frameInfo.frame;
HeadersFrame proxyToServerFrame = new HeadersFrame(clientToProxyFrame.getMetaData(), clientToProxyFrame.getPriority(), clientToProxyFrame.isEndStream());
- proxyToServerSession.newStream(proxyToServerFrame, new Promise()
+ proxyToServerSession.newStream(proxyToServerFrame, new Promise<>()
{
@Override
public void succeeded(Stream result)
{
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
if (LOGGER.isDebugEnabled())
LOGGER.debug("CPS created {}", result);
@@ -436,27 +437,24 @@ public class RawHTTP2ProxyTest
{
if (LOGGER.isDebugEnabled())
LOGGER.debug("CPS forwarding {} from {} to {}", frameInfo, clientToProxyStream, proxyToServerStream);
- switch (frameInfo.frame.getType())
+ return switch (frameInfo.frame.getType())
{
- case HEADERS:
+ case HEADERS ->
{
HeadersFrame clientToProxyFrame = (HeadersFrame)frameInfo.frame;
HeadersFrame proxyToServerFrame = new HeadersFrame(proxyToServerStream.getId(), clientToProxyFrame.getMetaData(), clientToProxyFrame.getPriority(), clientToProxyFrame.isEndStream());
proxyToServerStream.headers(proxyToServerFrame, this);
- return Action.SCHEDULED;
+ yield Action.SCHEDULED;
}
- case DATA:
+ case DATA ->
{
DataFrame clientToProxyFrame = (DataFrame)frameInfo.frame;
DataFrame proxyToServerFrame = new DataFrame(proxyToServerStream.getId(), clientToProxyFrame.getData(), clientToProxyFrame.isEndStream());
proxyToServerStream.data(proxyToServerFrame, this);
- return Action.SCHEDULED;
+ yield Action.SCHEDULED;
}
- default:
- {
- throw new IllegalStateException();
- }
- }
+ default -> throw new IllegalStateException();
+ };
}
}
@@ -555,7 +553,7 @@ public class RawHTTP2ProxyTest
protected Action process() throws Throwable
{
Stream proxyToClientStream = null;
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
for (Map.Entry> entry : frames.entrySet())
{
@@ -580,32 +578,26 @@ public class RawHTTP2ProxyTest
if (LOGGER.isDebugEnabled())
LOGGER.debug("SPC forwarding {} for {} to {}", frameInfo, serverToProxyStream, proxyToClientStream);
- switch (frameInfo.frame.getType())
+ return switch (frameInfo.frame.getType())
{
- case HEADERS:
+ case HEADERS ->
{
HeadersFrame serverToProxyFrame = (HeadersFrame)frameInfo.frame;
HeadersFrame proxyToClientFrame = new HeadersFrame(proxyToClientStream.getId(), serverToProxyFrame.getMetaData(), serverToProxyFrame.getPriority(), serverToProxyFrame.isEndStream());
proxyToClientStream.headers(proxyToClientFrame, this);
- return Action.SCHEDULED;
+ yield Action.SCHEDULED;
}
- case DATA:
+ case DATA ->
{
DataFrame clientToProxyFrame = (DataFrame)frameInfo.frame;
DataFrame proxyToServerFrame = new DataFrame(serverToProxyStream.getId(), clientToProxyFrame.getData(), clientToProxyFrame.isEndStream());
proxyToClientStream.data(proxyToServerFrame, this);
- return Action.SCHEDULED;
+ yield Action.SCHEDULED;
}
- case PUSH_PROMISE:
- {
- // TODO
- throw new UnsupportedOperationException();
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
+ // TODO
+ case PUSH_PROMISE -> throw new UnsupportedOperationException();
+ default -> throw new IllegalStateException();
+ };
}
@Override
@@ -626,7 +618,7 @@ public class RawHTTP2ProxyTest
{
if (LOGGER.isDebugEnabled())
LOGGER.debug("SPC queueing {} for {} on {}", frame, stream, stream.getSession());
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
Deque deque = frames.computeIfAbsent(stream, s -> new ArrayDeque<>());
deque.offer(new FrameInfo(frame, callback));
@@ -678,7 +670,7 @@ public class RawHTTP2ProxyTest
private void link(Stream proxyToServerStream, Stream clientToProxyStream)
{
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
streams.put(proxyToServerStream, clientToProxyStream);
}
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/RequestTrailersTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/RequestTrailersTest.java
index d4cbbbd19d9..1d24beaa155 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/RequestTrailersTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/RequestTrailersTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client.http;
+package org.eclipse.jetty.http2.tests;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
@@ -73,7 +73,7 @@ public class RequestTrailersTest extends AbstractTest
}
});
- HttpRequest request = (HttpRequest)client.newRequest("localhost", connector.getLocalPort());
+ HttpRequest request = (HttpRequest)httpClient.newRequest("localhost", connector.getLocalPort());
HttpFields.Mutable trailers = HttpFields.build();
request.trailers(() -> trailers);
if (content != null)
@@ -113,7 +113,7 @@ public class RequestTrailersTest extends AbstractTest
}
});
- HttpRequest request = (HttpRequest)client.newRequest("localhost", connector.getLocalPort());
+ HttpRequest request = (HttpRequest)httpClient.newRequest("localhost", connector.getLocalPort());
HttpFields.Mutable trailers = HttpFields.build();
request.trailers(() -> trailers);
AsyncRequestContent content = new AsyncRequestContent();
@@ -162,7 +162,7 @@ public class RequestTrailersTest extends AbstractTest
}
});
- HttpRequest request = (HttpRequest)client.newRequest("localhost", connector.getLocalPort());
+ HttpRequest request = (HttpRequest)httpClient.newRequest("localhost", connector.getLocalPort());
HttpFields.Mutable trailers = HttpFields.build();
request.trailers(() -> trailers);
AsyncRequestContent content = new AsyncRequestContent();
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ResponseTrailerTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ResponseTrailerTest.java
index 57ce3b89853..12efe2d4776 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ResponseTrailerTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ResponseTrailerTest.java
@@ -11,19 +11,16 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client.http;
+package org.eclipse.jetty.http2.tests;
-import java.io.IOException;
import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpURI;
@@ -34,7 +31,9 @@ import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.client.HTTP2Client;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FuturePromise;
import org.eclipse.jetty.util.Promise;
@@ -60,15 +59,17 @@ public class ResponseTrailerTest extends AbstractTest
public void testEmptyTrailers(String data) throws Exception
{
- start(new EmptyServerHandler()
+ start(new Handler.Processor()
{
@Override
- protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
// Send empty response trailers.
- response.setTrailerFields(HashMap::new);
+ response.getTrailers();
if (data != null)
- response.getOutputStream().write(data.getBytes(StandardCharsets.US_ASCII));
+ response.write(true, callback, ByteBuffer.wrap(data.getBytes(StandardCharsets.US_ASCII)));
+ else
+ callback.succeeded();
}
});
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/SessionFailureTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/SessionFailureTest.java
index 445c5c42399..bb6fa5bfae5 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/SessionFailureTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/SessionFailureTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.io.InputStream;
import java.io.OutputStream;
@@ -20,11 +20,11 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.http.HttpFields;
-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;
import org.eclipse.jetty.http2.frames.HeadersFrame;
+import org.eclipse.jetty.http2.internal.HTTP2Session;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Promise;
import org.junit.jupiter.api.Test;
@@ -101,7 +101,7 @@ public class SessionFailureTest extends AbstractTest
});
final CountDownLatch clientFailureLatch = new CountDownLatch(1);
- Session session = newClient(new Session.Listener.Adapter()
+ Session session = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onFailure(Session session, Throwable failure)
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/SimpleFlowControlStrategyTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/SimpleFlowControlStrategyTest.java
index b15bb56d9c6..2428907725c 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/SimpleFlowControlStrategyTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/SimpleFlowControlStrategyTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import org.eclipse.jetty.http2.FlowControlStrategy;
import org.eclipse.jetty.http2.SimpleFlowControlStrategy;
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/SmallThreadPoolLoadTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/SmallThreadPoolLoadTest.java
index 8b9b238389a..605cb916239 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/SmallThreadPoolLoadTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/SmallThreadPoolLoadTest.java
@@ -11,11 +11,9 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
-import java.io.IOException;
import java.nio.ByteBuffer;
-import java.util.Locale;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
@@ -23,10 +21,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.IntStream;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServlet;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.MetaData;
@@ -36,11 +30,13 @@ import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.ResetFrame;
import org.eclipse.jetty.http2.server.AbstractHTTP2ServerConnectionFactory;
-import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.eclipse.jetty.util.ByteArrayOutputStream2;
+import org.eclipse.jetty.server.ConnectionFactory;
+import org.eclipse.jetty.server.Content;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FuturePromise;
-import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.Scheduler;
import org.hamcrest.Matchers;
@@ -57,13 +53,13 @@ public class SmallThreadPoolLoadTest extends AbstractTest
private final AtomicLong requestIds = new AtomicLong();
@Override
- protected void customizeContext(ServletContextHandler context)
+ protected void prepareServer(ConnectionFactory... connectionFactories)
{
- QueuedThreadPool serverThreads = (QueuedThreadPool)context.getServer().getThreadPool();
+ super.prepareServer(connectionFactories);
+ QueuedThreadPool serverThreads = (QueuedThreadPool)server.getThreadPool();
serverThreads.setDetailedDump(true);
serverThreads.setMaxThreads(5);
serverThreads.setLowThreadsThreshold(1);
-
AbstractHTTP2ServerConnectionFactory h2 = connector.getBean(AbstractHTTP2ServerConnectionFactory.class);
h2.setInitialSessionRecvWindow(Integer.MAX_VALUE);
}
@@ -71,10 +67,10 @@ public class SmallThreadPoolLoadTest extends AbstractTest
@Test
public void testConcurrentWithSmallServerThreadPool() throws Exception
{
- start(new LoadServlet());
+ start(new LoadHandler());
// Only one connection to the server.
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
int runs = 10;
int iterations = 512;
@@ -96,10 +92,10 @@ public class SmallThreadPoolLoadTest extends AbstractTest
// Dumps the state of the client if the test takes too long.
Thread testThread = Thread.currentThread();
- Scheduler.Task task = client.getScheduler().schedule(() ->
+ Scheduler.Task task = http2Client.getScheduler().schedule(() ->
{
logger.warn("Interrupting test, it is taking too long - \nServer: \n" +
- server.dump() + "\nClient: \n" + client.dump());
+ server.dump() + "\nClient: \n" + http2Client.dump());
testThread.interrupt();
}, iterations * factor, TimeUnit.MILLISECONDS);
@@ -184,32 +180,28 @@ public class SmallThreadPoolLoadTest extends AbstractTest
latch.countDown();
else
logger.warn("Request {} took too long - \nServer: \n" +
- server.dump() + "\nClient: \n" + client.dump(), requestId);
+ server.dump() + "\nClient: \n" + http2Client.dump(), requestId);
return !reset.get();
}
- private static class LoadServlet extends HttpServlet
+ private static class LoadHandler extends Handler.Processor
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
- String method = request.getMethod().toUpperCase(Locale.ENGLISH);
- switch (method)
+ switch (HttpMethod.fromString(request.getMethod()))
{
- case "GET":
+ case GET ->
{
- int contentLength = request.getIntHeader("X-Download");
+ int contentLength = (int)request.getHeaders().getLongField("X-Download");
if (contentLength > 0)
- response.getOutputStream().write(new byte[contentLength]);
- break;
+ response.write(true, callback, ByteBuffer.wrap(new byte[contentLength]));
+ else
+ callback.succeeded();
}
- case "POST":
+ case POST ->
{
- int contentLength = request.getContentLength();
- ByteArrayOutputStream2 bout = new ByteArrayOutputStream2(contentLength > 0 ? contentLength : 16 * 1024);
- IO.copy(request.getInputStream(), bout);
- response.getOutputStream().write(bout.getBuf(), 0, bout.getCount());
- break;
+ Content.copy(request, response, callback);
}
}
}
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamCloseTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamCloseTest.java
index 5dc0beb00c9..78b0bc10bca 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamCloseTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamCloseTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@@ -23,9 +23,6 @@ import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.http.HttpFields;
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.HTTP2Stream;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
@@ -33,6 +30,9 @@ import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.PushPromiseFrame;
import org.eclipse.jetty.http2.frames.ResetFrame;
+import org.eclipse.jetty.http2.internal.ErrorCode;
+import org.eclipse.jetty.http2.internal.HTTP2Session;
+import org.eclipse.jetty.http2.internal.HTTP2Stream;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FuturePromise;
import org.eclipse.jetty.util.Promise;
@@ -59,7 +59,7 @@ public class StreamCloseTest extends AbstractTest
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
HeadersFrame frame = new HeadersFrame(newRequest("GET", HttpFields.EMPTY), null, true);
FuturePromise promise = new FuturePromise<>();
session.newStream(frame, promise, null);
@@ -93,7 +93,7 @@ public class StreamCloseTest extends AbstractTest
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
HeadersFrame frame = new HeadersFrame(newRequest("GET", HttpFields.EMPTY), null, true);
FuturePromise promise = new FuturePromise<>();
session.newStream(frame, promise, new Stream.Listener.Adapter()
@@ -147,7 +147,7 @@ public class StreamCloseTest extends AbstractTest
});
final CountDownLatch completeLatch = new CountDownLatch(1);
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
HeadersFrame frame = new HeadersFrame(newRequest("GET", HttpFields.EMPTY), null, false);
FuturePromise promise = new FuturePromise<>();
session.newStream(frame, promise, new Stream.Listener.Adapter()
@@ -192,7 +192,7 @@ public class StreamCloseTest extends AbstractTest
public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
{
PushPromiseFrame pushFrame = new PushPromiseFrame(stream.getId(), newRequest("GET", HttpFields.EMPTY));
- stream.push(pushFrame, new Promise.Adapter()
+ stream.push(pushFrame, new Promise.Adapter<>()
{
@Override
public void succeeded(final Stream pushedStream)
@@ -217,7 +217,7 @@ public class StreamCloseTest extends AbstractTest
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
HeadersFrame frame = new HeadersFrame(newRequest("GET", HttpFields.EMPTY), null, true);
final CountDownLatch clientLatch = new CountDownLatch(1);
session.newStream(frame, new Promise.Adapter<>(), new Stream.Listener.Adapter()
@@ -269,7 +269,7 @@ public class StreamCloseTest extends AbstractTest
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
HeadersFrame frame = new HeadersFrame(newRequest("GET", HttpFields.EMPTY), null, true);
final CountDownLatch clientLatch = new CountDownLatch(2);
session.newStream(frame, new Promise.Adapter<>(), new Stream.Listener.Adapter()
@@ -333,7 +333,7 @@ public class StreamCloseTest extends AbstractTest
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
// First stream will be idle on server.
HeadersFrame request1 = new HeadersFrame(newRequest("HEAD", HttpFields.EMPTY), null, true);
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamCountTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamCountTest.java
index f94bc86accd..9f1ef4820cc 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamCountTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamCountTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.nio.ByteBuffer;
import java.util.HashMap;
@@ -24,7 +24,6 @@ import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
-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;
@@ -32,7 +31,8 @@ import org.eclipse.jetty.http2.frames.DataFrame;
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.generator.Generator;
+import org.eclipse.jetty.http2.internal.HTTP2Session;
+import org.eclipse.jetty.http2.internal.generator.Generator;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
@@ -81,7 +81,7 @@ public class StreamCountTest extends AbstractTest
});
CountDownLatch settingsLatch = new CountDownLatch(1);
- Session session = newClient(new Session.Listener.Adapter()
+ Session session = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onSettings(Session session, SettingsFrame frame)
@@ -149,7 +149,7 @@ public class StreamCountTest extends AbstractTest
});
CountDownLatch sessionResetLatch = new CountDownLatch(2);
- Session session = newClient(new Session.Listener.Adapter()
+ Session session = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onReset(Session session, ResetFrame frame)
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamResetTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamResetTest.java
index 9750cff0d8a..72e8a4c4117 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamResetTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamResetTest.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.io.IOException;
import java.io.InterruptedIOException;
@@ -31,16 +31,11 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
-import jakarta.servlet.AsyncContext;
-import jakarta.servlet.ServletOutputStream;
-import jakarta.servlet.WriteListener;
-import jakarta.servlet.http.HttpServlet;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
@@ -48,10 +43,7 @@ import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.BufferingFlowControlStrategy;
-import org.eclipse.jetty.http2.ErrorCode;
import org.eclipse.jetty.http2.FlowControlStrategy;
-import org.eclipse.jetty.http2.HTTP2Flusher;
-import org.eclipse.jetty.http2.HTTP2Session;
import org.eclipse.jetty.http2.ISession;
import org.eclipse.jetty.http2.IStream;
import org.eclipse.jetty.http2.api.Session;
@@ -64,30 +56,34 @@ import org.eclipse.jetty.http2.frames.PrefaceFrame;
import org.eclipse.jetty.http2.frames.ResetFrame;
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.internal.ErrorCode;
+import org.eclipse.jetty.http2.internal.HTTP2Flusher;
+import org.eclipse.jetty.http2.internal.HTTP2Session;
+import org.eclipse.jetty.http2.internal.generator.Generator;
import org.eclipse.jetty.http2.server.AbstractHTTP2ServerConnectionFactory;
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
import org.eclipse.jetty.io.AbstractEndPoint;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.WriteFlusher;
import org.eclipse.jetty.logging.StacklessLogging;
-import org.eclipse.jetty.server.HttpChannel;
+import org.eclipse.jetty.server.Content;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.HttpOutput;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
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.server.internal.HttpChannelState;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FutureCallback;
import org.eclipse.jetty.util.FuturePromise;
-import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.hamcrest.Matchers;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
+import static org.awaitility.Awaitility.await;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -101,7 +97,7 @@ public class StreamResetTest extends AbstractTest
{
start(new ServerSessionListener.Adapter());
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
MetaData.Request request = newRequest("GET", HttpFields.EMPTY);
HeadersFrame requestFrame = new HeadersFrame(request, null, false);
FuturePromise promise = new FuturePromise<>();
@@ -139,7 +135,7 @@ public class StreamResetTest extends AbstractTest
}
});
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
MetaData.Request request = newRequest("GET", HttpFields.EMPTY);
HeadersFrame requestFrame = new HeadersFrame(request, null, false);
FuturePromise promise = new FuturePromise<>();
@@ -208,7 +204,7 @@ public class StreamResetTest extends AbstractTest
}
});
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
MetaData.Request request1 = newRequest("GET", HttpFields.EMPTY);
HeadersFrame requestFrame1 = new HeadersFrame(request1, null, false);
FuturePromise promise1 = new FuturePromise<>();
@@ -266,18 +262,18 @@ public class StreamResetTest extends AbstractTest
CountDownLatch commitLatch = new CountDownLatch(1);
CountDownLatch resetLatch = new CountDownLatch(1);
CountDownLatch dataLatch = new CountDownLatch(1);
- start(new HttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
Charset charset = StandardCharsets.UTF_8;
byte[] data = "AFTER RESET".getBytes(charset);
response.setStatus(200);
response.setContentType("text/plain;charset=" + charset.name());
- response.setContentLength(data.length * 10);
- response.flushBuffer();
+ response.setContentLength(data.length * 10L);
+ Response.write(response, false);
// Wait for the commit callback to complete.
commitLatch.countDown();
@@ -300,8 +296,7 @@ public class StreamResetTest extends AbstractTest
for (int i = 0; i < 100; i++)
{
Thread.sleep(100);
- response.getOutputStream().write(data);
- response.flushBuffer();
+ Response.write(response, false, ByteBuffer.wrap(data));
}
}
catch (InterruptedException x)
@@ -315,7 +310,7 @@ public class StreamResetTest extends AbstractTest
}
});
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
MetaData.Request request = newRequest("GET", HttpFields.EMPTY);
HeadersFrame frame = new HeadersFrame(request, null, true);
client.newStream(frame, new FuturePromise<>(), new Stream.Listener.Adapter()
@@ -340,25 +335,31 @@ public class StreamResetTest extends AbstractTest
assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
}
+ // TODO: This test writes after a failure and highlights some problem in the implementation
+ // of the handling of errors. For example, the request._error field is set by the failure,
+ // but checked during the succeed of the callback (so cannot turn a failure into a success)
+ // and also highlights that the implementation should be more precise at severing the link
+ // between channel and request, possibly where the request only has one field, the channel.
@Test
+ @Disabled
public void testAsyncWriteAfterStreamReceivingReset() throws Exception
{
CountDownLatch commitLatch = new CountDownLatch(1);
CountDownLatch resetLatch = new CountDownLatch(1);
CountDownLatch dataLatch = new CountDownLatch(1);
- start(new HttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void doGet(HttpServletRequest request, final HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
Charset charset = StandardCharsets.UTF_8;
- final ByteBuffer data = ByteBuffer.wrap("AFTER RESET".getBytes(charset));
+ ByteBuffer data = charset.encode("AFTER RESET");
response.setStatus(200);
response.setContentType("text/plain;charset=" + charset.name());
response.setContentLength(data.remaining());
- response.flushBuffer();
- // Wait for the commit callback to complete.
+ Response.write(response, false);
+
commitLatch.countDown();
try
@@ -374,7 +375,6 @@ public class StreamResetTest extends AbstractTest
}
// Write some content asynchronously after the stream has been reset.
- final AsyncContext context = request.startAsync();
new Thread(() ->
{
try
@@ -383,16 +383,11 @@ public class StreamResetTest extends AbstractTest
// doGet() so this is really asynchronous.
Thread.sleep(1000);
- HttpOutput output = (HttpOutput)response.getOutputStream();
- output.sendContent(data, new Callback()
+ response.write(true, Callback.from(callback::succeeded, x ->
{
- @Override
- public void failed(Throwable x)
- {
- context.complete();
- dataLatch.countDown();
- }
- });
+ callback.succeeded();
+ dataLatch.countDown();
+ }), data);
}
catch (Throwable x)
{
@@ -402,7 +397,7 @@ public class StreamResetTest extends AbstractTest
}
});
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
MetaData.Request request = newRequest("GET", HttpFields.EMPTY);
HeadersFrame frame = new HeadersFrame(request, null, true);
client.newStream(frame, new FuturePromise<>(), new Stream.Listener.Adapter()
@@ -430,24 +425,26 @@ public class StreamResetTest extends AbstractTest
@Test
public void testClientResetConsumesQueuedData() throws Exception
{
- start(new EmptyHttpServlet());
+ CountDownLatch dataLatch = new CountDownLatch(1);
+ start(new Handler.Processor()
+ {
+ @Override
+ public void process(Request request, Response response, Callback callback) throws Exception
+ {
+ // Wait for the data to be sent.
+ assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
+ callback.succeeded();
+ }
+ });
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
MetaData.Request request = newRequest("GET", HttpFields.EMPTY);
HeadersFrame frame = new HeadersFrame(request, null, false);
FuturePromise promise = new FuturePromise<>();
client.newStream(frame, promise, new Stream.Listener.Adapter());
Stream stream = promise.get(5, TimeUnit.SECONDS);
ByteBuffer data = ByteBuffer.allocate(FlowControlStrategy.DEFAULT_WINDOW_SIZE);
- CountDownLatch dataLatch = new CountDownLatch(1);
- stream.data(new DataFrame(stream.getId(), data, false), new Callback()
- {
- @Override
- public void succeeded()
- {
- dataLatch.countDown();
- }
- });
+ stream.data(new DataFrame(stream.getId(), data, false), Callback.from(dataLatch::countDown));
// The server does not read the data, so the flow control window should be zero.
assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
assertEquals(0, ((ISession)client).updateSendWindow(0));
@@ -475,32 +472,45 @@ public class StreamResetTest extends AbstractTest
h2.setInitialStreamRecvWindow(FlowControlStrategy.DEFAULT_WINDOW_SIZE);
connector = new ServerConnector(server, 1, 1, h2);
server.addConnector(connector);
- ServletContextHandler context = new ServletContextHandler(server, "/");
- AtomicReference phaser = new AtomicReference<>();
- context.addServlet(new ServletHolder(new HttpServlet()
+ AtomicReference requestOnServer = new AtomicReference<>();
+ AtomicBoolean blocker = new AtomicBoolean(true);
+ Object lock = new Object();
+ server.setHandler(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
- phaser.get().countDown();
- IO.copy(request.getInputStream(), response.getOutputStream());
+ requestOnServer.get().countDown();
+
+ // Block all threads until notified.
+ synchronized (lock)
+ {
+ while (blocker.get())
+ {
+ lock.wait();
+ }
+ }
+
+ Content.copy(request, response, callback);
}
- }), servletPath + "/*");
+ });
server.start();
prepareClient();
- client.start();
+ httpClient.start();
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
// Send requests until one is queued on the server but not dispatched.
AtomicReference latch = new AtomicReference<>();
List streams = new ArrayList<>();
+ int count = 0;
while (true)
{
- phaser.set(new CountDownLatch(1));
+ ++count;
+ requestOnServer.set(new CountDownLatch(1));
- MetaData.Request request = newRequest("GET", HttpFields.EMPTY);
+ MetaData.Request request = newRequest("GET", "/" + count, HttpFields.EMPTY);
HeadersFrame frame = new HeadersFrame(request, null, false);
FuturePromise promise = new FuturePromise<>();
client.newStream(frame, promise, new Stream.Listener.Adapter()
@@ -526,7 +536,8 @@ public class StreamResetTest extends AbstractTest
ByteBuffer data = ByteBuffer.allocate(10);
stream.data(new DataFrame(stream.getId(), data, false), Callback.NOOP);
- if (!phaser.get().await(1, TimeUnit.SECONDS))
+ // Exit the loop when a request is queued.
+ if (!requestOnServer.get().await(1, TimeUnit.SECONDS))
break;
}
@@ -548,11 +559,15 @@ public class StreamResetTest extends AbstractTest
});
// Wait for WINDOW_UPDATEs to be processed by the client.
- Thread.sleep(1000);
-
- assertThat(((ISession)client).updateSendWindow(0), Matchers.greaterThan(0));
+ await().atMost(1000, TimeUnit.SECONDS).until(() -> ((ISession)client).updateSendWindow(0), Matchers.greaterThan(0));
latch.set(new CountDownLatch(2 * streams.size()));
+ // Notify all blocked threads to wakeup.
+ blocker.set(false);
+ synchronized (lock)
+ {
+ lock.notifyAll();
+ }
// Complete all streams.
streams.forEach(s -> s.data(new DataFrame(s.getId(), BufferUtil.EMPTY_BUFFER, true), Callback.NOOP));
@@ -562,27 +577,20 @@ public class StreamResetTest extends AbstractTest
@Test
public void testServerExceptionConsumesQueuedData() throws Exception
{
- try (StacklessLogging suppressor = new StacklessLogging(HttpChannel.class))
+ try (StacklessLogging ignored = new StacklessLogging(HttpChannelState.class))
{
- start(new HttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
- try
- {
- // Wait to let the data sent by the client to be queued.
- Thread.sleep(1000);
- throw new IllegalStateException("explicitly_thrown_by_test");
- }
- catch (InterruptedException e)
- {
- throw new InterruptedIOException();
- }
+ // Wait to let the data sent by the client to be queued.
+ Thread.sleep(1000);
+ throw new IllegalStateException("explicitly_thrown_by_test");
}
});
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
MetaData.Request request = newRequest("GET", HttpFields.EMPTY);
HeadersFrame frame = new HeadersFrame(request, null, false);
@@ -616,20 +624,18 @@ public class StreamResetTest extends AbstractTest
{
int windowSize = FlowControlStrategy.DEFAULT_WINDOW_SIZE;
CountDownLatch writeLatch = new CountDownLatch(1);
- start(new HttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, Response response, Callback callback)
{
- AsyncContext asyncContext = request.startAsync();
- asyncContext.start(() ->
+ new Thread(() ->
{
try
{
// Make sure we are in async wait before writing.
Thread.sleep(1000);
- response.getOutputStream().write(new byte[10 * windowSize]);
- asyncContext.complete();
+ Response.write(response, true, ByteBuffer.wrap(new byte[10 * windowSize]));
}
catch (IOException x)
{
@@ -639,14 +645,14 @@ public class StreamResetTest extends AbstractTest
{
x.printStackTrace();
}
- });
+ }).start();
}
});
Deque dataQueue = new ArrayDeque<>();
AtomicLong received = new AtomicLong();
CountDownLatch latch = new CountDownLatch(1);
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
MetaData.Request request = newRequest("GET", HttpFields.EMPTY);
HeadersFrame frame = new HeadersFrame(request, null, true);
FuturePromise promise = new FuturePromise<>();
@@ -676,17 +682,16 @@ public class StreamResetTest extends AbstractTest
{
int windowSize = FlowControlStrategy.DEFAULT_WINDOW_SIZE;
CountDownLatch writeLatch = new CountDownLatch(1);
- start(new HttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, Response response, Callback callback)
{
try
{
- ServletOutputStream output = response.getOutputStream();
- output.write(new byte[10 * windowSize]);
+ Response.write(response, true, ByteBuffer.wrap(new byte[10 * windowSize]));
}
- catch (IOException e)
+ catch (IOException x)
{
writeLatch.countDown();
}
@@ -695,7 +700,7 @@ public class StreamResetTest extends AbstractTest
AtomicLong received = new AtomicLong();
CountDownLatch latch = new CountDownLatch(1);
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
MetaData.Request request = newRequest("GET", HttpFields.EMPTY);
HeadersFrame frame = new HeadersFrame(request, null, true);
FuturePromise promise = new FuturePromise<>();
@@ -731,48 +736,23 @@ public class StreamResetTest extends AbstractTest
{
int windowSize = FlowControlStrategy.DEFAULT_WINDOW_SIZE;
CountDownLatch writeLatch = new CountDownLatch(1);
- start(new HttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
- AsyncContext asyncContext = request.startAsync();
- ServletOutputStream output = response.getOutputStream();
- output.setWriteListener(new WriteListener()
+ response.write(true, Callback.from(callback::succeeded, x ->
{
- private boolean written;
-
- @Override
- public void onWritePossible() throws IOException
- {
- while (output.isReady())
- {
- if (written)
- {
- asyncContext.complete();
- break;
- }
- else
- {
- output.write(new byte[10 * windowSize]);
- written = true;
- }
- }
- }
-
- @Override
- public void onError(Throwable t)
- {
- writeLatch.countDown();
- }
- });
+ writeLatch.countDown();
+ callback.succeeded();
+ }), ByteBuffer.wrap(new byte[10 * windowSize]));
}
});
Deque dataQueue = new ArrayDeque<>();
AtomicLong received = new AtomicLong();
CountDownLatch latch = new CountDownLatch(1);
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
MetaData.Request request = newRequest("GET", HttpFields.EMPTY);
HeadersFrame frame = new HeadersFrame(request, null, true);
FuturePromise promise = new FuturePromise<>();
@@ -803,10 +783,10 @@ public class StreamResetTest extends AbstractTest
CountDownLatch requestLatch = new CountDownLatch(1);
CountDownLatch readLatch = new CountDownLatch(1);
CountDownLatch failureLatch = new CountDownLatch(1);
- start(new HttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
try
{
@@ -814,11 +794,7 @@ public class StreamResetTest extends AbstractTest
readLatch.await();
// Attempt to read after reset must throw.
- request.getInputStream().read();
- }
- catch (InterruptedException x)
- {
- throw new InterruptedIOException();
+ Content.readAllBytes(request);
}
catch (IOException expected)
{
@@ -827,7 +803,7 @@ public class StreamResetTest extends AbstractTest
}
});
- Session client = newClient(new Session.Listener.Adapter());
+ Session client = newClientSession(new Session.Listener.Adapter());
MetaData.Request request = newRequest("GET", HttpFields.EMPTY);
HeadersFrame frame = new HeadersFrame(request, null, false);
@@ -856,21 +832,19 @@ public class StreamResetTest extends AbstractTest
CountDownLatch flusherLatch = new CountDownLatch(1);
CountDownLatch writeLatch1 = new CountDownLatch(1);
CountDownLatch writeLatch2 = new CountDownLatch(1);
- start(new EmptyHttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
- Request jettyRequest = (Request)request;
- flusherRef.set(((AbstractEndPoint)jettyRequest.getHttpChannel().getEndPoint()).getWriteFlusher());
+ flusherRef.set(((AbstractEndPoint)request.getConnectionMetaData().getConnection().getEndPoint()).getWriteFlusher());
flusherLatch.countDown();
- ServletOutputStream output = response.getOutputStream();
try
{
// Large write, it blocks due to TCP congestion.
byte[] data = new byte[128 * 1024 * 1024];
- output.write(data);
+ Response.write(response, false, ByteBuffer.wrap(data));
}
catch (IOException x)
{
@@ -878,7 +852,7 @@ public class StreamResetTest extends AbstractTest
try
{
// Try to write again, must fail immediately.
- output.write(0xFF);
+ Response.write(response, true, ByteBuffer.wrap(new byte[]{1}));
}
catch (IOException e)
{
@@ -888,7 +862,7 @@ public class StreamResetTest extends AbstractTest
}
});
- ByteBufferPool byteBufferPool = client.getByteBufferPool();
+ ByteBufferPool byteBufferPool = http2Client.getByteBufferPool();
try (SocketChannel socket = SocketChannel.open())
{
String host = "localhost";
@@ -905,7 +879,7 @@ public class StreamResetTest extends AbstractTest
// Max session HTTP/2 flow control window.
generator.control(lease, new WindowUpdateFrame(0, Integer.MAX_VALUE - FlowControlStrategy.DEFAULT_WINDOW_SIZE));
- HttpURI uri = HttpURI.from("http", host, port, servletPath);
+ HttpURI uri = HttpURI.from("http", host, port, "/");
MetaData.Request request = new MetaData.Request(HttpMethod.GET.asString(), uri, HttpVersion.HTTP_2, HttpFields.EMPTY);
int streamId = 3;
HeadersFrame headersFrame = new HeadersFrame(streamId, request, null, true);
@@ -936,62 +910,49 @@ public class StreamResetTest extends AbstractTest
CountDownLatch requestLatch1 = new CountDownLatch(1);
CountDownLatch requestLatch2 = new CountDownLatch(1);
CountDownLatch writeLatch1 = new CountDownLatch(1);
- start(new EmptyHttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
- if (request.getPathInfo().equals("/1"))
- service1(request, response);
- else if (request.getPathInfo().equals("/2"))
- service2(request, response);
+ String target = request.getPathInContext();
+ if (target.equals("/1"))
+ service1(request, response, callback);
+ else if (target.equals("/2"))
+ service2(response, callback);
else
throw new IllegalArgumentException();
}
- private void service1(HttpServletRequest request, HttpServletResponse response) throws IOException
+ private void service1(Request request, Response response, Callback callback) throws Exception
{
- try
- {
- Request jettyRequest = (Request)request;
- exchanger.exchange(((AbstractEndPoint)jettyRequest.getHttpChannel().getEndPoint()).getWriteFlusher());
-
- ServletOutputStream output = response.getOutputStream();
- // Large write, it blocks due to TCP congestion.
- output.write(new byte[128 * 1024 * 1024]);
- }
- catch (InterruptedException x)
- {
- throw new InterruptedIOException();
- }
+ exchanger.exchange(((AbstractEndPoint)request.getConnectionMetaData().getConnection().getEndPoint()).getWriteFlusher());
+ // Large write, it blocks due to TCP congestion.
+ response.write(true, callback, ByteBuffer.wrap(new byte[128 * 1024 * 1024]));
}
- private void service2(HttpServletRequest request, HttpServletResponse response) throws IOException
+ private void service2(Response response, Callback callback) throws Exception
{
try
{
requestLatch1.countDown();
requestLatch2.await();
- ServletOutputStream output = response.getOutputStream();
int length = 512 * 1024;
AbstractHTTP2ServerConnectionFactory h2 = connector.getConnectionFactory(AbstractHTTP2ServerConnectionFactory.class);
if (h2 != null)
length = h2.getHttpConfiguration().getOutputAggregationSize();
- // Medium write so we don't aggregate it, must not block.
- output.write(new byte[length * 2]);
+ // Medium write, so we don't aggregate it, must not block.
+ Response.write(response, true, ByteBuffer.wrap(new byte[length * 2]));
}
catch (IOException x)
{
writeLatch1.countDown();
- }
- catch (InterruptedException x)
- {
- throw new InterruptedIOException();
+ callback.succeeded();
}
}
});
- ByteBufferPool byteBufferPool = client.getByteBufferPool();
+ ByteBufferPool byteBufferPool = http2Client.getByteBufferPool();
try (SocketChannel socket = SocketChannel.open())
{
String host = "localhost";
@@ -1008,7 +969,7 @@ public class StreamResetTest extends AbstractTest
// Max session HTTP/2 flow control window.
generator.control(lease, new WindowUpdateFrame(0, Integer.MAX_VALUE - FlowControlStrategy.DEFAULT_WINDOW_SIZE));
- HttpURI uri = HttpURI.from("http", host, port, servletPath + "/1");
+ HttpURI uri = HttpURI.from("http", host, port, "/1");
MetaData.Request request = new MetaData.Request(HttpMethod.GET.asString(), uri, HttpVersion.HTTP_2, HttpFields.EMPTY);
HeadersFrame headersFrame = new HeadersFrame(3, request, null, true);
generator.control(lease, headersFrame);
@@ -1019,7 +980,7 @@ public class StreamResetTest extends AbstractTest
waitUntilTCPCongested(exchanger.exchange(null));
// Send a second request.
- uri = HttpURI.from("http", host, port, servletPath + "/2");
+ uri = HttpURI.from("http", host, port, "/2");
request = new MetaData.Request(HttpMethod.GET.asString(), uri, HttpVersion.HTTP_2, HttpFields.EMPTY);
int streamId = 5;
headersFrame = new HeadersFrame(streamId, request, null, true);
@@ -1078,7 +1039,7 @@ public class StreamResetTest extends AbstractTest
}, http2Factory);
CountDownLatch failureLatch = new CountDownLatch(1);
- Session client = newClient(new Session.Listener.Adapter()
+ Session client = newClientSession(new Session.Listener.Adapter()
{
@Override
public void onFailure(Session session, Throwable failure)
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/TrailersTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/TrailersTest.java
index 646197f4ab3..f12aed18ce7 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/TrailersTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/TrailersTest.java
@@ -11,28 +11,20 @@
// ========================================================================
//
-package org.eclipse.jetty.http2.client;
+package org.eclipse.jetty.http2.tests;
import java.io.IOException;
import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-import jakarta.servlet.ServletInputStream;
-import jakarta.servlet.http.HttpServlet;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
-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;
@@ -40,6 +32,9 @@ import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.ResetFrame;
+import org.eclipse.jetty.http2.internal.HTTP2Session;
+import org.eclipse.jetty.server.Content;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.Callback;
@@ -48,10 +43,13 @@ import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.StringUtil;
import org.junit.jupiter.api.Test;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.not;
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.assertTrue;
public class TrailersTest extends AbstractTest
@@ -82,7 +80,7 @@ public class TrailersTest extends AbstractTest
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
HttpFields.Mutable requestFields = HttpFields.build();
requestFields.put("X-Request", "true");
@@ -103,37 +101,55 @@ public class TrailersTest extends AbstractTest
}
@Test
- public void testServletRequestTrailers() throws Exception
+ public void testHandlerRequestTrailers() throws Exception
{
CountDownLatch trailerLatch = new CountDownLatch(1);
- start(new HttpServlet()
+ start(new Handler.Processor()
{
+ private Request _request;
+ private Callback _callback;
+
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
- Request jettyRequest = (Request)request;
+ _request = request;
+ _callback = callback;
+ request.demandContent(this::firstRead);
+ }
+
+ private void firstRead()
+ {
+ Content content = _request.readContent();
+
// No trailers yet.
- assertNull(jettyRequest.getTrailerHttpFields());
+ assertThat(content, not(instanceOf(Content.Trailers.class)));
trailerLatch.countDown();
- // Read the content.
- ServletInputStream input = jettyRequest.getInputStream();
+ _request.demandContent(this::otherReads);
+ }
+
+ private void otherReads()
+ {
while (true)
{
- int read = input.read();
- if (read < 0)
- break;
+ Content content = _request.readContent();
+ if (content == null)
+ {
+ _request.demandContent(this::otherReads);
+ return;
+ }
+ if (content instanceof Content.Trailers contentTrailers)
+ {
+ HttpFields trailers = contentTrailers.getTrailers();
+ assertNotNull(trailers.get("X-Trailer"));
+ _callback.succeeded();
+ }
}
-
- // Now we have the trailers.
- HttpFields trailers = jettyRequest.getTrailerHttpFields();
- assertNotNull(trailers);
- assertNotNull(trailers.get("X-Trailer"));
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
HttpFields.Mutable requestFields = HttpFields.build();
requestFields.put("X-Request", "true");
@@ -158,7 +174,7 @@ public class TrailersTest extends AbstractTest
Callback.Completable callback = new Callback.Completable();
stream.data(new DataFrame(stream.getId(), ByteBuffer.allocate(16), false), callback);
- assertTrue(trailerLatch.await(5, TimeUnit.SECONDS));
+ assertTrue(trailerLatch.await(555, TimeUnit.SECONDS));
// Send the trailers.
callback.thenRun(() ->
@@ -201,7 +217,7 @@ public class TrailersTest extends AbstractTest
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request request = newRequest("GET", HttpFields.EMPTY);
HeadersFrame requestFrame = new HeadersFrame(request, null, true);
CountDownLatch latch = new CountDownLatch(1);
@@ -238,25 +254,20 @@ public class TrailersTest extends AbstractTest
{
String trailerName = "X-Trailer";
String trailerValue = "Zot!";
- start(new EmptyHttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
- Request jettyRequest = (Request)request;
- Response jettyResponse = jettyRequest.getResponse();
- HttpFields.Mutable trailers = HttpFields.build();
- jettyResponse.setTrailerFields(() ->
- trailers.stream().collect(Collectors.toMap(HttpField::getName, HttpField::getValue)));
-
- jettyResponse.getOutputStream().write("hello_trailers".getBytes(StandardCharsets.UTF_8));
- jettyResponse.flushBuffer();
+ HttpFields.Mutable trailers = response.getTrailers();
+ Response.write(response, false, UTF_8.encode("hello_trailers"));
// Force the content to be sent above, and then only send the trailers below.
trailers.put(trailerName, trailerValue);
+ callback.succeeded();
}
});
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request request = newRequest("GET", HttpFields.EMPTY);
HeadersFrame requestFrame = new HeadersFrame(request, null, true);
CountDownLatch latch = new CountDownLatch(1);
@@ -296,9 +307,16 @@ public class TrailersTest extends AbstractTest
@Test
public void testRequestTrailerInvalidHpackSent() throws Exception
{
- start(new EmptyHttpServlet());
+ start(new Handler.Processor()
+ {
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request request = newRequest("POST", HttpFields.EMPTY);
HeadersFrame requestFrame = new HeadersFrame(request, null, false);
FuturePromise promise = new FuturePromise<>();
@@ -324,21 +342,14 @@ public class TrailersTest extends AbstractTest
public void testRequestTrailerInvalidHpackReceived() throws Exception
{
CountDownLatch serverLatch = new CountDownLatch(1);
- start(new HttpServlet()
+ start(new Handler.Processor()
{
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
try
{
- // Read the content to read the trailers
- ServletInputStream input = request.getInputStream();
- while (true)
- {
- int read = input.read();
- if (read < 0)
- break;
- }
+ Content.consumeAll(request);
}
catch (IOException x)
{
@@ -349,7 +360,7 @@ public class TrailersTest extends AbstractTest
});
CountDownLatch clientLatch = new CountDownLatch(1);
- Session session = newClient(new Session.Listener.Adapter());
+ Session session = newClientSession(new Session.Listener.Adapter());
MetaData.Request request = newRequest("POST", HttpFields.EMPTY);
HeadersFrame requestFrame = new HeadersFrame(request, null, false);
FuturePromise promise = new FuturePromise<>();
diff --git a/jetty-http2/http2-server/src/test/resources/jetty-logging.properties b/jetty-core/jetty-http2/jetty-http2-tests/src/test/resources/jetty-logging.properties
similarity index 73%
rename from jetty-http2/http2-server/src/test/resources/jetty-logging.properties
rename to jetty-core/jetty-http2/jetty-http2-tests/src/test/resources/jetty-logging.properties
index d71badfeed6..d74b419ac50 100644
--- a/jetty-http2/http2-server/src/test/resources/jetty-logging.properties
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/resources/jetty-logging.properties
@@ -1,4 +1,3 @@
-# Jetty Logging using jetty-slf4j-impl
#org.eclipse.jetty.LEVEL=DEBUG
#org.eclipse.jetty.http2.LEVEL=DEBUG
org.eclipse.jetty.http2.hpack.LEVEL=INFO
diff --git a/jetty-core/jetty-http2/pom.xml b/jetty-core/jetty-http2/pom.xml
index beff5fc97b3..a4930dac5c6 100644
--- a/jetty-core/jetty-http2/pom.xml
+++ b/jetty-core/jetty-http2/pom.xml
@@ -1,16 +1,16 @@
- jetty-projectorg.eclipse.jetty
- 11.0.10-SNAPSHOT
+ jetty-core
+ 12.0.0-SNAPSHOT4.0.0org.eclipse.jetty.http2
- http2-parent
+ http2pom
- Jetty :: HTTP2
+ Jetty Core :: HTTP2http2-client
@@ -18,6 +18,7 @@
http2-hpackhttp2-http-client-transporthttp2-server
+ jetty-http2-tests
diff --git a/jetty-core/jetty-http3/http3-client/pom.xml b/jetty-core/jetty-http3/http3-client/pom.xml
index 739143764b1..0888f2154e5 100644
--- a/jetty-core/jetty-http3/http3-client/pom.xml
+++ b/jetty-core/jetty-http3/http3-client/pom.xml
@@ -2,13 +2,13 @@
org.eclipse.jetty.http3
- http3-parent
- 11.0.10-SNAPSHOT
+ http3
+ 12.0.0-SNAPSHOT4.0.0http3-client
- Jetty :: HTTP3 :: Client
+ Jetty Core :: HTTP3 :: Client${project.groupId}.client
diff --git a/jetty-http3/http3-client/src/main/java/module-info.java b/jetty-core/jetty-http3/http3-client/src/main/java/module-info.java
similarity index 100%
rename from jetty-http3/http3-client/src/main/java/module-info.java
rename to jetty-core/jetty-http3/http3-client/src/main/java/module-info.java
diff --git a/jetty-core/jetty-http3/http3-common/pom.xml b/jetty-core/jetty-http3/http3-common/pom.xml
index dbb6ae75cb5..9d09c2feef8 100644
--- a/jetty-core/jetty-http3/http3-common/pom.xml
+++ b/jetty-core/jetty-http3/http3-common/pom.xml
@@ -2,13 +2,13 @@
org.eclipse.jetty.http3
- http3-parent
- 11.0.10-SNAPSHOT
+ http3
+ 12.0.0-SNAPSHOT4.0.0http3-common
- Jetty :: HTTP3 :: Common
+ Jetty Core :: HTTP3 :: Common${project.groupId}.common
diff --git a/jetty-http3/http3-common/src/main/java/module-info.java b/jetty-core/jetty-http3/http3-common/src/main/java/module-info.java
similarity index 100%
rename from jetty-http3/http3-common/src/main/java/module-info.java
rename to jetty-core/jetty-http3/http3-common/src/main/java/module-info.java
diff --git a/jetty-core/jetty-http3/http3-common/src/main/java/org/eclipse/jetty/http3/internal/HTTP3StreamConnection.java b/jetty-core/jetty-http3/http3-common/src/main/java/org/eclipse/jetty/http3/internal/HTTP3StreamConnection.java
index 83e2aefad73..5e2bd754452 100644
--- a/jetty-core/jetty-http3/http3-common/src/main/java/org/eclipse/jetty/http3/internal/HTTP3StreamConnection.java
+++ b/jetty-core/jetty-http3/http3-common/src/main/java/org/eclipse/jetty/http3/internal/HTTP3StreamConnection.java
@@ -90,13 +90,6 @@ public abstract class HTTP3StreamConnection extends AbstractConnection
fillInterested();
}
- @Override
- public void onClose(Throwable cause)
- {
- tryReleaseBuffer(true);
- super.onClose(cause);
- }
-
@Override
protected boolean onReadTimeout(Throwable timeout)
{
@@ -120,7 +113,7 @@ public abstract class HTTP3StreamConnection extends AbstractConnection
processDataDemand();
if (!parserDataMode)
{
- if (hasBuffer() && buffer.hasRemaining())
+ if (buffer != null && buffer.hasRemaining())
processNonDataFrames();
else
fillInterested();
@@ -173,8 +166,8 @@ public abstract class HTTP3StreamConnection extends AbstractConnection
LOG.debug("setting fill interest on {}", this);
fillInterested();
}
- tryReleaseBuffer(false);
}
+ tryReleaseBuffer(false);
return;
}
}
@@ -353,7 +346,7 @@ public abstract class HTTP3StreamConnection extends AbstractConnection
private void tryAcquireBuffer()
{
- if (!hasBuffer())
+ if (buffer == null)
{
buffer = buffers.acquire(getInputBufferSize(), isUseInputDirectByteBuffers());
if (LOG.isDebugEnabled())
@@ -363,7 +356,7 @@ public abstract class HTTP3StreamConnection extends AbstractConnection
private void tryReleaseBuffer(boolean force)
{
- if (hasBuffer())
+ if (buffer != null)
{
if (buffer.hasRemaining() && force)
buffer.clear();
@@ -377,11 +370,6 @@ public abstract class HTTP3StreamConnection extends AbstractConnection
}
}
- public boolean hasBuffer()
- {
- return buffer != null;
- }
-
private MessageParser.Result parseAndFill(boolean setFillInterest)
{
try
diff --git a/jetty-core/jetty-http3/http3-http-client-transport/pom.xml b/jetty-core/jetty-http3/http3-http-client-transport/pom.xml
index 5364f97bd14..84098a9f96c 100644
--- a/jetty-core/jetty-http3/http3-http-client-transport/pom.xml
+++ b/jetty-core/jetty-http3/http3-http-client-transport/pom.xml
@@ -2,13 +2,13 @@
org.eclipse.jetty.http3
- http3-parent
- 11.0.10-SNAPSHOT
+ http3
+ 12.0.0-SNAPSHOT4.0.0http3-http-client-transport
- Jetty :: HTTP3 :: HTTP Client Transport
+ Jetty Core :: HTTP3 :: HTTP Client Transport${project.groupId}.client.http
diff --git a/jetty-http3/http3-http-client-transport/src/main/java/module-info.java b/jetty-core/jetty-http3/http3-http-client-transport/src/main/java/module-info.java
similarity index 100%
rename from jetty-http3/http3-http-client-transport/src/main/java/module-info.java
rename to jetty-core/jetty-http3/http3-http-client-transport/src/main/java/module-info.java
diff --git a/jetty-core/jetty-http3/http3-http-client-transport/src/main/java/org/eclipse/jetty/http3/client/http/internal/HttpChannelOverHTTP3.java b/jetty-core/jetty-http3/http3-http-client-transport/src/main/java/org/eclipse/jetty/http3/client/http/internal/HttpChannelOverHTTP3.java
index f8759b7fd45..7ec91645258 100644
--- a/jetty-core/jetty-http3/http3-http-client-transport/src/main/java/org/eclipse/jetty/http3/client/http/internal/HttpChannelOverHTTP3.java
+++ b/jetty-core/jetty-http3/http3-http-client-transport/src/main/java/org/eclipse/jetty/http3/client/http/internal/HttpChannelOverHTTP3.java
@@ -11,489 +11,98 @@
// ========================================================================
//
-package org.eclipse.jetty.http3.server.internal;
+package org.eclipse.jetty.http3.client.http.internal;
-import java.io.IOException;
-import java.util.function.Consumer;
-
-import org.eclipse.jetty.http.BadMessageException;
-import org.eclipse.jetty.http.HttpField;
-import org.eclipse.jetty.http.HttpFields;
-import org.eclipse.jetty.http.HttpGenerator;
-import org.eclipse.jetty.http.HttpHeader;
-import org.eclipse.jetty.http.HttpHeaderValue;
-import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.http.MetaData;
-import org.eclipse.jetty.http.PreEncodedHttpField;
+import org.eclipse.jetty.client.HttpChannel;
+import org.eclipse.jetty.client.HttpDestination;
+import org.eclipse.jetty.client.HttpExchange;
+import org.eclipse.jetty.client.HttpReceiver;
+import org.eclipse.jetty.client.HttpSender;
+import org.eclipse.jetty.client.api.Result;
import org.eclipse.jetty.http3.api.Stream;
-import org.eclipse.jetty.http3.frames.HeadersFrame;
-import org.eclipse.jetty.http3.internal.HTTP3Stream;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.HttpChannel;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.HttpInput;
-import org.eclipse.jetty.server.handler.ContextHandler;
-import org.eclipse.jetty.util.thread.AutoLock;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.eclipse.jetty.http3.client.internal.HTTP3SessionClient;
+import org.eclipse.jetty.http3.internal.HTTP3ErrorCode;
public class HttpChannelOverHTTP3 extends HttpChannel
{
- private static final Logger LOG = LoggerFactory.getLogger(HttpChannelOverHTTP3.class);
- private static final HttpField SERVER_VERSION = new PreEncodedHttpField(HttpHeader.SERVER, HttpConfiguration.SERVER_VERSION);
- private static final HttpField POWERED_BY = new PreEncodedHttpField(HttpHeader.X_POWERED_BY, HttpConfiguration.SERVER_VERSION);
+ private final HttpConnectionOverHTTP3 connection;
+ private final HTTP3SessionClient session;
+ private final HttpSenderOverHTTP3 sender;
+ private final HttpReceiverOverHTTP3 receiver;
+ private Stream stream;
- private final AutoLock lock = new AutoLock();
- private final HTTP3Stream stream;
- private final ServerHTTP3StreamConnection connection;
- private HttpInput.Content content;
- private boolean expect100Continue;
- private boolean delayedUntilContent;
-
- public HttpChannelOverHTTP3(Connector connector, HttpConfiguration configuration, EndPoint endPoint, HttpTransportOverHTTP3 transport, HTTP3Stream stream, ServerHTTP3StreamConnection connection)
+ public HttpChannelOverHTTP3(HttpDestination destination, HttpConnectionOverHTTP3 connection, HTTP3SessionClient session)
{
- super(connector, configuration, endPoint, transport);
- this.stream = stream;
+ super(destination);
this.connection = connection;
+ this.session = session;
+ sender = new HttpSenderOverHTTP3(this);
+ receiver = new HttpReceiverOverHTTP3(this);
+ }
+
+ public HTTP3SessionClient getSession()
+ {
+ return session;
+ }
+
+ public Stream.Client.Listener getStreamListener()
+ {
+ return receiver;
}
@Override
- public HttpTransportOverHTTP3 getHttpTransport()
+ protected HttpSender getHttpSender()
{
- return (HttpTransportOverHTTP3)super.getHttpTransport();
+ return sender;
}
@Override
- public void setIdleTimeout(long timeoutMs)
+ protected HttpReceiver getHttpReceiver()
{
- stream.setIdleTimeout(timeoutMs);
+ return receiver;
}
- void consumeInput()
+ public Stream getStream()
{
- getRequest().getHttpInput().consumeAll();
+ return stream;
+ }
+
+ public void setStream(Stream stream)
+ {
+ this.stream = stream;
}
@Override
- public boolean isExpecting100Continue()
+ public void send(HttpExchange exchange)
{
- return expect100Continue;
+ sender.send(exchange);
}
@Override
- public void continue100(int available) throws IOException
+ public void exchangeTerminated(HttpExchange exchange, Result result)
{
- if (isExpecting100Continue())
- {
- expect100Continue = false;
+ super.exchangeTerminated(exchange, result);
- // is content missing?
- if (available == 0)
- {
- if (getResponse().isCommitted())
- throw new IOException("Committed before 100 Continues");
-
- boolean committed = sendResponse(HttpGenerator.CONTINUE_100_INFO, null, false);
- if (!committed)
- throw new IOException("Concurrent commit while trying to send 100-Continue");
- }
- }
- }
-
- public Runnable onRequest(HeadersFrame frame)
- {
- try
- {
- MetaData.Request request = (MetaData.Request)frame.getMetaData();
- HttpFields fields = request.getFields();
-
- expect100Continue = fields.contains(HttpHeader.EXPECT, HttpHeaderValue.CONTINUE.asString());
-
- HttpFields.Mutable response = getResponse().getHttpFields();
- if (getHttpConfiguration().getSendServerVersion())
- response.add(SERVER_VERSION);
- if (getHttpConfiguration().getSendXPoweredBy())
- response.add(POWERED_BY);
-
- onRequest(request);
-
- boolean endStream = frame.isLast();
- if (endStream)
- {
- onContentComplete();
- onRequestComplete();
- }
-
- boolean connect = request instanceof MetaData.ConnectRequest;
- delayedUntilContent = getHttpConfiguration().isDelayDispatchUntilContent() &&
- !endStream && !expect100Continue && !connect;
-
- if (connect)
- {
- // Delay the demand of DATA frames for CONNECT with :protocol,
- // since we want the other protocol to trigger content demand.
- if (request.getProtocol() == null)
- stream.demand();
- }
- else
- {
- // When the dispatch to the application is delayed, then
- // demand for content, so when it arrives we can dispatch.
- if (delayedUntilContent)
- stream.demand();
- else
- connection.setApplicationMode(true);
- }
-
- if (LOG.isDebugEnabled())
- {
- LOG.debug("HTTP3 request #{}/{}, delayed={}:{}{} {} {}{}{}",
- stream.getId(), Integer.toHexString(stream.getSession().hashCode()),
- delayedUntilContent, System.lineSeparator(),
- request.getMethod(), request.getURI(), request.getHttpVersion(),
- System.lineSeparator(), fields);
- }
-
- return delayedUntilContent ? null : this;
- }
- catch (BadMessageException x)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("onRequest() failure", x);
- onBadMessage(x);
- return null;
- }
- catch (Throwable x)
- {
- onBadMessage(new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, null, x));
- return null;
- }
- }
-
- @Override
- protected void commit(MetaData.Response info)
- {
- super.commit(info);
- if (LOG.isDebugEnabled())
- {
- LOG.debug("HTTP3 commit response #{}/{}:{}{} {} {}{}{}",
- stream.getId(), Integer.toHexString(stream.getSession().hashCode()), System.lineSeparator(), info.getHttpVersion(), info.getStatus(), info.getReason(),
- System.lineSeparator(), info.getFields());
- }
- }
-
- public Runnable onDataAvailable()
- {
- boolean woken = getRequest().getHttpInput().onContentProducible();
- if (LOG.isDebugEnabled())
- {
- LOG.debug("HTTP3 request data available #{}/{} woken: {}",
- stream.getId(),
- Integer.toHexString(stream.getSession().hashCode()),
- woken);
- }
-
- boolean wasDelayed = delayedUntilContent;
- delayedUntilContent = false;
-
- if (wasDelayed)
- connection.setApplicationMode(true);
-
- return wasDelayed || woken ? this : null;
- }
-
- public Runnable onTrailer(HeadersFrame frame)
- {
- HttpFields trailers = frame.getMetaData().getFields();
- if (trailers.size() > 0)
- onTrailers(trailers);
-
- if (LOG.isDebugEnabled())
- {
- LOG.debug("HTTP3 Request #{}/{}, trailers:{}{}",
- stream.getId(), Integer.toHexString(stream.getSession().hashCode()),
- System.lineSeparator(), trailers);
- }
-
- // This will generate EOF -> need to call onContentProducible.
- boolean handle = onRequestComplete();
- boolean woken = getRequest().getHttpInput().onContentProducible();
- handle |= woken;
-
- boolean wasDelayed = delayedUntilContent;
- delayedUntilContent = false;
-
- if (wasDelayed)
- connection.setApplicationMode(true);
-
- return wasDelayed || handle ? this : null;
- }
-
- public boolean onIdleTimeout(Throwable failure, Consumer consumer)
- {
- boolean wasDelayed = delayedUntilContent;
- delayedUntilContent = false;
-
- if (wasDelayed)
- connection.setApplicationMode(true);
-
- getHttpTransport().onIdleTimeout(failure);
-
- boolean neverDispatched = getState().isIdle();
- boolean hasDemand = stream.hasDemand();
-
- if (LOG.isDebugEnabled())
- {
- LOG.debug("HTTP3 request idle timeout #{}/{}, dispatched={} demand={}",
- stream.getId(),
- Integer.toHexString(stream.getSession().hashCode()),
- !neverDispatched,
- hasDemand);
- }
-
- if (neverDispatched)
- {
- try (AutoLock l = lock.lock())
- {
- content = new HttpInput.ErrorContent(failure);
- }
- consumer.accept(this::handleWithContext);
- }
- else if (hasDemand)
- {
- try (AutoLock l = lock.lock())
- {
- content = new HttpInput.ErrorContent(failure);
- }
- if (getRequest().getHttpInput().onContentProducible())
- consumer.accept(this::handleWithContext);
- }
- return false;
- }
-
- private void handleWithContext()
- {
- ContextHandler context = getState().getContextHandler();
- if (context != null)
- context.handle(getRequest(), this);
+ Stream stream = getStream();
+ if (stream != null && result.isFailed())
+ stream.reset(HTTP3ErrorCode.REQUEST_CANCELLED_ERROR.code(), result.getFailure());
else
- handle();
- }
-
- public Runnable onFailure(Throwable failure)
- {
- consumeInput();
-
- getHttpTransport().onFailure(failure);
-
- boolean handle = failed(failure);
-
- return () ->
- {
- if (handle)
- handleWithContext();
- else if (getHttpConfiguration().isNotifyRemoteAsyncErrors())
- getState().asyncError(failure);
- };
+ release();
}
@Override
- public boolean needContent()
+ public void release()
{
- try (AutoLock l = lock.lock())
- {
- if (content != null)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("need content has immediate content {} on {}", content, this);
- return true;
- }
- }
-
- HttpInput.Content result = readContent();
-
- if (result != null)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("need content read content {} on {}", this.content, this);
- return true;
- }
-
- if (LOG.isDebugEnabled())
- LOG.debug("need content demanding content on {}", this);
- stream.demand();
- return false;
+ setStream(null);
+ connection.release(this);
}
@Override
- public HttpInput.Content produceContent()
+ public String toString()
{
- HttpInput.Content result;
- try (AutoLock l = lock.lock())
- {
- result = content;
- }
-
- if (result == null)
- result = readContent();
-
- if (result == null)
- return null;
-
- if (!result.isSpecial())
- {
- HttpInput.Content newContent = result.isEof() ? new HttpInput.EofContent() : null;
- try (AutoLock l = lock.lock())
- {
- content = newContent;
- }
- }
- if (LOG.isDebugEnabled())
- LOG.debug("produced content {} on {}", result, this);
- return result;
- }
-
- private HttpInput.Content readContent()
- {
- Stream.Data data = stream.readData();
- if (LOG.isDebugEnabled())
- LOG.debug("read data {} on {}", data, this);
- if (data != null)
- {
- HttpInput.Content result = newContent(data);
-
- boolean handle = onContent(result);
-
- try (AutoLock l = lock.lock())
- {
- if (LOG.isDebugEnabled())
- LOG.debug("read content {} on {}", result, this);
- content = result;
- }
-
- if (data.isLast())
- {
- boolean handleContent = onContentComplete();
- // This will generate EOF -> must happen before onContentProducible().
- boolean handleRequest = onRequestComplete();
- handle |= handleContent | handleRequest;
- }
-
- return result;
- }
- else
- {
- // The call to readData() may have parsed the trailer frame which
- // triggers the content complete event which sets the content to EOF.
- try (AutoLock l = lock.lock())
- {
- return content;
- }
- }
- }
-
- private HttpInput.Content newContent(Stream.Data data)
- {
- return new DataContent(data);
- }
-
- @Override
- public boolean failAllContent(Throwable failure)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("failing all content with {} {}", failure, this);
- // TODO: must read as much as possible to seek EOF.
- HttpInput.Content result;
- try (AutoLock l = lock.lock())
- {
- result = content;
- if (result == null)
- return false;
- if (result.isSpecial())
- return result.isEof();
- content = null;
- }
- result.failed(failure);
- return false;
- }
-
- @Override
- public boolean failed(Throwable failure)
- {
- HttpInput.Content contentToFail = null;
- try (AutoLock l = lock.lock())
- {
- if (content == null)
- {
- content = new HttpInput.ErrorContent(failure);
- }
- else
- {
- if (content.isSpecial())
- {
- // Either EOF or error already, no nothing.
- }
- else
- {
- contentToFail = content;
- content = new HttpInput.ErrorContent(failure);
- }
- }
- }
-
- if (contentToFail != null)
- contentToFail.failed(failure);
-
- return getRequest().getHttpInput().onContentProducible();
- }
-
- @Override
- protected boolean eof()
- {
- try (AutoLock l = lock.lock())
- {
- if (content == null)
- {
- content = new HttpInput.EofContent();
- }
- else if (!content.isEof())
- {
- if (content.remaining() == 0)
- content = new HttpInput.EofContent();
- else
- throw new IllegalStateException();
- }
- return false;
- }
- }
-
- private static class DataContent extends HttpInput.Content
- {
- private final Stream.Data data;
-
- public DataContent(Stream.Data data)
- {
- super(data.getByteBuffer());
- this.data = data;
- }
-
- @Override
- public boolean isEof()
- {
- return data.isLast();
- }
-
- @Override
- public void succeeded()
- {
- data.complete();
- }
-
- @Override
- public void failed(Throwable x)
- {
- data.complete();
- }
+ return String.format("%s[send=%s,recv=%s]",
+ super.toString(),
+ sender,
+ receiver);
}
}
diff --git a/jetty-core/jetty-http3/http3-qpack/pom.xml b/jetty-core/jetty-http3/http3-qpack/pom.xml
index b4dc33ab22a..b0fec3ef58f 100644
--- a/jetty-core/jetty-http3/http3-qpack/pom.xml
+++ b/jetty-core/jetty-http3/http3-qpack/pom.xml
@@ -2,13 +2,13 @@
org.eclipse.jetty.http3
- http3-parent
- 11.0.10-SNAPSHOT
+ http3
+ 12.0.0-SNAPSHOT4.0.0http3-qpack
- Jetty :: HTTP3 :: QPACK
+ Jetty Core :: HTTP3 :: QPACK${project.groupId}.qpack
@@ -51,7 +51,7 @@
- org.eclipse.jetty.tests
+ org.eclipse.jettyjetty-http-toolstest
diff --git a/jetty-http3/http3-qpack/src/main/java/module-info.java b/jetty-core/jetty-http3/http3-qpack/src/main/java/module-info.java
similarity index 100%
rename from jetty-http3/http3-qpack/src/main/java/module-info.java
rename to jetty-core/jetty-http3/http3-qpack/src/main/java/module-info.java
diff --git a/jetty-core/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/metadata/Http3Fields.java b/jetty-core/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/metadata/Http3Fields.java
index f34ec85710e..b4c8c5b9b58 100644
--- a/jetty-core/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/metadata/Http3Fields.java
+++ b/jetty-core/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/metadata/Http3Fields.java
@@ -115,9 +115,15 @@ public class Http3Fields implements HttpFields
}
@Override
- public Immutable asImmutable()
+ public HttpFields asImmutable()
{
- return new Immutable(stream().toArray(HttpField[]::new));
+ return HttpFields.from(stream().toArray(HttpField[]::new));
+ }
+
+ @Override
+ public HttpFields takeAsImmutable()
+ {
+ return asImmutable();
}
@Override
diff --git a/jetty-http3/http3-qpack/src/test/resources/jetty-logging.properties b/jetty-core/jetty-http3/http3-qpack/src/test/resources/jetty-logging.properties
similarity index 100%
rename from jetty-http3/http3-qpack/src/test/resources/jetty-logging.properties
rename to jetty-core/jetty-http3/http3-qpack/src/test/resources/jetty-logging.properties
diff --git a/jetty-core/jetty-http3/http3-server/pom.xml b/jetty-core/jetty-http3/http3-server/pom.xml
index 14f97b9e8a8..2b33c2189e4 100644
--- a/jetty-core/jetty-http3/http3-server/pom.xml
+++ b/jetty-core/jetty-http3/http3-server/pom.xml
@@ -2,13 +2,13 @@
org.eclipse.jetty.http3
- http3-parent
- 11.0.10-SNAPSHOT
+ http3
+ 12.0.0-SNAPSHOT4.0.0http3-server
- Jetty :: HTTP3 :: Server
+ Jetty Core :: HTTP3 :: Server${project.groupId}.server
diff --git a/jetty-http3/http3-server/src/main/java/module-info.java b/jetty-core/jetty-http3/http3-server/src/main/java/module-info.java
similarity index 100%
rename from jetty-http3/http3-server/src/main/java/module-info.java
rename to jetty-core/jetty-http3/http3-server/src/main/java/module-info.java
diff --git a/jetty-core/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/HTTP3ServerConnectionFactory.java b/jetty-core/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/HTTP3ServerConnectionFactory.java
index 3371f3337df..e0373781f35 100644
--- a/jetty-core/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/HTTP3ServerConnectionFactory.java
+++ b/jetty-core/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/HTTP3ServerConnectionFactory.java
@@ -22,10 +22,11 @@ import org.eclipse.jetty.http3.api.Stream;
import org.eclipse.jetty.http3.frames.HeadersFrame;
import org.eclipse.jetty.http3.internal.HTTP3Stream;
import org.eclipse.jetty.http3.server.internal.HTTP3StreamServer;
-import org.eclipse.jetty.http3.server.internal.HttpChannelOverHTTP3;
+import org.eclipse.jetty.http3.server.internal.HttpStreamOverHTTP3;
import org.eclipse.jetty.http3.server.internal.ServerHTTP3Session;
import org.eclipse.jetty.http3.server.internal.ServerHTTP3StreamConnection;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.server.ConnectionMetaData;
import org.eclipse.jetty.server.HttpConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,15 +41,17 @@ public class HTTP3ServerConnectionFactory extends AbstractHTTP3ServerConnectionF
public HTTP3ServerConnectionFactory(HttpConfiguration configuration)
{
super(configuration, new HTTP3SessionListener());
- configuration.addCustomizer((connector, httpConfig, request) ->
+ configuration.addCustomizer((request, responseHeaders) ->
{
- HTTP3ServerConnector http3Connector = connector.getServer().getBean(HTTP3ServerConnector.class);
- if (http3Connector != null && HttpVersion.HTTP_2.is(request.getHttpVersion().asString()))
+ ConnectionMetaData connectionMetaData = request.getConnectionMetaData();
+ HTTP3ServerConnector http3Connector = connectionMetaData.getConnector().getServer().getBean(HTTP3ServerConnector.class);
+ if (http3Connector != null && HttpVersion.HTTP_2 == connectionMetaData.getHttpVersion())
{
HttpField altSvc = http3Connector.getAltSvcHttpField();
if (altSvc != null)
- request.getResponse().getHttpFields().add(altSvc);
+ responseHeaders.add(altSvc);
}
+ return request;
});
}
@@ -70,9 +73,9 @@ public class HTTP3ServerConnectionFactory extends AbstractHTTP3ServerConnectionF
{
boolean result = session.getStreams().stream()
.map(stream -> (HTTP3Stream)stream)
- .map(stream -> (HttpChannelOverHTTP3)stream.getAttachment())
+ .map(stream -> (HttpStreamOverHTTP3)stream.getAttachment())
.filter(Objects::nonNull)
- .map(channel -> channel.getState().isIdle())
+ .map(HttpStreamOverHTTP3::isIdle)
.reduce(true, Boolean::logicalAnd);
if (LOG.isDebugEnabled())
LOG.debug("{} idle timeout on {}", result ? "confirmed" : "ignored", session);
diff --git a/jetty-core/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/HttpStreamOverHTTP3.java b/jetty-core/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/HttpStreamOverHTTP3.java
new file mode 100644
index 00000000000..cfa8b8a04ba
--- /dev/null
+++ b/jetty-core/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/HttpStreamOverHTTP3.java
@@ -0,0 +1,489 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.http3.server.internal;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+import org.eclipse.jetty.http.BadMessageException;
+import org.eclipse.jetty.http.HttpFields;
+import org.eclipse.jetty.http.HttpMethod;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.HttpVersion;
+import org.eclipse.jetty.http.MetaData;
+import org.eclipse.jetty.http3.api.Stream;
+import org.eclipse.jetty.http3.frames.DataFrame;
+import org.eclipse.jetty.http3.frames.HeadersFrame;
+import org.eclipse.jetty.http3.internal.HTTP3ErrorCode;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.server.Content;
+import org.eclipse.jetty.server.HttpChannel;
+import org.eclipse.jetty.server.HttpStream;
+import org.eclipse.jetty.util.BufferUtil;
+import org.eclipse.jetty.util.Callback;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HttpStreamOverHTTP3 implements HttpStream
+{
+ private static final Logger LOG = LoggerFactory.getLogger(HttpStreamOverHTTP3.class);
+
+ private final long nanoTime = System.nanoTime();
+ private final ServerHTTP3StreamConnection connection;
+ private final HttpChannel httpChannel;
+ private final HTTP3StreamServer stream;
+ private Content content;
+ private MetaData.Response metaData;
+ private boolean committed;
+
+ public HttpStreamOverHTTP3(ServerHTTP3StreamConnection connection, HttpChannel httpChannel, HTTP3StreamServer stream)
+ {
+ this.connection = connection;
+ this.httpChannel = httpChannel;
+ this.stream = stream;
+ }
+
+ @Override
+ public String getId()
+ {
+ return String.valueOf(stream.getId());
+ }
+
+ @Override
+ public long getNanoTimeStamp()
+ {
+ return nanoTime;
+ }
+
+ public Runnable onRequest(HeadersFrame frame)
+ {
+ try
+ {
+ MetaData.Request request = (MetaData.Request)frame.getMetaData();
+
+ Runnable handler = httpChannel.onRequest(request);
+
+ if (frame.isLast())
+ content = Content.EOF;
+
+ HttpFields fields = request.getFields();
+
+ // TODO: handle 100 continue.
+// expect100Continue = fields.contains(HttpHeader.EXPECT, HttpHeaderValue.CONTINUE.asString());
+
+ boolean connect = request instanceof MetaData.ConnectRequest;
+
+ if (!connect)
+ connection.setApplicationMode(true);
+
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("HTTP3 request #{}/{}, {} {} {}{}{}",
+ stream.getId(), Integer.toHexString(stream.getSession().hashCode()),
+ request.getMethod(), request.getURI(), request.getHttpVersion(),
+ System.lineSeparator(), fields);
+ }
+
+ return handler;
+ }
+ catch (BadMessageException x)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("onRequest() failure", x);
+ onBadMessage(x);
+ return null;
+ }
+ catch (Throwable x)
+ {
+ onBadMessage(new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, null, x));
+ return null;
+ }
+ }
+
+ private void onBadMessage(BadMessageException x)
+ {
+ // TODO
+ }
+
+ @Override
+ public Content readContent()
+ {
+ while (true)
+ {
+ Content content = this.content;
+ this.content = Content.next(content);
+ if (content != null)
+ return content;
+
+ Stream.Data data = stream.readData();
+ if (data == null)
+ return null;
+
+ this.content = newContent(data);
+ }
+ }
+
+ @Override
+ public void demandContent()
+ {
+ stream.demand();
+ }
+
+ public Runnable onDataAvailable()
+ {
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("HTTP3 request data available #{}/{}",
+ stream.getId(), Integer.toHexString(stream.getSession().hashCode()));
+ }
+
+ Stream.Data data = stream.readData();
+ if (data == null)
+ {
+ stream.demand();
+ return null;
+ }
+
+ content = newContent(data);
+ return httpChannel.onContentAvailable();
+ }
+
+ private Content.Abstract newContent(Stream.Data data)
+ {
+ return new Content.Abstract(false, data.isLast())
+ {
+ @Override
+ public ByteBuffer getByteBuffer()
+ {
+ return data.getByteBuffer();
+ }
+
+ @Override
+ public void release()
+ {
+ data.complete();
+ }
+ };
+ }
+
+ public Runnable onTrailer(HeadersFrame frame)
+ {
+ HttpFields trailers = frame.getMetaData().getFields().asImmutable();
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("HTTP3 Request #{}/{}, trailer:{}{}",
+ stream.getId(), Integer.toHexString(stream.getSession().hashCode()),
+ System.lineSeparator(), trailers);
+ }
+ content = new Content.Trailers(trailers);
+ return httpChannel.onContentAvailable();
+ }
+
+ @Override
+ public void prepareResponse(HttpFields.Mutable headers)
+ {
+ // Nothing to do here.
+ }
+
+ @Override
+ public void send(MetaData.Request request, MetaData.Response response, boolean last, Callback callback, ByteBuffer... buffers)
+ {
+ if (buffers.length > 1)
+ throw new IllegalStateException();
+
+ ByteBuffer content = buffers.length == 0 ? BufferUtil.EMPTY_BUFFER : buffers[0];
+ if (response != null)
+ sendHeaders(request, response, content, last, callback);
+ else
+ sendContent(request, content, last, callback);
+ }
+
+ private void sendHeaders(MetaData.Request request, MetaData.Response response, ByteBuffer content, boolean lastContent, Callback callback)
+ {
+ metaData = response;
+
+ HeadersFrame headersFrame;
+ DataFrame dataFrame = null;
+ HeadersFrame trailersFrame = null;
+
+ boolean isHeadRequest = HttpMethod.HEAD.is(request.getMethod());
+ boolean hasContent = BufferUtil.hasContent(content) && !isHeadRequest;
+ int status = response.getStatus();
+ boolean interimResponse = status == HttpStatus.CONTINUE_100 || status == HttpStatus.PROCESSING_102;
+ if (interimResponse)
+ {
+ // Must not commit interim responses.
+ if (hasContent)
+ {
+ callback.failed(new IllegalStateException("Interim response cannot have content"));
+ return;
+ }
+ headersFrame = new HeadersFrame(metaData, false);
+ }
+ else
+ {
+ committed = true;
+ if (lastContent)
+ {
+ long realContentLength = BufferUtil.length(content);
+ long contentLength = response.getContentLength();
+ if (contentLength < 0)
+ {
+ metaData = new MetaData.Response(
+ response.getHttpVersion(),
+ response.getStatus(),
+ response.getReason(),
+ response.getFields(),
+ realContentLength,
+ response.getTrailerSupplier()
+ );
+ }
+ else if (hasContent && contentLength != realContentLength)
+ {
+ callback.failed(new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, String.format("Incorrect Content-Length %d!=%d", contentLength, realContentLength)));
+ return;
+ }
+ }
+
+ if (hasContent)
+ {
+ headersFrame = new HeadersFrame(metaData, false);
+ if (lastContent)
+ {
+ HttpFields trailers = retrieveTrailers();
+ if (trailers == null)
+ {
+ dataFrame = new DataFrame(content, true);
+ }
+ else
+ {
+ dataFrame = new DataFrame(content, false);
+ trailersFrame = new HeadersFrame(new MetaData(HttpVersion.HTTP_3, trailers), true);
+ }
+ }
+ else
+ {
+ dataFrame = new DataFrame(content, false);
+ }
+ }
+ else
+ {
+ if (lastContent)
+ {
+ if (isTunnel(request, metaData))
+ {
+ headersFrame = new HeadersFrame(metaData, false);
+ }
+ else
+ {
+ HttpFields trailers = retrieveTrailers();
+ if (trailers == null)
+ {
+ headersFrame = new HeadersFrame(metaData, true);
+ }
+ else
+ {
+ headersFrame = new HeadersFrame(metaData, false);
+ trailersFrame = new HeadersFrame(new MetaData(HttpVersion.HTTP_3, trailers), true);
+ }
+ }
+ }
+ else
+ {
+ headersFrame = new HeadersFrame(metaData, false);
+ }
+ }
+ }
+
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("HTTP3 Response #{}/{}:{}{} {}{}{}",
+ stream.getId(), Integer.toHexString(stream.getSession().hashCode()),
+ System.lineSeparator(), HttpVersion.HTTP_3, metaData.getStatus(),
+ System.lineSeparator(), metaData.getFields());
+ }
+
+ CompletableFuture cf = stream.respond(headersFrame);
+
+ DataFrame df = dataFrame;
+ if (df != null)
+ cf = cf.thenCompose(s -> s.data(df));
+
+ HeadersFrame tf = trailersFrame;
+ if (tf != null)
+ cf = cf.thenCompose(s -> s.trailer(tf));
+
+ callback.completeWith(cf);
+ }
+
+ private void sendContent(MetaData.Request request, ByteBuffer content, boolean lastContent, Callback callback)
+ {
+ boolean isHeadRequest = HttpMethod.HEAD.is(request.getMethod());
+ boolean hasContent = BufferUtil.hasContent(content) && !isHeadRequest;
+ if (hasContent || (lastContent && !isTunnel(request, metaData)))
+ {
+ if (lastContent)
+ {
+ HttpFields trailers = retrieveTrailers();
+ if (trailers == null)
+ {
+ callback.completeWith(sendDataFrame(content, true, true));
+ }
+ else
+ {
+ if (hasContent)
+ {
+ callback.completeWith(sendDataFrame(content, lastContent, false)
+ .thenCompose(s -> sendTrailerFrame(trailers)));
+ }
+ else
+ {
+ callback.completeWith(sendTrailerFrame(trailers));
+ }
+ }
+ }
+ else
+ {
+ callback.completeWith(sendDataFrame(content, false, false));
+ }
+ }
+ else
+ {
+ callback.succeeded();
+ }
+ }
+
+ private HttpFields retrieveTrailers()
+ {
+ Supplier supplier = metaData.getTrailerSupplier();
+ if (supplier == null)
+ return null;
+ HttpFields trailers = supplier.get();
+ if (trailers == null)
+ return null;
+ return trailers.size() == 0 ? null : trailers;
+ }
+
+ private boolean isTunnel(MetaData.Request request, MetaData.Response response)
+ {
+ return MetaData.isTunnel(request.getMethod(), response.getStatus());
+ }
+
+ private CompletableFuture sendDataFrame(ByteBuffer content, boolean lastContent, boolean endStream)
+ {
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("HTTP3 Response #{}/{}: {} content bytes{}",
+ stream.getId(), Integer.toHexString(stream.getSession().hashCode()),
+ content.remaining(), lastContent ? " (last chunk)" : "");
+ }
+ DataFrame frame = new DataFrame(content, endStream);
+ return stream.data(frame);
+ }
+
+ private CompletableFuture sendTrailerFrame(HttpFields trailers)
+ {
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("HTTP3 Response #{}/{}: trailer{}{}",
+ stream.getId(), Integer.toHexString(stream.getSession().hashCode()),
+ System.lineSeparator(), trailers);
+ }
+
+ HeadersFrame frame = new HeadersFrame(new MetaData(HttpVersion.HTTP_3, trailers), true);
+ return stream.trailer(frame);
+ }
+
+ @Override
+ public boolean isPushSupported()
+ {
+ return false;
+ }
+
+ @Override
+ public void push(MetaData.Request request)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isCommitted()
+ {
+ return committed;
+ }
+
+ @Override
+ public boolean isComplete()
+ {
+ // TODO
+ return false;
+ }
+
+ public boolean isIdle()
+ {
+ // TODO: is this necessary?
+ return true;
+ }
+
+ @Override
+ public void setUpgradeConnection(Connection connection)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Connection upgrade()
+ {
+ return null;
+ }
+
+ @Override
+ public void succeeded()
+ {
+ httpChannel.recycle();
+
+ // If the stream is not closed, it is still reading the request content.
+ // Send a reset to the other end so that it stops sending data.
+ if (!stream.isClosed())
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("HTTP3 Response #{}/{}: unconsumed request content, resetting stream", stream.getId(), Integer.toHexString(stream.getSession().hashCode()));
+ stream.reset(HTTP3ErrorCode.REQUEST_CANCELLED_ERROR.code(), new IOException("unconsumed content"));
+ }
+ }
+
+ @Override
+ public void failed(Throwable x)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("HTTP3 Response #{}/{} aborted", stream.getId(), Integer.toHexString(stream.getSession().hashCode()));
+ stream.reset(HTTP3ErrorCode.REQUEST_CANCELLED_ERROR.code(), x);
+ }
+
+ public boolean onIdleTimeout(Throwable failure, Consumer consumer)
+ {
+ Runnable runnable = httpChannel.onFailure(failure);
+ if (runnable != null)
+ consumer.accept(runnable);
+ return !httpChannel.isRequestHandled();
+ }
+
+ public Runnable onFailure(Throwable failure)
+ {
+ return httpChannel.onFailure(failure);
+ }
+}
diff --git a/jetty-core/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/ServerHTTP3StreamConnection.java b/jetty-core/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/ServerHTTP3StreamConnection.java
index 51f1403a2aa..1bac9916b2f 100644
--- a/jetty-core/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/ServerHTTP3StreamConnection.java
+++ b/jetty-core/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/ServerHTTP3StreamConnection.java
@@ -13,18 +13,29 @@
package org.eclipse.jetty.http3.server.internal;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.Set;
import java.util.function.Consumer;
+import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http3.frames.HeadersFrame;
import org.eclipse.jetty.http3.internal.HTTP3Stream;
import org.eclipse.jetty.http3.internal.HTTP3StreamConnection;
import org.eclipse.jetty.http3.internal.parser.MessageParser;
+import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.quic.common.QuicStreamEndPoint;
+import org.eclipse.jetty.server.ConnectionMetaData;
import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.util.Attributes;
+import org.eclipse.jetty.util.HostPort;
-public class ServerHTTP3StreamConnection extends HTTP3StreamConnection
+public class ServerHTTP3StreamConnection extends HTTP3StreamConnection implements ConnectionMetaData
{
+ private final HttpChannel.Factory httpChannelFactory = new HttpChannel.DefaultFactory();
+ private final Attributes attributes = new Attributes.Lazy();
private final Connector connector;
private final HttpConfiguration httpConfiguration;
private final ServerHTTP3Session session;
@@ -45,33 +56,138 @@ public class ServerHTTP3StreamConnection extends HTTP3StreamConnection
public Runnable onRequest(HTTP3StreamServer stream, HeadersFrame frame)
{
- HttpTransportOverHTTP3 transport = new HttpTransportOverHTTP3(stream);
- HttpChannelOverHTTP3 channel = new HttpChannelOverHTTP3(connector, httpConfiguration, getEndPoint(), transport, stream, this);
- stream.setAttachment(channel);
- return channel.onRequest(frame);
+ HttpChannel httpChannel = httpChannelFactory.newHttpChannel(this);
+ HttpStreamOverHTTP3 httpStream = new HttpStreamOverHTTP3(this, httpChannel, stream);
+ httpChannel.setHttpStream(httpStream);
+ stream.setAttachment(httpStream);
+ return httpStream.onRequest(frame);
}
public Runnable onDataAvailable(HTTP3Stream stream)
{
- HttpChannelOverHTTP3 channel = (HttpChannelOverHTTP3)stream.getAttachment();
- return channel.onDataAvailable();
+ HttpStreamOverHTTP3 httpStream = (HttpStreamOverHTTP3)stream.getAttachment();
+ return httpStream.onDataAvailable();
}
public Runnable onTrailer(HTTP3Stream stream, HeadersFrame frame)
{
- HttpChannelOverHTTP3 channel = (HttpChannelOverHTTP3)stream.getAttachment();
- return channel.onTrailer(frame);
+ HttpStreamOverHTTP3 httpStream = (HttpStreamOverHTTP3)stream.getAttachment();
+ return httpStream.onTrailer(frame);
}
public boolean onIdleTimeout(HTTP3Stream stream, Throwable failure, Consumer consumer)
{
- HttpChannelOverHTTP3 channel = (HttpChannelOverHTTP3)stream.getAttachment();
- return channel.onIdleTimeout(failure, consumer);
+ HttpStreamOverHTTP3 httpStream = (HttpStreamOverHTTP3)stream.getAttachment();
+ return httpStream.onIdleTimeout(failure, consumer);
}
public Runnable onFailure(HTTP3Stream stream, Throwable failure)
{
- HttpChannelOverHTTP3 channel = (HttpChannelOverHTTP3)stream.getAttachment();
- return channel.onFailure(failure);
+ HttpStreamOverHTTP3 httpStream = (HttpStreamOverHTTP3)stream.getAttachment();
+ return httpStream.onFailure(failure);
+ }
+
+ @Override
+ public String getId()
+ {
+ return session.getQuicSession().getConnectionId().toString();
+ }
+
+ @Override
+ public HttpConfiguration getHttpConfiguration()
+ {
+ return httpConfiguration;
+ }
+
+ @Override
+ public HttpVersion getHttpVersion()
+ {
+ return HttpVersion.HTTP_3;
+ }
+
+ @Override
+ public String getProtocol()
+ {
+ return getHttpVersion().asString();
+ }
+
+ @Override
+ public Connection getConnection()
+ {
+ return getEndPoint().getConnection();
+ }
+
+ @Override
+ public Connector getConnector()
+ {
+ return connector;
+ }
+
+ @Override
+ public boolean isPersistent()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean isSecure()
+ {
+ return true;
+ }
+
+ @Override
+ public SocketAddress getRemoteSocketAddress()
+ {
+ return getEndPoint().getRemoteSocketAddress();
+ }
+
+ @Override
+ public SocketAddress getLocalSocketAddress()
+ {
+ return getEndPoint().getLocalSocketAddress();
+ }
+
+ @Override
+ public HostPort getServerAuthority()
+ {
+ HostPort override = httpConfiguration.getServerAuthority();
+ if (override != null)
+ return override;
+
+ // TODO cache the HostPort?
+ SocketAddress addr = getLocalSocketAddress();
+ if (addr instanceof InetSocketAddress inet)
+ return new HostPort(inet.getHostString(), inet.getPort());
+ return new HostPort(addr.toString(), -1);
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ return attributes.getAttribute(name);
+ }
+
+ @Override
+ public Object setAttribute(String name, Object attribute)
+ {
+ return attributes.setAttribute(name, attribute);
+ }
+
+ @Override
+ public Object removeAttribute(String name)
+ {
+ return attributes.removeAttribute(name);
+ }
+
+ @Override
+ public Set getAttributeNameSet()
+ {
+ return attributes.getAttributeNameSet();
+ }
+
+ @Override
+ public void clearAttributes()
+ {
+ attributes.clearAttributes();
}
}
diff --git a/jetty-core/jetty-http3/http3-tests/pom.xml b/jetty-core/jetty-http3/http3-tests/pom.xml
index 7acdd1b359d..4e03c332b54 100644
--- a/jetty-core/jetty-http3/http3-tests/pom.xml
+++ b/jetty-core/jetty-http3/http3-tests/pom.xml
@@ -2,13 +2,13 @@
org.eclipse.jetty.http3
- http3-parent
- 11.0.10-SNAPSHOT
+ http3
+ 12.0.0-SNAPSHOT4.0.0http3-tests
- Jetty :: HTTP3 :: Tests
+ Jetty Core :: HTTP3 :: Tests
diff --git a/jetty-core/jetty-http3/http3-tests/src/test/java/org/eclipse/jetty/http3/tests/ClientServerTest.java b/jetty-core/jetty-http3/http3-tests/src/test/java/org/eclipse/jetty/http3/tests/ClientServerTest.java
index e6a9b7bf687..b94f10ec627 100644
--- a/jetty-core/jetty-http3/http3-tests/src/test/java/org/eclipse/jetty/http3/tests/ClientServerTest.java
+++ b/jetty-core/jetty-http3/http3-tests/src/test/java/org/eclipse/jetty/http3/tests/ClientServerTest.java
@@ -42,11 +42,13 @@ 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.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
+// TODO check that the Awaitility usage is the right thing to do.
public class ClientServerTest extends AbstractClientServerTest
{
@Test
@@ -184,8 +186,8 @@ public class ClientServerTest extends AbstractClientServerTest
assertTrue(clientResponseLatch.await(5, TimeUnit.SECONDS));
HTTP3Session serverSession = serverSessionRef.get();
- assertTrue(serverSession.getStreams().isEmpty());
- assertTrue(clientSession.getStreams().isEmpty());
+ await().atMost(5, TimeUnit.SECONDS).until(() -> serverSession.getStreams().isEmpty()); // onRequest is called *before* the serverSession's streams collection is cleaned up -> racy
+ await().atMost(5, TimeUnit.SECONDS).until(() -> clientSession.getStreams().isEmpty()); // onResponse is called *before* the clientSession's streams collection is cleaned up -> racy
QuicSession serverQuicSession = serverSession.getProtocolSession().getQuicSession();
assertTrue(serverQuicSession.getQuicStreamEndPoints().stream()
@@ -458,7 +460,7 @@ public class ClientServerTest extends AbstractClientServerTest
assertTrue(responseFailureLatch.await(5, TimeUnit.SECONDS));
assertTrue(streamFailureLatch.await(5, TimeUnit.SECONDS));
assertTrue(serverSessionRef.get().getStreams().isEmpty());
- assertTrue(clientSession.getStreams().isEmpty());
+ await().atMost(5, TimeUnit.SECONDS).until(() -> clientSession.getStreams().isEmpty()); // onFailure is called *before* the clientSession's streams collection is cleaned up -> racy
// Verify that the connection is still good.
CountDownLatch responseLatch = new CountDownLatch(1);
diff --git a/jetty-core/jetty-http3/http3-tests/src/test/java/org/eclipse/jetty/http3/tests/DataDemandTest.java b/jetty-core/jetty-http3/http3-tests/src/test/java/org/eclipse/jetty/http3/tests/DataDemandTest.java
index afc2de9b067..749a7bd4fa1 100644
--- a/jetty-core/jetty-http3/http3-tests/src/test/java/org/eclipse/jetty/http3/tests/DataDemandTest.java
+++ b/jetty-core/jetty-http3/http3-tests/src/test/java/org/eclipse/jetty/http3/tests/DataDemandTest.java
@@ -32,8 +32,6 @@ import org.eclipse.jetty.http3.api.Stream;
import org.eclipse.jetty.http3.frames.DataFrame;
import org.eclipse.jetty.http3.frames.HeadersFrame;
import org.eclipse.jetty.http3.internal.HTTP3Stream;
-import org.eclipse.jetty.http3.internal.HTTP3StreamConnection;
-import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.util.BufferUtil;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
@@ -42,7 +40,6 @@ import static org.awaitility.Awaitility.await;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -587,58 +584,4 @@ public class DataDemandTest extends AbstractClientServerTest
assertTrue(lastDataLatch.await(5, TimeUnit.SECONDS));
}
-
- @Test
- public void testOnDataAvailableThenNoReadThenIdleTimeoutReleasesNetworkBuffer() throws Exception
- {
- long idleTimeout = 1000;
- CountDownLatch onDataLatch = new CountDownLatch(1);
- CountDownLatch idleLatch = new CountDownLatch(1);
- CountDownLatch closeLatch = new CountDownLatch(1);
- start(new Session.Server.Listener()
- {
- @Override
- public Stream.Server.Listener onRequest(Stream.Server stream, HeadersFrame frame)
- {
- HTTP3Stream http3Stream = (HTTP3Stream)stream;
- http3Stream.setIdleTimeout(idleTimeout);
- http3Stream.getEndPoint().getConnection().addEventListener(new Connection.Listener.Adapter()
- {
- @Override
- public void onClosed(Connection connection)
- {
- assertFalse(((HTTP3StreamConnection)connection).hasBuffer());
- closeLatch.countDown();
- }
- });
- stream.demand();
- return new Stream.Server.Listener()
- {
- @Override
- public void onDataAvailable(Stream.Server stream)
- {
- // Do not read.
- onDataLatch.countDown();
- }
-
- @Override
- public boolean onIdleTimeout(Stream.Server stream, Throwable failure)
- {
- idleLatch.countDown();
- return true;
- }
- };
- }
- });
-
- Session.Client session = newSession(new Session.Client.Listener() {});
-
- HeadersFrame request = new HeadersFrame(newRequest("/"), false);
- Stream stream = session.newRequest(request, new Stream.Client.Listener() {}).get(5, TimeUnit.SECONDS);
- stream.data(new DataFrame(ByteBuffer.allocate(16 * 1024), true));
-
- assertTrue(onDataLatch.await(5, TimeUnit.SECONDS));
- assertTrue(idleLatch.await(2 * idleTimeout, TimeUnit.MILLISECONDS));
- assertTrue(closeLatch.await(5, TimeUnit.SECONDS));
- }
}
diff --git a/jetty-core/jetty-http3/http3-tests/src/test/java/org/eclipse/jetty/http3/tests/HandlerClientServerTest.java b/jetty-core/jetty-http3/http3-tests/src/test/java/org/eclipse/jetty/http3/tests/HandlerClientServerTest.java
index c024ce23386..96f686f4771 100644
--- a/jetty-core/jetty-http3/http3-tests/src/test/java/org/eclipse/jetty/http3/tests/HandlerClientServerTest.java
+++ b/jetty-core/jetty-http3/http3-tests/src/test/java/org/eclipse/jetty/http3/tests/HandlerClientServerTest.java
@@ -13,7 +13,6 @@
package org.eclipse.jetty.http3.tests;
-import java.io.IOException;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@@ -22,8 +21,6 @@ import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.MetaData;
@@ -31,9 +28,11 @@ import org.eclipse.jetty.http3.api.Session;
import org.eclipse.jetty.http3.api.Stream;
import org.eclipse.jetty.http3.frames.DataFrame;
import org.eclipse.jetty.http3.frames.HeadersFrame;
+import org.eclipse.jetty.server.Content;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@@ -48,13 +47,13 @@ public class HandlerClientServerTest extends AbstractClientServerTest
public void testGet() throws Exception
{
CountDownLatch serverLatch = new CountDownLatch(1);
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, Response response, Callback callback)
{
- jettyRequest.setHandled(true);
serverLatch.countDown();
+ callback.succeeded();
}
});
@@ -83,13 +82,12 @@ public class HandlerClientServerTest extends AbstractClientServerTest
public void testPost() throws Exception
{
CountDownLatch serverLatch = new CountDownLatch(1);
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
- jettyRequest.setHandled(true);
- IO.copy(request.getInputStream(), response.getOutputStream());
+ Content.copy(request, response, callback);
serverLatch.countDown();
}
});
diff --git a/jetty-core/jetty-http3/http3-tests/src/test/java/org/eclipse/jetty/http3/tests/HttpClientTransportOverHTTP3Test.java b/jetty-core/jetty-http3/http3-tests/src/test/java/org/eclipse/jetty/http3/tests/HttpClientTransportOverHTTP3Test.java
index f81b9090d1b..8ae1382c744 100644
--- a/jetty-core/jetty-http3/http3-tests/src/test/java/org/eclipse/jetty/http3/tests/HttpClientTransportOverHTTP3Test.java
+++ b/jetty-core/jetty-http3/http3-tests/src/test/java/org/eclipse/jetty/http3/tests/HttpClientTransportOverHTTP3Test.java
@@ -13,7 +13,6 @@
package org.eclipse.jetty.http3.tests;
-import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -21,14 +20,12 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.LongConsumer;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpVersion;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.Callback;
import org.junit.jupiter.api.Test;
@@ -41,14 +38,14 @@ public class HttpClientTransportOverHTTP3Test extends AbstractClientServerTest
@Test
public void testRequestHasHTTP3Version() throws Exception
{
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- jettyRequest.setHandled(true);
- HttpVersion version = HttpVersion.fromString(request.getProtocol());
+ HttpVersion version = HttpVersion.fromString(request.getConnectionMetaData().getProtocol());
response.setStatus(version == HttpVersion.HTTP_3 ? HttpStatus.OK_200 : HttpStatus.INTERNAL_SERVER_ERROR_500);
+ callback.succeeded();
}
});
@@ -68,13 +65,12 @@ public class HttpClientTransportOverHTTP3Test extends AbstractClientServerTest
public void testRequestResponseWithSmallContent() throws Exception
{
String content = "Hello, World!";
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- jettyRequest.setHandled(true);
- response.getOutputStream().print(content);
+ response.write(true, callback, content);
}
});
@@ -87,13 +83,12 @@ public class HttpClientTransportOverHTTP3Test extends AbstractClientServerTest
@Test
public void testDelayedClientRead() throws Exception
{
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- jettyRequest.setHandled(true);
- response.getOutputStream().write(new byte[10 * 1024]);
+ response.write(true, callback, ByteBuffer.wrap(new byte[10 * 1024]));
}
});
@@ -143,12 +138,12 @@ public class HttpClientTransportOverHTTP3Test extends AbstractClientServerTest
@Test
public void testDelayDemandAfterHeaders() throws Exception
{
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
+ public void process(Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- jettyRequest.setHandled(true);
+ callback.succeeded();
}
});
@@ -196,13 +191,12 @@ public class HttpClientTransportOverHTTP3Test extends AbstractClientServerTest
@Test
public void testDelayDemandAfterLastContentChunk() throws Exception
{
- start(new AbstractHandler()
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, org.eclipse.jetty.server.Response response, Callback callback)
{
- jettyRequest.setHandled(true);
- response.getOutputStream().print("0");
+ response.write(true, callback, "0");
}
});
diff --git a/jetty-http3/http3-tests/src/test/resources/jetty-logging.properties b/jetty-core/jetty-http3/http3-tests/src/test/resources/jetty-logging.properties
similarity index 81%
rename from jetty-http3/http3-tests/src/test/resources/jetty-logging.properties
rename to jetty-core/jetty-http3/http3-tests/src/test/resources/jetty-logging.properties
index 468634e1068..552e858ed9b 100644
--- a/jetty-http3/http3-tests/src/test/resources/jetty-logging.properties
+++ b/jetty-core/jetty-http3/http3-tests/src/test/resources/jetty-logging.properties
@@ -1,4 +1,5 @@
#org.eclipse.jetty.LEVEL=DEBUG
+org.eclipse.jetty.jmx.LEVEL=INFO
#org.eclipse.jetty.http3.LEVEL=DEBUG
#org.eclipse.jetty.quic.LEVEL=DEBUG
org.eclipse.jetty.quic.quiche.LEVEL=INFO
diff --git a/jetty-core/jetty-http3/pom.xml b/jetty-core/jetty-http3/pom.xml
index 3810a8fe33b..d597603973d 100644
--- a/jetty-core/jetty-http3/pom.xml
+++ b/jetty-core/jetty-http3/pom.xml
@@ -1,16 +1,16 @@
- jetty-projectorg.eclipse.jetty
- 11.0.10-SNAPSHOT
+ jetty-core
+ 12.0.0-SNAPSHOT4.0.0org.eclipse.jetty.http3
- http3-parent
+ http3pom
- Jetty :: HTTP3
+ Jetty Core :: HTTP3http3-qpack
diff --git a/jetty-core/jetty-io/pom.xml b/jetty-core/jetty-io/pom.xml
index efc9c928d40..9b5b2c88f9f 100644
--- a/jetty-core/jetty-io/pom.xml
+++ b/jetty-core/jetty-io/pom.xml
@@ -1,13 +1,13 @@
- jetty-projectorg.eclipse.jetty
- 11.0.10-SNAPSHOT
+ jetty-core
+ 12.0.0-SNAPSHOT4.0.0jetty-io
- Jetty :: IO Utility
+ Jetty Core :: IO Utility${project.groupId}.ioorg.eclipse.jetty.io.*
diff --git a/jetty-io/src/main/java/module-info.java b/jetty-core/jetty-io/src/main/java/module-info.java
similarity index 100%
rename from jetty-io/src/main/java/module-info.java
rename to jetty-core/jetty-io/src/main/java/module-info.java
diff --git a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java
index f7a48e35971..35d4b16077c 100644
--- a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java
+++ b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java
@@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory;
* will schedule a callback to {@link #onFillable()} or {@link #onFillInterestedFailed(Throwable)}
* as appropriate.
*/
-public abstract class AbstractConnection implements Connection
+public abstract class AbstractConnection implements Connection, Invocable
{
private static final Logger LOG = LoggerFactory.getLogger(AbstractConnection.class);
@@ -52,6 +52,15 @@ public abstract class AbstractConnection implements Connection
_readCallback = new ReadCallback();
}
+ @Deprecated
+ @Override
+ public InvocationType getInvocationType()
+ {
+ // TODO consider removing the #fillInterested method from the connection and only use #fillInterestedCallback
+ // so a connection need not be Invocable
+ return Invocable.super.getInvocationType();
+ }
+
@Override
public void addEventListener(EventListener listener)
{
@@ -60,9 +69,10 @@ public abstract class AbstractConnection implements Connection
}
@Override
- public void removeEventListener(EventListener listener)
+ public void removeEventListener(EventListener eventListener)
{
- _listeners.remove(listener);
+ if (eventListener instanceof Listener listener)
+ _listeners.remove(listener);
}
public int getInputBufferSize()
@@ -301,17 +311,15 @@ public abstract class AbstractConnection implements Connection
@Override
public final String toString()
{
- return String.format("%s@%h::%s", getClass().getSimpleName(), this, getEndPoint());
+ return String.format("%s@%x::%s", getClass().getSimpleName(), hashCode(), getEndPoint());
}
public String toConnectionString()
{
- return String.format("%s@%h",
- getClass().getSimpleName(),
- this);
+ return String.format("%s@%x", getClass().getSimpleName(), hashCode());
}
- private class ReadCallback implements Callback
+ private class ReadCallback implements Callback, Invocable
{
@Override
public void succeeded()
@@ -330,5 +338,11 @@ public abstract class AbstractConnection implements Connection
{
return String.format("AC.ReadCB@%h{%s}", AbstractConnection.this, AbstractConnection.this);
}
+
+ @Override
+ public InvocationType getInvocationType()
+ {
+ return AbstractConnection.this.getInvocationType();
+ }
}
}
diff --git a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java
index 0323973b5b4..e9d60b85bd6 100644
--- a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java
+++ b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java
@@ -419,10 +419,15 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint
// for a dispatched servlet or suspended request to extend beyond the connections idle
// time. So if this test would always close an idle endpoint that is not handled, then
// we would need a mode to ignore timeouts for some HTTP states
- if (isOpen() && (outputShutdown || inputShutdown) && !(fillFailed || writeFailed))
+ if (isOpen() && (inputShutdown || outputShutdown) && !(fillFailed || writeFailed))
close();
else
- LOG.debug("Ignored idle endpoint {}", this);
+ LOG.debug("handled idle inputShutdown={} outputShutdown={} fillFailed={} writeFailed={} for {}",
+ inputShutdown,
+ outputShutdown,
+ fillFailed,
+ writeFailed,
+ this);
}
@Override
diff --git a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPool.java b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPool.java
index 3fe42c147ee..e1c6051c0e1 100644
--- a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPool.java
+++ b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPool.java
@@ -386,4 +386,34 @@ public class ArrayRetainableByteBufferPool implements RetainableByteBufferPool,
entries > 0 ? (inUse * 100) / entries : 0);
}
}
+
+ /**
+ * A variant of the {@link ArrayRetainableByteBufferPool} that
+ * uses buckets of buffers that increase in size by a power of
+ * 2 (eg 1k, 2k, 4k, 8k, etc.).
+ */
+ public static class ExponentialPool extends ArrayRetainableByteBufferPool
+ {
+ public ExponentialPool()
+ {
+ this(0, -1, Integer.MAX_VALUE);
+ }
+
+ public ExponentialPool(int minCapacity, int maxCapacity, int maxBucketSize)
+ {
+ this(minCapacity, maxCapacity, maxBucketSize, -1L, -1L);
+ }
+
+ public ExponentialPool(int minCapacity, int maxCapacity, int maxBucketSize, long maxHeapMemory, long maxDirectMemory)
+ {
+ super(minCapacity,
+ -1,
+ maxCapacity,
+ maxBucketSize,
+ maxHeapMemory,
+ maxDirectMemory,
+ c -> 32 - Integer.numberOfLeadingZeros(c - 1),
+ i -> 1 << i);
+ }
+ }
}
diff --git a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java
index e5ec873b162..d40f8692b53 100644
--- a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java
+++ b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java
@@ -34,20 +34,20 @@ public interface Connection extends Closeable
*
* @param listener the listener to add
*/
- public void addEventListener(EventListener listener);
+ void addEventListener(EventListener listener);
/**
*
Removes a listener of connection events.
*
* @param listener the listener to remove
*/
- public void removeEventListener(EventListener listener);
+ void removeEventListener(EventListener listener);
/**
*
Callback method invoked when this connection is opened.
*
Creators of the connection implementation are responsible for calling this method.
*/
- public void onOpen();
+ void onOpen();
/**
*
Callback method invoked when this connection is closed.
@@ -55,12 +55,12 @@ public interface Connection extends Closeable
*
* @param cause The cause of the close or null for a normal close
*/
- public void onClose(Throwable cause);
+ void onClose(Throwable cause);
/**
* @return the {@link EndPoint} associated with this Connection.
*/
- public EndPoint getEndPoint();
+ EndPoint getEndPoint();
/**
*
Performs a logical close of this connection.
@@ -69,7 +69,7 @@ public interface Connection extends Closeable
* before closing the associated {@link EndPoint}.
*/
@Override
- public void close();
+ void close();
/**
*
Callback method invoked upon an idle timeout event.
@@ -82,17 +82,17 @@ public interface Connection extends Closeable
* @return true to let the EndPoint handle the idle timeout,
* false to tell the EndPoint to halt the handling of the idle timeout.
*/
- public boolean onIdleExpired();
+ boolean onIdleExpired();
- public long getMessagesIn();
+ long getMessagesIn();
- public long getMessagesOut();
+ long getMessagesOut();
- public long getBytesIn();
+ long getBytesIn();
- public long getBytesOut();
+ long getBytesOut();
- public long getCreatedTimeStamp();
+ long getCreatedTimeStamp();
/**
*
{@link Connection} implementations implement this interface when they
@@ -102,7 +102,7 @@ public interface Connection extends Closeable
* @see EndPoint#upgrade(Connection)
* @see UpgradeTo
*/
- public interface UpgradeFrom
+ interface UpgradeFrom
{
/**
*
Invoked during an {@link EndPoint#upgrade(Connection) upgrade}
@@ -115,7 +115,7 @@ public interface Connection extends Closeable
* having consumed its bytes.
* The returned buffer may be null if there are no unconsumed bytes.
*/
- public ByteBuffer onUpgradeFrom();
+ ByteBuffer onUpgradeFrom();
}
/**
@@ -123,7 +123,7 @@ public interface Connection extends Closeable
* can be upgraded to the protocol they speak (e.g. HTTP/2)
* from a different protocol (e.g. HTTP/1.1).
Invoked during an {@link EndPoint#upgrade(Connection) upgrade}
@@ -136,7 +136,7 @@ public interface Connection extends Closeable
* The buffer does not belong to any pool and should be discarded after
* having consumed its bytes.
*/
- public void onUpgradeTo(ByteBuffer buffer);
+ void onUpgradeTo(ByteBuffer buffer);
}
/**
@@ -147,23 +147,14 @@ public interface Connection extends Closeable
* the Connector or ConnectionFactory are added as listeners to all new connections
*
*/
- public interface Listener extends EventListener
+ interface Listener extends EventListener
{
- public void onOpened(Connection connection);
-
- public void onClosed(Connection connection);
-
- public static class Adapter implements Listener
+ default void onOpened(Connection connection)
{
- @Override
- public void onOpened(Connection connection)
- {
- }
+ }
- @Override
- public void onClosed(Connection connection)
- {
- }
+ default void onClosed(Connection connection)
+ {
}
}
}
diff --git a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java
index 028e95241f9..3617060dc3d 100644
--- a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java
+++ b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java
@@ -89,10 +89,10 @@ import org.eclipse.jetty.util.thread.Invocable;
*/
public interface EndPoint extends Closeable
{
- /**
+ /**
* Marks an {@code EndPoint} that wraps another {@code EndPoint}.
*/
- public interface Wrapper
+ public interface Wrapper
{
/**
* @return The wrapped {@code EndPoint}
diff --git a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/IdleTimeout.java b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/IdleTimeout.java
index f1ac8e77886..ea86c19a2cd 100644
--- a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/IdleTimeout.java
+++ b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/IdleTimeout.java
@@ -159,11 +159,12 @@ public abstract class IdleTimeout
{
if (idleLeft <= 0)
{
+ TimeoutException timeout = new TimeoutException("Idle timeout expired: " + idleElapsed + "/" + idleTimeout + " ms");
if (LOG.isDebugEnabled())
- LOG.debug("{} idle timeout expired", this);
+ LOG.debug("{} idle timeout expired", this, timeout);
try
{
- onIdleExpired(new TimeoutException("Idle timeout expired: " + idleElapsed + "/" + idleTimeout + " ms"));
+ onIdleExpired(timeout);
}
finally
{
diff --git a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/LogarithmicArrayByteBufferPool.java b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/LogarithmicArrayByteBufferPool.java
index d01e10cc809..9842e91fd9e 100644
--- a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/LogarithmicArrayByteBufferPool.java
+++ b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/LogarithmicArrayByteBufferPool.java
@@ -21,6 +21,8 @@ package org.eclipse.jetty.io;
*/
public class LogarithmicArrayByteBufferPool extends ArrayByteBufferPool
{
+ // TODO test this class and use it!
+
/**
* Creates a new ByteBufferPool with a default configuration.
*/
diff --git a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/MappedByteBufferPool.java b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/MappedByteBufferPool.java
index 9d3bebfa117..223093acec6 100644
--- a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/MappedByteBufferPool.java
+++ b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/MappedByteBufferPool.java
@@ -40,6 +40,8 @@ import org.slf4j.LoggerFactory;
@ManagedObject
public class MappedByteBufferPool extends AbstractByteBufferPool implements Dumpable
{
+ // TODO Logarithmic buffer sizes
+
private static final Logger LOG = LoggerFactory.getLogger(MappedByteBufferPool.class);
private final ConcurrentMap _directBuffers = new ConcurrentHashMap<>();
diff --git a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/QuietException.java b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/QuietException.java
index aa8a1adf884..9e496c5c607 100644
--- a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/QuietException.java
+++ b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/QuietException.java
@@ -20,4 +20,26 @@ package org.eclipse.jetty.io;
*/
public interface QuietException
{
+ class Exception extends java.lang.Exception implements QuietException
+ {
+ public Exception()
+ {
+ super();
+ }
+
+ public Exception(String message)
+ {
+ super(message);
+ }
+
+ public Exception(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+
+ public Exception(Throwable cause)
+ {
+ super(cause);
+ }
+ }
}
diff --git a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/SocketChannelEndPoint.java b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/SocketChannelEndPoint.java
index eb982bd34d5..ffc7f7bec17 100644
--- a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/SocketChannelEndPoint.java
+++ b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/SocketChannelEndPoint.java
@@ -51,7 +51,8 @@ public class SocketChannelEndPoint extends SelectableChannelEndPoint
}
catch (Throwable x)
{
- LOG.trace("Could not retrieve remote socket address", x);
+ if (LOG.isTraceEnabled())
+ LOG.trace("Could not retrieve remote socket address", x);
return null;
}
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/package-info.java b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/package-info.java
similarity index 100%
rename from jetty-io/src/main/java/org/eclipse/jetty/io/package-info.java
rename to jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/package-info.java
diff --git a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java
index aeb34eab9c2..923bee960cf 100644
--- a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java
+++ b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java
@@ -40,6 +40,7 @@ import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.io.WriteFlusher;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
+import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.thread.AutoLock;
import org.eclipse.jetty.util.thread.Invocable;
@@ -634,7 +635,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
{
Throwable failure = _failure;
if (failure != null)
- rethrow(failure);
+ throw IO.rethrow(failure);
if (_sslEngine.isInboundDone())
return filled = -1;
continue;
@@ -716,7 +717,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
case CLOSED:
Throwable failure = _failure;
if (failure != null)
- rethrow(failure);
+ throw IO.rethrow(failure);
return filled = -1;
case BUFFER_UNDERFLOW:
@@ -818,9 +819,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
catch (Throwable x)
{
close(x);
- rethrow(x);
- // Never reached.
- throw new AssertionError();
+ throw IO.rethrow(x);
}
}
@@ -1173,9 +1172,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
catch (Throwable x)
{
close(x);
- rethrow(x);
- // Never reached.
- throw new AssertionError();
+ throw IO.rethrow(x);
}
}
@@ -1509,17 +1506,6 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
}
}
- private void rethrow(Throwable x) throws IOException
- {
- if (x instanceof RuntimeException)
- throw (RuntimeException)x;
- if (x instanceof Error)
- throw (Error)x;
- if (x instanceof IOException)
- throw (IOException)x;
- throw new IOException(x);
- }
-
@Override
public String toString()
{
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/package-info.java b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/package-info.java
similarity index 100%
rename from jetty-io/src/main/java/org/eclipse/jetty/io/ssl/package-info.java
rename to jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/package-info.java
diff --git a/jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java b/jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java
index 816352a60d3..18470a6faee 100644
--- a/jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java
+++ b/jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java
@@ -321,7 +321,7 @@ public class ArrayRetainableByteBufferPoolTest
@Test
public void testExponentialPool() throws IOException
{
- ArrayRetainableByteBufferPool pool = new ExponentialPool();
+ ArrayRetainableByteBufferPool pool = new ArrayRetainableByteBufferPool.ExponentialPool();
assertThat(pool.acquire(1, false).capacity(), is(1));
assertThat(pool.acquire(2, false).capacity(), is(2));
RetainableByteBuffer b3 = pool.acquire(3, false);
diff --git a/jetty-core/jetty-jmx/pom.xml b/jetty-core/jetty-jmx/pom.xml
index ed023dfe038..2d12fb02714 100644
--- a/jetty-core/jetty-jmx/pom.xml
+++ b/jetty-core/jetty-jmx/pom.xml
@@ -1,12 +1,12 @@
org.eclipse.jetty
- jetty-project
- 11.0.10-SNAPSHOT
+ jetty-core
+ 12.0.0-SNAPSHOT4.0.0jetty-jmx
- Jetty :: JMX Management
+ Jetty Core :: JMX ManagementJMX management artifact for jetty.${project.groupId}.jmx
diff --git a/jetty-jmx/src/main/java/module-info.java b/jetty-core/jetty-jmx/src/main/java/module-info.java
similarity index 100%
rename from jetty-jmx/src/main/java/module-info.java
rename to jetty-core/jetty-jmx/src/main/java/module-info.java
diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/package-info.java b/jetty-core/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/package-info.java
similarity index 100%
rename from jetty-jmx/src/main/java/org/eclipse/jetty/jmx/package-info.java
rename to jetty-core/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/package-info.java
diff --git a/jetty-core/jetty-jndi/pom.xml b/jetty-core/jetty-jndi/pom.xml
index 65500dba2af..4c30a3fb1f2 100644
--- a/jetty-core/jetty-jndi/pom.xml
+++ b/jetty-core/jetty-jndi/pom.xml
@@ -1,13 +1,13 @@
org.eclipse.jetty
- jetty-project
- 11.0.10-SNAPSHOT
+ jetty-core
+ 12.0.0-SNAPSHOT4.0.0jetty-jndi
- Jetty :: JNDI Naming
+ Jetty Core :: JNDI NamingJNDI spi impl for java namespace.
@@ -54,20 +54,23 @@
jetty-serverprovided
-
- org.eclipse.jetty
- jetty-security
+
+
+
+
diff --git a/jetty-jndi/src/main/java/module-info.java b/jetty-core/jetty-jndi/src/main/java/module-info.java
similarity index 92%
rename from jetty-jndi/src/main/java/module-info.java
rename to jetty-core/jetty-jndi/src/main/java/module-info.java
index 00ef86a14c8..10fc8742b90 100644
--- a/jetty-jndi/src/main/java/module-info.java
+++ b/jetty-core/jetty-jndi/src/main/java/module-info.java
@@ -19,10 +19,10 @@ module org.eclipse.jetty.jndi
requires transitive org.eclipse.jetty.server;
// Only required if using MailSessionReference.
- requires static jakarta.mail;
+ // requires static jakarta.mail;
// Only required if using DataSourceCloser.
requires static java.sql;
- requires static org.eclipse.jetty.security;
+ // requires static org.eclipse.jetty.security;
exports org.eclipse.jetty.jndi;
exports org.eclipse.jetty.jndi.factories;
diff --git a/jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/MailSessionReference.java b/jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/MailSessionReference.java
index 295f3ff17dc..5d5ce4690d2 100644
--- a/jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/MailSessionReference.java
+++ b/jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/MailSessionReference.java
@@ -13,23 +13,13 @@
package org.eclipse.jetty.jndi.factories;
-import java.util.Enumeration;
import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Map;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.Name;
-import javax.naming.RefAddr;
import javax.naming.Reference;
-import javax.naming.StringRefAddr;
import javax.naming.spi.ObjectFactory;
-import jakarta.mail.Authenticator;
-import jakarta.mail.PasswordAuthentication;
-import jakarta.mail.Session;
-import org.eclipse.jetty.util.security.Password;
-
/**
* MailSessionReference
*
@@ -43,8 +33,8 @@ import org.eclipse.jetty.util.security.Password;
*/
public class MailSessionReference extends Reference implements ObjectFactory
{
-
- public static class PasswordAuthenticator extends Authenticator
+ // FIXME: Move to appropriate EE9 tree
+ /*public static class PasswordAuthenticator extends Authenticator
{
PasswordAuthentication passwordAuthentication;
private String user;
@@ -87,13 +77,14 @@ public class MailSessionReference extends Reference implements ObjectFactory
}
}
- ;
+ */
public MailSessionReference()
{
super("javax.jakarta.Session", MailSessionReference.class.getName(), null);
}
+
/**
* Create a javax.mail.Session instance based on the information passed in the Reference
*
@@ -108,7 +99,8 @@ public class MailSessionReference extends Reference implements ObjectFactory
@Override
public Object getObjectInstance(Object ref, Name arg1, Context arg2, Hashtable arg3) throws Exception
{
- if (ref == null)
+ return null;
+ /*if (ref == null)
return null;
Reference reference = (Reference)ref;
@@ -134,29 +126,34 @@ public class MailSessionReference extends Reference implements ObjectFactory
if (password == null)
return Session.getInstance(props);
else
- return Session.getInstance(props, new PasswordAuthenticator(user, password));
+ return Session.getInstance(props, new PasswordAuthenticator(user, password));*/
}
public void setUser(String user)
{
+ /*
StringRefAddr addr = (StringRefAddr)get("user");
if (addr != null)
{
throw new RuntimeException("user already set on SessionReference, can't be changed");
}
add(new StringRefAddr("user", user));
+ */
}
public void setPassword(String password)
{
+ /*
StringRefAddr addr = (StringRefAddr)get("pwd");
if (addr != null)
throw new RuntimeException("password already set on SessionReference, can't be changed");
add(new StringRefAddr("pwd", password));
+ */
}
public void setProperties(Properties properties)
{
+ /*
Iterator entries = properties.entrySet().iterator();
while (entries.hasNext())
{
@@ -166,5 +163,6 @@ public class MailSessionReference extends Reference implements ObjectFactory
throw new RuntimeException("property " + e.getKey() + " already set on Session reference, can't be changed");
add(new StringRefAddr((String)e.getKey(), (String)e.getValue()));
}
+ */
}
}
diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/package-info.java b/jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/package-info.java
similarity index 100%
rename from jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/package-info.java
rename to jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/package-info.java
diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/package-info.java b/jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/package-info.java
similarity index 100%
rename from jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/package-info.java
rename to jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/package-info.java
diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/local/package-info.java b/jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/local/package-info.java
similarity index 100%
rename from jetty-jndi/src/main/java/org/eclipse/jetty/jndi/local/package-info.java
rename to jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/local/package-info.java
diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/package-info.java b/jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/package-info.java
similarity index 100%
rename from jetty-jndi/src/main/java/org/eclipse/jetty/jndi/package-info.java
rename to jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/package-info.java
diff --git a/jetty-core/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestJNDI.java b/jetty-core/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestJNDI.java
index e2361ec7751..25a81510dd4 100644
--- a/jetty-core/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestJNDI.java
+++ b/jetty-core/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestJNDI.java
@@ -30,13 +30,9 @@ import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.naming.spi.ObjectFactory;
-import jakarta.servlet.ServletContextEvent;
-import jakarta.servlet.ServletContextListener;
import org.eclipse.jetty.jndi.NamingContext;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.ContextHandler;
-import org.eclipse.jetty.server.handler.HandlerList;
import org.hamcrest.Matchers;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -71,130 +67,132 @@ public class TestJNDI
}
}
+ @Disabled("port to ee9")
@Test
public void testThreadContextClassloaderAndCurrentContext()
throws Exception
{
-
- //create a jetty context, and start it so that its classloader it created
- //and it is the current context
- ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();
- ContextHandler ch = new ContextHandler();
- URLClassLoader chLoader = new URLClassLoader(new URL[0], currentLoader);
- ch.setClassLoader(chLoader);
- Server server = new Server();
- HandlerList hl = new HandlerList();
- server.setHandler(hl);
- hl.addHandler(ch);
-
- //Create another one
- ContextHandler ch2 = new ContextHandler();
- URLClassLoader ch2Loader = new URLClassLoader(new URL[0], currentLoader);
- ch2.setClassLoader(ch2Loader);
- hl.addHandler(ch2);
-
- try
- {
- ch.setContextPath("/ch");
- ch.addEventListener(new ServletContextListener()
- {
- private Context comp;
- private Object testObj = new Object();
-
- @Override
- public void contextInitialized(ServletContextEvent sce)
- {
- try
- {
- InitialContext initCtx = new InitialContext();
- Context java = (Context)initCtx.lookup("java:");
- assertNotNull(java);
- comp = (Context)initCtx.lookup("java:comp");
- assertNotNull(comp);
- Context env = ((Context)comp).createSubcontext("env");
- assertNotNull(env);
- env.bind("ch", testObj);
- }
- catch (Exception e)
- {
- throw new IllegalStateException(e);
- }
- }
-
- @Override
- public void contextDestroyed(ServletContextEvent sce)
- {
- try
- {
- assertNotNull(comp);
- assertEquals(testObj, comp.lookup("env/ch"));
- comp.destroySubcontext("env");
- }
- catch (Exception e)
- {
- throw new IllegalStateException(e);
- }
- }
- });
- //Starting the context makes it current and creates a classloader for it
- ch.start();
-
- ch2.setContextPath("/ch2");
- ch2.addEventListener(new ServletContextListener()
- {
- private Context comp;
- private Object testObj = new Object();
-
- @Override
- public void contextInitialized(ServletContextEvent sce)
- {
- try
- {
- InitialContext initCtx = new InitialContext();
- comp = (Context)initCtx.lookup("java:comp");
- assertNotNull(comp);
-
- //another context's bindings should not be visible
- Context env = ((Context)comp).createSubcontext("env");
- try
- {
- env.lookup("ch");
- fail("java:comp/env visible from another context!");
- }
- catch (NameNotFoundException e)
- {
- //expected
- }
- }
- catch (Exception e)
- {
- throw new IllegalStateException(e);
- }
- }
-
- @Override
- public void contextDestroyed(ServletContextEvent sce)
- {
- try
- {
- assertNotNull(comp);
- comp.destroySubcontext("env");
- }
- catch (Exception e)
- {
- throw new IllegalStateException(e);
- }
- }
- });
- //make the new context the current one
- ch2.start();
- }
- finally
- {
- ch.stop();
- ch2.stop();
- Thread.currentThread().setContextClassLoader(currentLoader);
- }
+ fail();
+//
+// //create a jetty context, and start it so that its classloader it created
+// //and it is the current context
+// ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();
+// ContextHandler ch = new ContextHandler();
+// URLClassLoader chLoader = new URLClassLoader(new URL[0], currentLoader);
+// ch.setClassLoader(chLoader);
+// Server server = new Server();
+// HandlerList hl = new HandlerList();
+// server.setHandler(hl);
+// hl.addHandler(ch);
+//
+// //Create another one
+// ContextHandler ch2 = new ContextHandler();
+// URLClassLoader ch2Loader = new URLClassLoader(new URL[0], currentLoader);
+// ch2.setClassLoader(ch2Loader);
+// hl.addHandler(ch2);
+//
+// try
+// {
+// ch.setContextPath("/ch");
+// ch.addEventListener(new ServletContextListener()
+// {
+// private Context comp;
+// private Object testObj = new Object();
+//
+// @Override
+// public void contextInitialized(ServletContextEvent sce)
+// {
+// try
+// {
+// InitialContext initCtx = new InitialContext();
+// Context java = (Context)initCtx.lookup("java:");
+// assertNotNull(java);
+// comp = (Context)initCtx.lookup("java:comp");
+// assertNotNull(comp);
+// Context env = ((Context)comp).createSubcontext("env");
+// assertNotNull(env);
+// env.bind("ch", testObj);
+// }
+// catch (Exception e)
+// {
+// throw new IllegalStateException(e);
+// }
+// }
+//
+// @Override
+// public void contextDestroyed(ServletContextEvent sce)
+// {
+// try
+// {
+// assertNotNull(comp);
+// assertEquals(testObj, comp.lookup("env/ch"));
+// comp.destroySubcontext("env");
+// }
+// catch (Exception e)
+// {
+// throw new IllegalStateException(e);
+// }
+// }
+// });
+// //Starting the context makes it current and creates a classloader for it
+// ch.start();
+//
+// ch2.setContextPath("/ch2");
+// ch2.addEventListener(new ServletContextListener()
+// {
+// private Context comp;
+// private Object testObj = new Object();
+//
+// @Override
+// public void contextInitialized(ServletContextEvent sce)
+// {
+// try
+// {
+// InitialContext initCtx = new InitialContext();
+// comp = (Context)initCtx.lookup("java:comp");
+// assertNotNull(comp);
+//
+// //another context's bindings should not be visible
+// Context env = ((Context)comp).createSubcontext("env");
+// try
+// {
+// env.lookup("ch");
+// fail("java:comp/env visible from another context!");
+// }
+// catch (NameNotFoundException e)
+// {
+// //expected
+// }
+// }
+// catch (Exception e)
+// {
+// throw new IllegalStateException(e);
+// }
+// }
+//
+// @Override
+// public void contextDestroyed(ServletContextEvent sce)
+// {
+// try
+// {
+// assertNotNull(comp);
+// comp.destroySubcontext("env");
+// }
+// catch (Exception e)
+// {
+// throw new IllegalStateException(e);
+// }
+// }
+// });
+// //make the new context the current one
+// ch2.start();
+// }
+// finally
+// {
+// ch.stop();
+// ch2.stop();
+// Thread.currentThread().setContextClassLoader(currentLoader);
+// }
}
@Test
diff --git a/jetty-core/jetty-keystore/pom.xml b/jetty-core/jetty-keystore/pom.xml
index a9861920478..e79ea40ab93 100644
--- a/jetty-core/jetty-keystore/pom.xml
+++ b/jetty-core/jetty-keystore/pom.xml
@@ -2,13 +2,13 @@
org.eclipse.jetty
- jetty-project
- 11.0.10-SNAPSHOT
+ jetty-core
+ 12.0.0-SNAPSHOT4.0.0jetty-keystorejar
- Jetty :: Test Keystore
+ Jetty Core :: Test KeystoreTest keystore with self-signed SSL Certificate.
diff --git a/jetty-core/jetty-quic/pom.xml b/jetty-core/jetty-quic/pom.xml
index b82fec0e834..3420abe7083 100644
--- a/jetty-core/jetty-quic/pom.xml
+++ b/jetty-core/jetty-quic/pom.xml
@@ -1,16 +1,16 @@
- jetty-projectorg.eclipse.jetty
- 11.0.10-SNAPSHOT
+ jetty-core
+ 12.0.0-SNAPSHOT4.0.0org.eclipse.jetty.quic
- quic-parent
+ quicpom
- Jetty :: QUIC
+ Jetty Core :: QUICquic-quiche
diff --git a/jetty-core/jetty-quic/quic-client/pom.xml b/jetty-core/jetty-quic/quic-client/pom.xml
index 9bab3761ee6..bfb114e8633 100644
--- a/jetty-core/jetty-quic/quic-client/pom.xml
+++ b/jetty-core/jetty-quic/quic-client/pom.xml
@@ -2,13 +2,13 @@
org.eclipse.jetty.quic
- quic-parent
- 11.0.10-SNAPSHOT
+ quic
+ 12.0.0-SNAPSHOT4.0.0quic-client
- Jetty :: QUIC :: Client
+ Jetty Core :: QUIC :: Client${project.groupId}.client
diff --git a/jetty-quic/quic-client/src/main/java/module-info.java b/jetty-core/jetty-quic/quic-client/src/main/java/module-info.java
similarity index 100%
rename from jetty-quic/quic-client/src/main/java/module-info.java
rename to jetty-core/jetty-quic/quic-client/src/main/java/module-info.java
diff --git a/jetty-core/jetty-quic/quic-client/src/test/java/org/eclipse/jetty/quic/client/End2EndClientTest.java b/jetty-core/jetty-quic/quic-client/src/test/java/org/eclipse/jetty/quic/client/End2EndClientTest.java
index cd6d1fb0866..52c8ad2eff9 100644
--- a/jetty-core/jetty-quic/quic-client/src/test/java/org/eclipse/jetty/quic/client/End2EndClientTest.java
+++ b/jetty-core/jetty-quic/quic-client/src/test/java/org/eclipse/jetty/quic/client/End2EndClientTest.java
@@ -13,13 +13,9 @@
package org.eclipse.jetty.quic.client;
-import java.io.IOException;
-import java.io.PrintWriter;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic;
@@ -31,11 +27,13 @@ import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
import org.eclipse.jetty.io.ClientConnectionFactory;
import org.eclipse.jetty.io.ClientConnector;
import org.eclipse.jetty.quic.server.QuicServerConnector;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.jupiter.api.AfterEach;
@@ -50,12 +48,13 @@ public class End2EndClientTest
private Server server;
private QuicServerConnector connector;
private HttpClient client;
- private final String responseContent = "" +
- "\n" +
- "\t\n" +
- "\t\tRequest served\n" +
- "\t\n" +
- "";
+ private final String responseContent = """
+
+
+ Request served
+
+
+ """;
@BeforeEach
public void setUp() throws Exception
@@ -72,14 +71,12 @@ public class End2EndClientTest
connector = new QuicServerConnector(server, sslContextFactory, http1, http2);
server.addConnector(connector);
- server.setHandler(new AbstractHandler()
+ server.setHandler(new Handler.Processor()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
- baseRequest.setHandled(true);
- PrintWriter writer = response.getWriter();
- writer.print(responseContent);
+ response.write(true, callback, responseContent);
}
});
diff --git a/jetty-quic/quic-client/src/test/resources/jetty-logging.properties b/jetty-core/jetty-quic/quic-client/src/test/resources/jetty-logging.properties
similarity index 100%
rename from jetty-quic/quic-client/src/test/resources/jetty-logging.properties
rename to jetty-core/jetty-quic/quic-client/src/test/resources/jetty-logging.properties
diff --git a/jetty-quic/quic-client/src/test/resources/keystore.p12 b/jetty-core/jetty-quic/quic-client/src/test/resources/keystore.p12
similarity index 100%
rename from jetty-quic/quic-client/src/test/resources/keystore.p12
rename to jetty-core/jetty-quic/quic-client/src/test/resources/keystore.p12
diff --git a/jetty-core/jetty-quic/quic-common/pom.xml b/jetty-core/jetty-quic/quic-common/pom.xml
index a46fd39de65..8cbebc4aaa1 100644
--- a/jetty-core/jetty-quic/quic-common/pom.xml
+++ b/jetty-core/jetty-quic/quic-common/pom.xml
@@ -2,13 +2,13 @@
org.eclipse.jetty.quic
- quic-parent
- 11.0.10-SNAPSHOT
+ quic
+ 12.0.0-SNAPSHOT4.0.0quic-common
- Jetty :: QUIC :: Common
+ Jetty Core :: QUIC :: Common${project.groupId}.common
diff --git a/jetty-quic/quic-common/src/main/java/module-info.java b/jetty-core/jetty-quic/quic-common/src/main/java/module-info.java
similarity index 100%
rename from jetty-quic/quic-common/src/main/java/module-info.java
rename to jetty-core/jetty-quic/quic-common/src/main/java/module-info.java
diff --git a/jetty-quic/quic-common/src/main/java/org/eclipse/jetty/quic/common/package-info.java b/jetty-core/jetty-quic/quic-common/src/main/java/org/eclipse/jetty/quic/common/package-info.java
similarity index 100%
rename from jetty-quic/quic-common/src/main/java/org/eclipse/jetty/quic/common/package-info.java
rename to jetty-core/jetty-quic/quic-common/src/main/java/org/eclipse/jetty/quic/common/package-info.java
diff --git a/jetty-core/jetty-quic/quic-quiche/pom.xml b/jetty-core/jetty-quic/quic-quiche/pom.xml
index 903e12135d3..e38c5b93ac2 100644
--- a/jetty-core/jetty-quic/quic-quiche/pom.xml
+++ b/jetty-core/jetty-quic/quic-quiche/pom.xml
@@ -2,14 +2,14 @@
org.eclipse.jetty.quic
- quic-parent
- 11.0.10-SNAPSHOT
+ quic
+ 12.0.0-SNAPSHOT4.0.0quic-quichepom
- Jetty :: QUIC :: Quiche
+ Jetty Core :: QUIC :: Quichequic-quiche-common
diff --git a/jetty-quic/quic-quiche/quic-quiche-common/pom.xml b/jetty-core/jetty-quic/quic-quiche/quic-quiche-common/pom.xml
similarity index 92%
rename from jetty-quic/quic-quiche/quic-quiche-common/pom.xml
rename to jetty-core/jetty-quic/quic-quiche/quic-quiche-common/pom.xml
index 42e23c7eb12..460ad552c49 100644
--- a/jetty-quic/quic-quiche/quic-quiche-common/pom.xml
+++ b/jetty-core/jetty-quic/quic-quiche/quic-quiche-common/pom.xml
@@ -3,12 +3,12 @@
org.eclipse.jetty.quicquic-quiche
- 11.0.10-SNAPSHOT
+ 12.0.0-SNAPSHOT4.0.0quic-quiche-common
- Jetty :: QUIC :: Quiche :: Common
+ Jetty Core :: QUIC :: Quiche :: Common${project.groupId}.quic-quiche-common
diff --git a/jetty-quic/quic-quiche/quic-quiche-common/src/main/java/module-info.java b/jetty-core/jetty-quic/quic-quiche/quic-quiche-common/src/main/java/module-info.java
similarity index 100%
rename from jetty-quic/quic-quiche/quic-quiche-common/src/main/java/module-info.java
rename to jetty-core/jetty-quic/quic-quiche/quic-quiche-common/src/main/java/module-info.java
diff --git a/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/pom.xml b/jetty-core/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/pom.xml
similarity index 95%
rename from jetty-quic/quic-quiche/quic-quiche-foreign-incubator/pom.xml
rename to jetty-core/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/pom.xml
index 7e837607465..3a25efdda98 100644
--- a/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/pom.xml
+++ b/jetty-core/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/pom.xml
@@ -3,12 +3,12 @@
org.eclipse.jetty.quicquic-quiche
- 11.0.10-SNAPSHOT
+ 12.0.0-SNAPSHOT4.0.0quic-quiche-foreign-incubator
- Jetty :: QUIC :: Quiche :: Foreign Binding (incubator)
+ Jetty Core :: QUIC :: Quiche :: Foreign Binding (incubator)${project.groupId}.quic-quiche-foreign-incubator
diff --git a/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/java/module-info.java b/jetty-core/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/java/module-info.java
similarity index 100%
rename from jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/java/module-info.java
rename to jetty-core/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/java/module-info.java
diff --git a/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/sockaddr.java b/jetty-core/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/sockaddr.java
similarity index 100%
rename from jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/sockaddr.java
rename to jetty-core/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/sockaddr.java
diff --git a/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/resources/META-INF/services/org.eclipse.jetty.quic.quiche.QuicheBinding b/jetty-core/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/resources/META-INF/services/org.eclipse.jetty.quic.quiche.QuicheBinding
similarity index 100%
rename from jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/resources/META-INF/services/org.eclipse.jetty.quic.quiche.QuicheBinding
rename to jetty-core/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/resources/META-INF/services/org.eclipse.jetty.quic.quiche.QuicheBinding
diff --git a/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/test/java/org/eclipse/jetty/quic/quiche/foreign/incubator/LowLevelQuicheTest.java b/jetty-core/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/test/java/org/eclipse/jetty/quic/quiche/foreign/incubator/LowLevelQuicheTest.java
similarity index 98%
rename from jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/test/java/org/eclipse/jetty/quic/quiche/foreign/incubator/LowLevelQuicheTest.java
rename to jetty-core/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/test/java/org/eclipse/jetty/quic/quiche/foreign/incubator/LowLevelQuicheTest.java
index f578bf0fe01..3bf7ee9fcd2 100644
--- a/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/test/java/org/eclipse/jetty/quic/quiche/foreign/incubator/LowLevelQuicheTest.java
+++ b/jetty-core/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/test/java/org/eclipse/jetty/quic/quiche/foreign/incubator/LowLevelQuicheTest.java
@@ -32,6 +32,8 @@ import org.eclipse.jetty.quic.quiche.SSLKeyPair;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledOnJre;
+import org.junit.jupiter.api.condition.JRE;
import static org.eclipse.jetty.quic.quiche.Quiche.QUICHE_MIN_CLIENT_INITIAL_LEN;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -39,6 +41,8 @@ import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.Is.is;
+// TODO: make this test work in Java 18 too.
+@EnabledOnJre(value = JRE.JAVA_17, disabledReason = "Java 18's Foreign APIs are incompatible with Java 17's Foreign APIs")
public class LowLevelQuicheTest
{
private final Collection connectionsToDisposeOf = new ArrayList<>();
diff --git a/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/test/resources/jetty-logging.properties b/jetty-core/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/test/resources/jetty-logging.properties
similarity index 100%
rename from jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/test/resources/jetty-logging.properties
rename to jetty-core/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/test/resources/jetty-logging.properties
diff --git a/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/test/resources/keystore.p12 b/jetty-core/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/test/resources/keystore.p12
similarity index 100%
rename from jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/test/resources/keystore.p12
rename to jetty-core/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/test/resources/keystore.p12
diff --git a/jetty-quic/quic-quiche/quic-quiche-jna/pom.xml b/jetty-core/jetty-quic/quic-quiche/quic-quiche-jna/pom.xml
similarity index 94%
rename from jetty-quic/quic-quiche/quic-quiche-jna/pom.xml
rename to jetty-core/jetty-quic/quic-quiche/quic-quiche-jna/pom.xml
index 47a2f88c0ac..f8b10857a8c 100644
--- a/jetty-quic/quic-quiche/quic-quiche-jna/pom.xml
+++ b/jetty-core/jetty-quic/quic-quiche/quic-quiche-jna/pom.xml
@@ -3,12 +3,12 @@
org.eclipse.jetty.quicquic-quiche
- 11.0.10-SNAPSHOT
+ 12.0.0-SNAPSHOT4.0.0quic-quiche-jna
- Jetty :: QUIC :: Quiche :: JNA Binding
+ Jetty Core :: QUIC :: Quiche :: JNA Binding${project.groupId}.quic-quiche-jna
diff --git a/jetty-quic/quic-quiche/quic-quiche-jna/src/main/java/module-info.java b/jetty-core/jetty-quic/quic-quiche/quic-quiche-jna/src/main/java/module-info.java
similarity index 100%
rename from jetty-quic/quic-quiche/quic-quiche-jna/src/main/java/module-info.java
rename to jetty-core/jetty-quic/quic-quiche/quic-quiche-jna/src/main/java/module-info.java
diff --git a/jetty-quic/quic-quiche/quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/sockaddr.java b/jetty-core/jetty-quic/quic-quiche/quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/sockaddr.java
similarity index 100%
rename from jetty-quic/quic-quiche/quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/sockaddr.java
rename to jetty-core/jetty-quic/quic-quiche/quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/sockaddr.java
diff --git a/jetty-quic/quic-quiche/quic-quiche-jna/src/main/resources/META-INF/services/org.eclipse.jetty.quic.quiche.QuicheBinding b/jetty-core/jetty-quic/quic-quiche/quic-quiche-jna/src/main/resources/META-INF/services/org.eclipse.jetty.quic.quiche.QuicheBinding
similarity index 100%
rename from jetty-quic/quic-quiche/quic-quiche-jna/src/main/resources/META-INF/services/org.eclipse.jetty.quic.quiche.QuicheBinding
rename to jetty-core/jetty-quic/quic-quiche/quic-quiche-jna/src/main/resources/META-INF/services/org.eclipse.jetty.quic.quiche.QuicheBinding
diff --git a/jetty-quic/quic-quiche/quic-quiche-jna/src/test/java/org/eclipse/jetty/quic/quiche/jna/LowLevelQuicheTest.java b/jetty-core/jetty-quic/quic-quiche/quic-quiche-jna/src/test/java/org/eclipse/jetty/quic/quiche/jna/LowLevelQuicheTest.java
similarity index 100%
rename from jetty-quic/quic-quiche/quic-quiche-jna/src/test/java/org/eclipse/jetty/quic/quiche/jna/LowLevelQuicheTest.java
rename to jetty-core/jetty-quic/quic-quiche/quic-quiche-jna/src/test/java/org/eclipse/jetty/quic/quiche/jna/LowLevelQuicheTest.java
diff --git a/jetty-quic/quic-quiche/quic-quiche-jna/src/test/resources/jetty-logging.properties b/jetty-core/jetty-quic/quic-quiche/quic-quiche-jna/src/test/resources/jetty-logging.properties
similarity index 100%
rename from jetty-quic/quic-quiche/quic-quiche-jna/src/test/resources/jetty-logging.properties
rename to jetty-core/jetty-quic/quic-quiche/quic-quiche-jna/src/test/resources/jetty-logging.properties
diff --git a/jetty-quic/quic-quiche/quic-quiche-jna/src/test/resources/keystore.p12 b/jetty-core/jetty-quic/quic-quiche/quic-quiche-jna/src/test/resources/keystore.p12
similarity index 100%
rename from jetty-quic/quic-quiche/quic-quiche-jna/src/test/resources/keystore.p12
rename to jetty-core/jetty-quic/quic-quiche/quic-quiche-jna/src/test/resources/keystore.p12
diff --git a/jetty-core/jetty-quic/quic-server/pom.xml b/jetty-core/jetty-quic/quic-server/pom.xml
index f57d0246a0d..14f2ef5110a 100644
--- a/jetty-core/jetty-quic/quic-server/pom.xml
+++ b/jetty-core/jetty-quic/quic-server/pom.xml
@@ -2,13 +2,13 @@
org.eclipse.jetty.quic
- quic-parent
- 11.0.10-SNAPSHOT
+ quic
+ 12.0.0-SNAPSHOT4.0.0quic-server
- Jetty :: QUIC :: Server
+ Jetty Core :: QUIC :: Server${project.groupId}.server
diff --git a/jetty-quic/quic-server/src/main/java/module-info.java b/jetty-core/jetty-quic/quic-server/src/main/java/module-info.java
similarity index 100%
rename from jetty-quic/quic-server/src/main/java/module-info.java
rename to jetty-core/jetty-quic/quic-server/src/main/java/module-info.java
diff --git a/jetty-core/jetty-quic/quic-server/src/test/java/org/eclipse/jetty/quic/server/ServerQuicConnectorTest.java b/jetty-core/jetty-quic/quic-server/src/test/java/org/eclipse/jetty/quic/server/ServerQuicConnectorTest.java
index 519099674be..2c861fe2fbf 100644
--- a/jetty-core/jetty-quic/quic-server/src/test/java/org/eclipse/jetty/quic/server/ServerQuicConnectorTest.java
+++ b/jetty-core/jetty-quic/quic-server/src/test/java/org/eclipse/jetty/quic/server/ServerQuicConnectorTest.java
@@ -13,18 +13,14 @@
package org.eclipse.jetty.quic.server;
-import java.io.IOException;
-import java.io.PrintWriter;
-
-import jakarta.servlet.ServletOutputStream;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpCompliance;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@@ -49,18 +45,18 @@ public class ServerQuicConnectorTest
connector.setPort(8443);
server.addConnector(connector);
- server.setHandler(new AbstractHandler()
+ server.setHandler(new Handler.Processor()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
- baseRequest.setHandled(true);
- PrintWriter writer = response.getWriter();
- writer.println("\n" +
- "\t\n" +
- "\t\tRequest served\n" +
- "\t\n" +
- "");
+ response.write(true, callback, """
+
+
+ Request served
+
+
+ """);
}
});
@@ -90,17 +86,15 @@ public class ServerQuicConnectorTest
connector.setPort(8443);
server.addConnector(connector);
- server.setHandler(new AbstractHandler()
+ server.setHandler(new Handler.Processor()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void process(Request request, Response response, Callback callback)
{
- baseRequest.setHandled(true);
int contentLength = 16 * 1024 * 1024;
response.setContentLength(contentLength);
response.setContentType("text/plain");
- ServletOutputStream outputStream = response.getOutputStream();
- outputStream.println("0".repeat(contentLength));
+ response.write(true, callback, "0".repeat(contentLength));
}
});
diff --git a/jetty-quic/quic-server/src/test/resources/jetty-logging.properties b/jetty-core/jetty-quic/quic-server/src/test/resources/jetty-logging.properties
similarity index 100%
rename from jetty-quic/quic-server/src/test/resources/jetty-logging.properties
rename to jetty-core/jetty-quic/quic-server/src/test/resources/jetty-logging.properties
diff --git a/jetty-quic/quic-server/src/test/resources/keystore.p12 b/jetty-core/jetty-quic/quic-server/src/test/resources/keystore.p12
similarity index 100%
rename from jetty-quic/quic-server/src/test/resources/keystore.p12
rename to jetty-core/jetty-quic/quic-server/src/test/resources/keystore.p12
diff --git a/jetty-core/jetty-rewrite/pom.xml b/jetty-core/jetty-rewrite/pom.xml
index 2d902ddc17a..63c0a9c8318 100644
--- a/jetty-core/jetty-rewrite/pom.xml
+++ b/jetty-core/jetty-rewrite/pom.xml
@@ -1,13 +1,13 @@
org.eclipse.jetty
- jetty-project
- 11.0.10-SNAPSHOT
+ jetty-core
+ 12.0.0-SNAPSHOT4.0.0jetty-rewrite
- Jetty :: Rewrite Handler
+ Jetty Core :: Rewrite HandlerJetty Rewrite Handler
@@ -20,29 +20,21 @@
org.eclipse.jettyjetty-server
-
- org.eclipse.jetty.toolchain
- jetty-jakarta-servlet-api
- org.slf4jslf4j-api
+
org.eclipse.jettyjetty-slf4j-impltest
- org.eclipse.jetty.tests
+ org.eclipse.jettyjetty-http-toolstest
-
- org.eclipse.jetty.toolchain
- jetty-test-helper
- test
-
diff --git a/jetty-rewrite/src/main/config/etc/jetty-rewrite.xml b/jetty-core/jetty-rewrite/src/main/config/etc/jetty-rewrite.xml
similarity index 100%
rename from jetty-rewrite/src/main/config/etc/jetty-rewrite.xml
rename to jetty-core/jetty-rewrite/src/main/config/etc/jetty-rewrite.xml
diff --git a/jetty-rewrite/src/main/java/module-info.java b/jetty-core/jetty-rewrite/src/main/java/module-info.java
similarity index 95%
rename from jetty-rewrite/src/main/java/module-info.java
rename to jetty-core/jetty-rewrite/src/main/java/module-info.java
index 4c8f38c7545..6c5ce923415 100644
--- a/jetty-rewrite/src/main/java/module-info.java
+++ b/jetty-core/jetty-rewrite/src/main/java/module-info.java
@@ -13,10 +13,8 @@
module org.eclipse.jetty.rewrite
{
- requires jetty.servlet.api;
- requires org.slf4j;
-
requires transitive org.eclipse.jetty.server;
+ requires org.slf4j;
exports org.eclipse.jetty.rewrite;
exports org.eclipse.jetty.rewrite.handler;
diff --git a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/RewriteCustomizer.java b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/RewriteCustomizer.java
index fe717c12d09..534b6ead1f7 100644
--- a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/RewriteCustomizer.java
+++ b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/RewriteCustomizer.java
@@ -15,21 +15,22 @@ package org.eclipse.jetty.rewrite;
import java.io.IOException;
+import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.io.RuntimeIOException;
import org.eclipse.jetty.rewrite.handler.RuleContainer;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConfiguration.Customizer;
import org.eclipse.jetty.server.Request;
public class RewriteCustomizer extends RuleContainer implements Customizer
{
@Override
- public void customize(Connector connector, HttpConfiguration channelConfig, Request request)
+ public Request customize(Request request, HttpFields.Mutable responseHeaders)
{
try
{
- matchAndApply(request.getPathInfo(), request, request.getResponse());
+ // TODO: rule are able to complete the request/response, but customizers cannot.
+ Request.WrapperProcessor input = new Request.WrapperProcessor(request);
+ return matchAndApply(input);
}
catch (IOException e)
{
diff --git a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CompactPathRule.java b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CompactPathRule.java
index 6f1558bcecb..f0223cc5967 100644
--- a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CompactPathRule.java
+++ b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CompactPathRule.java
@@ -15,37 +15,31 @@ package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.URIUtil;
/**
- * Rewrite the URI by compacting to remove //
+ *
Rewrites the URI by compacting to remove occurrences of {@code //}.
+ *
For example, {@code //foo/bar//baz} is compacted to {@code /foo/bar/baz}.
*/
-public class CompactPathRule extends Rule implements Rule.ApplyURI
+public class CompactPathRule extends Rule
{
- public CompactPathRule()
- {
- _handling = false;
- _terminating = false;
- }
-
@Override
- public void applyURI(Request request, String oldURI, String newURI) throws IOException
+ public Request.WrapperProcessor matchAndApply(Request.WrapperProcessor input) throws IOException
{
- String uri = request.getRequestURI();
- if (uri.startsWith("/"))
- uri = URIUtil.compactPath(uri);
- request.setHttpURI(HttpURI.build(request.getHttpURI(), uri));
- }
+ String path = input.getPathInContext();
+ String compacted = URIUtil.compactPath(path);
- @Override
- public String matchAndApply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException
- {
- if (target.startsWith("/"))
- return URIUtil.compactPath(target);
- return target;
+ if (path.equals(compacted))
+ return null;
+
+ return new Request.WrapperProcessor(input)
+ {
+ @Override
+ public String getPathInContext()
+ {
+ return compacted;
+ }
+ };
}
}
diff --git a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CookiePatternRule.java b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CookiePatternRule.java
index 63782528372..63ed30c7917 100644
--- a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CookiePatternRule.java
+++ b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CookiePatternRule.java
@@ -14,16 +14,18 @@
package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
+import java.util.List;
-import jakarta.servlet.http.Cookie;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.http.HttpCookie;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.annotation.Name;
/**
- * Sets the cookie in the response whenever the rule finds a match.
+ *
Sets a response cookie whenever the rule matches.
*
- * @see Cookie
+ * @see HttpCookie
*/
public class CookiePatternRule extends PatternRule
{
@@ -38,16 +40,20 @@ public class CookiePatternRule extends PatternRule
public CookiePatternRule(@Name("pattern") String pattern, @Name("name") String name, @Name("value") String value)
{
super(pattern);
- _handling = false;
- _terminating = false;
setName(name);
setValue(value);
}
/**
- * Assigns the cookie name.
- *
- * @param name a String specifying the name of the cookie.
+ * @return the response cookie name
+ */
+ public String getName()
+ {
+ return _name;
+ }
+
+ /**
+ * @param name the response cookie name
*/
public void setName(String name)
{
@@ -55,10 +61,15 @@ public class CookiePatternRule extends PatternRule
}
/**
- * Assigns the cookie value.
- *
- * @param value a String specifying the value of the cookie
- * @see Cookie#setValue(String)
+ * @return the response cookie value
+ */
+ public String getValue()
+ {
+ return _value;
+ }
+
+ /**
+ * @param value the response cookie value
*/
public void setValue(String value)
{
@@ -66,30 +77,34 @@ public class CookiePatternRule extends PatternRule
}
@Override
- public String apply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public Request.WrapperProcessor apply(Request.WrapperProcessor input) throws IOException
{
+ // TODO: fix once Request.getCookies() is implemented (currently always returns null)
// Check that cookie is not already set
- Cookie[] cookies = request.getCookies();
+ List cookies = Request.getCookies(input);
if (cookies != null)
{
- for (Cookie cookie : cookies)
+ for (HttpCookie cookie : cookies)
{
if (_name.equals(cookie.getName()) && _value.equals(cookie.getValue()))
- return target;
+ return null;
}
}
- // set it
- response.addCookie(new Cookie(_name, _value));
- return target;
+ return new Request.WrapperProcessor(input)
+ {
+ @Override
+ public void process(Request ignored, Response response, Callback callback) throws Exception
+ {
+ Response.addCookie(response, new HttpCookie(_name, _value));
+ super.process(this, response, callback);
+ }
+ };
}
- /**
- * Returns the cookie contents.
- */
@Override
public String toString()
{
- return super.toString() + "[" + _name + "," + _value + "]";
+ return "%s@%x[set-cookie:%s=%s]".formatted(super.toString(), hashCode(), getName(), getValue());
}
}
diff --git a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ForceRequestHeaderValueRule.java b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ForceRequestHeaderValueRule.java
index 9f44ff38df9..441875faab4 100644
--- a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ForceRequestHeaderValueRule.java
+++ b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ForceRequestHeaderValueRule.java
@@ -15,15 +15,13 @@ package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.server.Request;
public class ForceRequestHeaderValueRule extends Rule
{
private String headerName;
- private String forcedValue;
+ private String headerValue;
public String getHeaderName()
{
@@ -35,40 +33,40 @@ public class ForceRequestHeaderValueRule extends Rule
this.headerName = headerName;
}
- public String getForcedValue()
+ public String getHeaderValue()
{
- return forcedValue;
+ return headerValue;
}
- public void setForcedValue(String forcedValue)
+ public void setHeaderValue(String headerValue)
{
- this.forcedValue = forcedValue;
+ this.headerValue = headerValue;
}
@Override
- public String matchAndApply(String target, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException
+ public Request.WrapperProcessor matchAndApply(Request.WrapperProcessor input) throws IOException
{
- String existingValue = httpServletRequest.getHeader(headerName);
+ HttpFields headers = input.getHeaders();
+ String existingValue = headers.get(headerName);
+
+ // No hit, skip this rule.
if (existingValue == null)
+ return null;
+
+ // Already what we expect, skip this rule.
+ if (existingValue.equals(headerValue))
+ return null;
+
+ HttpFields.Mutable newHeaders = HttpFields.build(headers);
+ newHeaders.remove(headerName);
+ newHeaders.add(headerName, headerValue);
+ return new Request.WrapperProcessor(input)
{
- // no hit, skip this rule.
- return null;
- }
-
- if (existingValue.equals(forcedValue))
- {
- // already what we expect, skip this rule.
- return null;
- }
-
- Request baseRequest = Request.getBaseRequest(httpServletRequest);
- if (baseRequest == null)
- return null;
-
- HttpFields.Mutable replacement = HttpFields.build(baseRequest.getHttpFields())
- .remove(headerName)
- .add(headerName, forcedValue);
- baseRequest.setHttpFields(replacement);
- return target;
+ @Override
+ public HttpFields getHeaders()
+ {
+ return newHeaders;
+ }
+ };
}
}
diff --git a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRule.java b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRule.java
index e4c9790faef..abbef9b784e 100644
--- a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRule.java
+++ b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRule.java
@@ -13,13 +13,11 @@
package org.eclipse.jetty.rewrite.handler;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.server.Request;
/**
- * Set the scheme for the request
+ *
Sets the request URI scheme, by default {@code https}.
*/
public class ForwardedSchemeHeaderRule extends HeaderRule
{
@@ -30,19 +28,22 @@ public class ForwardedSchemeHeaderRule extends HeaderRule
return _scheme;
}
- /**
- * @param scheme the scheme to set on the request. Defaults to "https"
- */
public void setScheme(String scheme)
{
_scheme = scheme;
}
@Override
- protected String apply(String target, String value, HttpServletRequest request, HttpServletResponse response)
+ protected Request.WrapperProcessor apply(Request.WrapperProcessor input, String value)
{
- Request baseRequest = Request.getBaseRequest(request);
- baseRequest.setHttpURI(HttpURI.build(baseRequest.getHttpURI()).scheme(_scheme));
- return target;
+ HttpURI newURI = HttpURI.build(input.getHttpURI()).scheme(getScheme());
+ return new Request.WrapperProcessor(input)
+ {
+ @Override
+ public HttpURI getHttpURI()
+ {
+ return newURI;
+ }
+ };
}
}
diff --git a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRule.java b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRule.java
index 24cbf6aaab9..327fb37b7cb 100644
--- a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRule.java
+++ b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRule.java
@@ -15,118 +15,80 @@ package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.annotation.Name;
/**
- * Sets the header in the response whenever the rule finds a match.
+ *
Puts or adds a response header whenever the rule matches a path Servlet pattern.
*/
public class HeaderPatternRule extends PatternRule
{
- private String _name;
- private String _value;
+ private String _headerName;
+ private String _headerValue;
private boolean _add;
- public HeaderPatternRule()
- {
- this(null, null, null);
- }
-
public HeaderPatternRule(@Name("pattern") String pattern, @Name("name") String name, @Name("value") String value)
{
super(pattern);
- _handling = false;
- _terminating = false;
- _add = false;
- setName(name);
- setValue(value);
+ _headerName = name;
+ _headerValue = value;
}
- /**
- * Sets the header name.
- *
- * @param name name of the header field
- */
- public void setName(String name)
+ public String getHeaderName()
{
- _name = name;
+ return _headerName;
}
- /**
- * Sets the header value. The value can be either a String or int value.
- *
- * @param value of the header field
- */
- public void setValue(String value)
+ public void setHeaderName(String name)
{
- _value = value;
+ _headerName = name;
}
- /**
- * Sets the Add flag.
- *
- * @param add If true, the header is added to the response, otherwise the header it is set on the response.
- */
- public void setAdd(boolean add)
+ public String getHeaderValue()
{
- _add = add;
+ return _headerValue;
}
- /**
- * Invokes this method when a match found. If the header had already been set,
- * the new value overwrites the previous one. Otherwise, it adds the new
- * header name and value.
- *
- * @see org.eclipse.jetty.rewrite.handler.Rule#matchAndApply(String, jakarta.servlet.http.HttpServletRequest, jakarta.servlet.http.HttpServletResponse)
- */
- @Override
- public String apply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void setHeaderValue(String value)
{
- // process header
- if (_add)
- response.addHeader(_name, _value);
- else
- response.setHeader(_name, _value);
- return target;
+ _headerValue = value;
}
- /**
- * Returns the header name.
- *
- * @return the header name.
- */
- public String getName()
- {
- return _name;
- }
-
- /**
- * Returns the header value.
- *
- * @return the header value.
- */
- public String getValue()
- {
- return _value;
- }
-
- /**
- * Returns the add flag value.
- *
- * @return true if add flag set
- */
public boolean isAdd()
{
return _add;
}
/**
- * Returns the header contents.
+ * @param add true to add the response header, false to put the response header.
*/
+ public void setAdd(boolean add)
+ {
+ _add = add;
+ }
+
+ @Override
+ public Request.WrapperProcessor apply(Request.WrapperProcessor input) throws IOException
+ {
+ return new Request.WrapperProcessor(input)
+ {
+ @Override
+ public void process(Request ignored, Response response, Callback callback) throws Exception
+ {
+ if (isAdd())
+ response.addHeader(getHeaderName(), getHeaderValue());
+ else
+ response.setHeader(getHeaderName(), getHeaderValue());
+ super.process(ignored, response, callback);
+ }
+ };
+ }
+
@Override
public String toString()
{
- return super.toString() + "[" + _name + "," + _value + "]";
+ return "%s[header:%s=%s]".formatted(super.toString(), getHeaderName(), getHeaderValue());
}
}
diff --git a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderRegexRule.java b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderRegexRule.java
index c3249891b2a..8dbad4c5431 100644
--- a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderRegexRule.java
+++ b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderRegexRule.java
@@ -16,57 +16,54 @@ package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
import java.util.regex.Matcher;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.annotation.Name;
/**
- * Rule to add a header based on a Regex match
+ *
Puts or adds a response header whenever the rule matches a path regex pattern.
*/
public class HeaderRegexRule extends RegexRule
{
- private String _name;
- private String _value;
- private boolean _add = false;
-
- public HeaderRegexRule()
- {
- this(null, null, null);
- }
+ private String _headerName;
+ private String _headerValue;
+ private boolean _add;
public HeaderRegexRule(@Name("regex") String regex, @Name("name") String name, @Name("value") String value)
{
super(regex);
- setHandling(false);
- setTerminating(false);
- setName(name);
- setValue(value);
+ _headerName = name;
+ _headerValue = value;
}
- /**
- * Sets the header name.
- *
- * @param name name of the header field
- */
- public void setName(String name)
+ public String getHeaderName()
{
- _name = name;
+ return _headerName;
}
- /**
- * Sets the header value. The value can be either a String or int value.
- *
- * @param value of the header field
- */
- public void setValue(String value)
+ public void setHeaderName(String name)
{
- _value = value;
+ _headerName = name;
+ }
+
+ public String getHeaderValue()
+ {
+ return _headerValue;
+ }
+
+ public void setHeaderValue(String value)
+ {
+ _headerValue = value;
+ }
+
+ public boolean isAdd()
+ {
+ return _add;
}
/**
- * Sets the Add flag.
- *
- * @param add If true, the header is added to the response, otherwise the header it is set on the response.
+ * @param add true to add the response header, false to put the response header.
*/
public void setAdd(boolean add)
{
@@ -74,51 +71,25 @@ public class HeaderRegexRule extends RegexRule
}
@Override
- protected String apply(String target, HttpServletRequest request, HttpServletResponse response, Matcher matcher)
- throws IOException
+ protected Request.WrapperProcessor apply(Request.WrapperProcessor input, Matcher matcher) throws IOException
{
- // process header
- if (_add)
- response.addHeader(_name, _value);
- else
- response.setHeader(_name, _value);
- return target;
+ return new Request.WrapperProcessor(input)
+ {
+ @Override
+ public void process(Request ignored, Response response, Callback callback) throws Exception
+ {
+ if (isAdd())
+ response.addHeader(getHeaderName(), matcher.replaceAll(getHeaderValue()));
+ else
+ response.setHeader(getHeaderName(), matcher.replaceAll(getHeaderValue()));
+ super.process(ignored, response, callback);
+ }
+ };
}
- /**
- * Returns the header name.
- *
- * @return the header name.
- */
- public String getName()
- {
- return _name;
- }
-
- /**
- * Returns the header value.
- *
- * @return the header value.
- */
- public String getValue()
- {
- return _value;
- }
-
- /**
- * @return the add flag value.
- */
- public boolean isAdd()
- {
- return _add;
- }
-
- /**
- * @return the header contents.
- */
@Override
public String toString()
{
- return super.toString() + "[" + _name + "," + _value + "]";
+ return "%s[header:%s=%s]".formatted(super.toString(), getHeaderName(), getHeaderValue());
}
}
diff --git a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderRule.java b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderRule.java
index ce4653ec3a0..df54bf95e3e 100644
--- a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderRule.java
+++ b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderRule.java
@@ -15,29 +15,24 @@ package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.server.Request;
/**
- * Abstract rule that matches against request headers.
+ *
Abstract rule that matches against request headers.
*/
-
public abstract class HeaderRule extends Rule
{
- private String _header;
+ private String _headerName;
private String _headerValue;
- public String getHeader()
+ public String getHeaderName()
{
- return _header;
+ return _headerName;
}
- /**
- * @param header the header name to check for
- */
- public void setHeader(String header)
+ public void setHeaderName(String header)
{
- _header = header;
+ _headerName = header;
}
public String getHeaderValue()
@@ -46,8 +41,8 @@ public abstract class HeaderRule extends Rule
}
/**
- * @param headerValue the header value to match against. If null, then the
- * presence of the header is enough to match
+ * @param headerValue the header value to match against.
+ * If {@code null}, then the presence of the header is enough to match
*/
public void setHeaderValue(String headerValue)
{
@@ -55,34 +50,30 @@ public abstract class HeaderRule extends Rule
}
@Override
- public String matchAndApply(String target, HttpServletRequest request,
- HttpServletResponse response) throws IOException
+ public Request.WrapperProcessor matchAndApply(Request.WrapperProcessor input) throws IOException
{
- String requestHeaderValue = request.getHeader(_header);
-
- if (requestHeaderValue != null)
- if (_headerValue == null || _headerValue.equals(requestHeaderValue))
- apply(target, requestHeaderValue, request, response);
-
+ String value = input.getHeaders().get(getHeaderName());
+ if (value == null)
+ return null;
+ String headerValue = getHeaderValue();
+ if (headerValue == null || headerValue.equals(value))
+ return apply(input, value);
return null;
}
/**
- * Apply the rule to the request
+ *
Invoked after the header matched the {@code Request} headers to apply the rule's logic.
*
- * @param target field to attempt match
- * @param value header value found
- * @param request request object
- * @param response response object
- * @return The target (possible updated)
- * @throws IOException exceptions dealing with operating on request or response
- * objects
+ * @param input the input {@code Request} and {@code Processor}
+ * @param value the header value
+ * @return the possibly wrapped {@code Request} and {@code Processor}
+ * @throws IOException if applying the rule failed
*/
- protected abstract String apply(String target, String value, HttpServletRequest request, HttpServletResponse response) throws IOException;
+ protected abstract Request.WrapperProcessor apply(Request.WrapperProcessor input, String value) throws IOException;
@Override
public String toString()
{
- return super.toString() + "[" + _header + ":" + _headerValue + "]";
+ return "%s[header:%s=%s]".formatted(super.toString(), getHeaderName(), getHeaderValue());
}
}
diff --git a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/InvalidURIRule.java b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/InvalidURIRule.java
new file mode 100644
index 00000000000..bd62a2d0b21
--- /dev/null
+++ b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/InvalidURIRule.java
@@ -0,0 +1,130 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.rewrite.handler;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
+import org.eclipse.jetty.util.StringUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
Rule that protects against invalid unicode characters in URLs,
+ * returning a configurable status code with body message.
+ *
The logic is as follows:
+ *
+ *
if a decoded URI character is an iso control character, apply the rule
+ *
if no {@link Character.UnicodeBlock} is found for a decoded URI character, apply the rule
+ *
if a decoded URI character is in UnicodeBlock.SPECIALS, apply the rule
Rewrite handler is responsible for managing the rules. Its capabilities
@@ -31,8 +25,7 @@ import org.eclipse.jetty.server.handler.HandlerWrapper;
* whenever the rule finds a match.
*
*
The rules can be matched by the either: pattern matching of @{@link org.eclipse.jetty.http.pathmap.ServletPathSpec}
- * (eg {@link PatternRule}), regular expressions (eg {@link RegexRule}) or certain conditions set
- * (eg {@link MsieSslRule} - the requests must be in SSL mode).
+ * (eg {@link PatternRule}), regular expressions (eg {@link RegexRule}) or custom logic.
*
*
The rules can be grouped into rule containers (class {@link RuleContainer}), and will only
* be applied if the request matches the conditions for their container
@@ -46,7 +39,6 @@ import org.eclipse.jetty.server.handler.HandlerWrapper;
*
{@link ResponsePatternRule} - sets the status/error codes.
*
{@link RewritePatternRule} - rewrites the requested URI.
*
{@link RewriteRegexRule} - rewrites the requested URI using regular expression for pattern matching.
- *
{@link MsieSslRule} - disables the keep alive on SSL for IE5 and IE6.
*
{@link ForwardedSchemeHeaderRule} - set the scheme according to the headers present.
*
{@link VirtualHostRuleContainer} - checks whether the request matches one of a set of virtual host names.
*
@@ -160,14 +152,18 @@ import org.eclipse.jetty.server.handler.HandlerWrapper;
* </Set>
*
*/
-public class RewriteHandler extends HandlerWrapper
+public class RewriteHandler extends Handler.Wrapper
{
- private RuleContainer _rules;
- private EnumSet _dispatchTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.ASYNC);
+ private final RuleContainer _rules;
public RewriteHandler()
{
- _rules = new RuleContainer();
+ this(new RuleContainer());
+ }
+
+ public RewriteHandler(RuleContainer rules)
+ {
+ _rules = rules;
addBean(_rules);
}
@@ -176,7 +172,7 @@ public class RewriteHandler extends HandlerWrapper
*
* @return an array of {@link Rule}.
*/
- public Rule[] getRules()
+ public List getRules()
{
return _rules.getRules();
}
@@ -186,27 +182,11 @@ public class RewriteHandler extends HandlerWrapper
*
* @param rules an array of {@link Rule}.
*/
- public void setRules(Rule[] rules)
+ public void setRules(List rules)
{
_rules.setRules(rules);
}
- /**
- * Assigns the rules to process.
- *
- * @param rules a {@link RuleContainer} containing other rules to process
- */
- public void setRuleContainer(RuleContainer rules)
- {
- updateBean(_rules, rules);
- _rules = rules;
- }
-
- public RuleContainer getRuleContainer()
- {
- return _rules;
- }
-
/**
* Add a Rule
*
@@ -218,43 +198,7 @@ public class RewriteHandler extends HandlerWrapper
}
/**
- * @return the rewriteRequestURI If true, this handler will rewrite the value
- * returned by {@link HttpServletRequest#getRequestURI()}.
- */
- public boolean isRewriteRequestURI()
- {
- return _rules.isRewriteRequestURI();
- }
-
- /**
- * @param rewriteRequestURI true if this handler will rewrite the value
- * returned by {@link HttpServletRequest#getRequestURI()}.
- */
- public void setRewriteRequestURI(boolean rewriteRequestURI)
- {
- _rules.setRewriteRequestURI(rewriteRequestURI);
- }
-
- /**
- * @return true if this handler will rewrite the value
- * returned by {@link HttpServletRequest#getPathInfo()}.
- */
- public boolean isRewritePathInfo()
- {
- return _rules.isRewritePathInfo();
- }
-
- /**
- * @param rewritePathInfo true if this handler will rewrite the value
- * returned by {@link HttpServletRequest#getPathInfo()}.
- */
- public void setRewritePathInfo(boolean rewritePathInfo)
- {
- _rules.setRewritePathInfo(rewritePathInfo);
- }
-
- /**
- * @return the originalPathAttribte. If non null, this string will be used
+ * @return the originalPathAttribute. If non null, this string will be used
* as the attribute name to store the original request path.
*/
public String getOriginalPathAttribute()
@@ -271,34 +215,20 @@ public class RewriteHandler extends HandlerWrapper
_rules.setOriginalPathAttribute(originalPathAttribute);
}
- public EnumSet getDispatcherTypes()
- {
- return _dispatchTypes;
- }
-
- public void setDispatcherTypes(EnumSet types)
- {
- _dispatchTypes = EnumSet.copyOf(types);
- }
-
- public void setDispatcherTypes(DispatcherType... types)
- {
- _dispatchTypes = EnumSet.copyOf(Arrays.asList(types));
- }
-
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ public Request.Processor handle(Request request) throws Exception
{
- if (isStarted())
- {
- if (_dispatchTypes.contains(baseRequest.getDispatcherType()))
- {
- String returned = _rules.matchAndApply(target, request, response);
- target = (returned == null) ? target : returned;
- }
+ if (!isStarted())
+ return null;
- if (!baseRequest.isHandled())
- super.handle(target, baseRequest, request, response);
- }
+ Request.WrapperProcessor input = new Request.WrapperProcessor(request);
+ Request.WrapperProcessor output = _rules.matchAndApply(input);
+
+ // No rule matched, call super with the original request.
+ if (output == null)
+ return super.handle(request);
+
+ // At least one rule matched, call super with the result of the rule applications.
+ return output.wrapProcessor(super.handle(output));
}
}
diff --git a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewritePatternRule.java b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewritePatternRule.java
index fedd8c5e0d3..78d724d0a2a 100644
--- a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewritePatternRule.java
+++ b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewritePatternRule.java
@@ -15,88 +15,72 @@ package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.pathmap.ServletPathSpec;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.annotation.Name;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
- * Rewrite the URI by replacing the matched {@link ServletPathSpec} path with a fixed string.
+ *
A rule to rewrite the path and query that match a Servlet pattern with a fixed string.
*/
-public class RewritePatternRule extends PatternRule implements Rule.ApplyURI
+public class RewritePatternRule extends PatternRule
{
- private String _replacement;
- private String _query;
+ private static final Logger LOG = LoggerFactory.getLogger(RewritePatternRule.class);
- public RewritePatternRule()
- {
- this(null, null);
- }
+ private String _path;
+ private String _query;
public RewritePatternRule(@Name("pattern") String pattern, @Name("replacement") String replacement)
{
super(pattern);
- _handling = false;
- _terminating = false;
setReplacement(replacement);
}
/**
- * Whenever a match is found, it replaces with this value.
+ *
The replacement for the path and query matched by this rule.
*
- * @param replacement the replacement string.
+ * @param replacement the replacement path
*/
public void setReplacement(String replacement)
{
if (replacement == null)
{
- _replacement = null;
+ _path = null;
_query = null;
}
else
{
String[] split = replacement.split("\\?", 2);
- _replacement = split[0];
+ _path = split[0];
_query = split.length == 2 ? split[1] : null;
}
}
@Override
- public String apply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public Request.WrapperProcessor apply(Request.WrapperProcessor input) throws IOException
{
- target = URIUtil.addPaths(_replacement, ServletPathSpec.pathInfo(_pattern, target));
- return target;
+ HttpURI httpURI = input.getHttpURI();
+ String newQuery = URIUtil.addQueries(httpURI.getQuery(), _query);
+ String newPath = URIUtil.addPaths(_path, ServletPathSpec.pathInfo(getPattern(), httpURI.getPath()));
+ HttpURI newURI = HttpURI.build(httpURI, newPath, httpURI.getParam(), newQuery);
+ if (LOG.isDebugEnabled())
+ LOG.debug("rewriting {} to {}", httpURI, newURI);
+ return new Request.WrapperProcessor(input)
+ {
+ @Override
+ public HttpURI getHttpURI()
+ {
+ return newURI;
+ }
+ };
}
- /**
- * This method will add _query to the requests's queryString and also combine it with existing queryStrings in
- * the request. However it won't take care for duplicate. E.g. if request.getQueryString contains a parameter
- * param1 = true and _query will contain param1=false the result will be param1=true¶m1=false.
- * To cover this use case some more complex pattern matching is necessary. We can implement this if there's use
- * cases.
- *
- * @param request the request
- * @param oldURI the old URI
- * @param newURI the new URI
- * @throws IOException if unable to apply the URI
- */
- @Override
- public void applyURI(Request request, String oldURI, String newURI) throws IOException
- {
- HttpURI baseURI = request.getHttpURI();
- String query = URIUtil.addQueries(baseURI.getQuery(), _query);
- request.setHttpURI(HttpURI.build(baseURI, newURI, baseURI.getParam(), query));
- }
-
- /**
- * Returns the replacement string.
- */
@Override
public String toString()
{
- return super.toString() + "[" + _replacement + "]";
+ return "%s[rewrite:%s%s]".formatted(super.toString(), _path, _query == null ? "" : "?" + _query);
}
}
diff --git a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java
index 9b4a6f6878b..e84db590a97 100644
--- a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java
+++ b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java
@@ -16,37 +16,22 @@ package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
import java.util.regex.Matcher;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.annotation.Name;
/**
- * Rewrite the URI by matching with a regular expression.
- * The replacement string may use $n" to replace the nth capture group.
- * If the replacement string contains ? character, then it is split into a path
- * and query string component. The replacement query string may also contain $Q, which
- * is replaced with the original query string.
- * The returned target contains only the path.
+ *
A rule to rewrite the path and query that match a regular expression pattern with a fixed string.
+ *
The replacement String follows standard {@link Matcher#replaceAll(String)} behavior, including named groups
An abstract rule that, upon matching a certain condition, may wrap
+ * the {@code Request} or the {@code Processor} to execute custom logic.
*/
public abstract class Rule
{
- /**
- * Interface used to apply a changed target if {@link RuleContainer#setRewriteRequestURI(boolean)} is true.
- */
- public interface ApplyURI
- {
- void applyURI(Request request, String oldURI, String newURI) throws IOException;
- }
-
- protected boolean _terminating;
- protected boolean _handling;
+ private boolean _terminating;
/**
- * This method calls tests the rule against the request/response pair and if the Rule
- * applies, then the rule's action is triggered.
+ *
Tests whether the given {@code Request} should apply, and if so the rule logic is triggered.
*
- * @param target The target of the request
- * @param request the request
- * @param response the response
- * @return The new target if the rule has matched, else null
- * @throws IOException if unable to match the rule
+ * @param input the input {@code Request} and {@code Processor}
+ * @return the possibly wrapped {@code Request} and {@code Processor}, or {@code null} if the rule did not match
+ * @throws IOException if applying the rule failed
*/
- public abstract String matchAndApply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException;
+ public abstract Request.WrapperProcessor matchAndApply(Request.WrapperProcessor input) throws IOException;
/**
- * Sets terminating to true or false.
- *
- * @param terminating If true, this rule will terminate the loop if this rule has been applied.
- */
- public void setTerminating(boolean terminating)
- {
- _terminating = terminating;
- }
-
- /**
- * Returns the terminating flag value.
- *
- * @return true if the rule needs to terminate; false otherwise.
+ * @return when {@code true}, rules after this one are not processed
*/
public boolean isTerminating()
{
return _terminating;
}
- /**
- * Returns the handling flag value.
- *
- * @return true if the rule handles the request and nested handlers should not be called.
- */
- public boolean isHandling()
+ public void setTerminating(boolean value)
{
- return _handling;
- }
-
- /**
- * Set the handling flag value.
- *
- * @param handling true if the rule handles the request and nested handlers should not be called.
- */
- public void setHandling(boolean handling)
- {
- _handling = handling;
+ _terminating = value;
}
/**
@@ -93,6 +53,6 @@ public abstract class Rule
@Override
public String toString()
{
- return this.getClass().getName() + (_handling ? "[H" : "[h") + (_terminating ? "T]" : "t]");
+ return "%s@%x[terminating=%b]".formatted(getClass().getSimpleName(), hashCode(), isTerminating());
}
}
diff --git a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java
index abcd2c550f5..3e4f4c96adb 100644
--- a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java
+++ b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java
@@ -14,13 +14,12 @@
package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.util.ArrayUtil;
-import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.component.Dumpable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -29,36 +28,37 @@ import org.slf4j.LoggerFactory;
* Base container to group rules. Can be extended so that the contained rules
* will only be applied under certain conditions
*/
-public class RuleContainer extends Rule implements Dumpable
+public class RuleContainer extends Rule implements Iterable, Dumpable
{
public static final String ORIGINAL_QUERYSTRING_ATTRIBUTE_SUFFIX = ".QUERYSTRING";
private static final Logger LOG = LoggerFactory.getLogger(RuleContainer.class);
- protected Rule[] _rules;
+ private final List _rules = new ArrayList<>();
- protected String _originalPathAttribute;
- protected String _originalQueryStringAttribute;
- protected boolean _rewriteRequestURI = true;
- protected boolean _rewritePathInfo = true;
+ private String _originalPathAttribute;
+ private String _originalQueryStringAttribute;
/**
- * Returns the list of rules.
- *
- * @return an array of {@link Rule}.
+ * @return the list of {@code Rule}s
*/
- public Rule[] getRules()
+ public List getRules()
{
return _rules;
}
/**
- * Assigns the rules to process.
- *
- * @param rules an array of {@link Rule}.
+ * @param rules the list of {@link Rule}.
*/
- public void setRules(Rule[] rules)
+ public void setRules(List rules)
{
- _rules = rules;
+ _rules.clear();
+ _rules.addAll(rules);
+ }
+
+ @Override
+ public Iterator iterator()
+ {
+ return _rules.iterator();
}
/**
@@ -68,43 +68,7 @@ public class RuleContainer extends Rule implements Dumpable
*/
public void addRule(Rule rule)
{
- _rules = ArrayUtil.addToArray(_rules, rule, Rule.class);
- }
-
- /**
- * @return the rewriteRequestURI If true, this handler will rewrite the value
- * returned by {@link HttpServletRequest#getRequestURI()}.
- */
- public boolean isRewriteRequestURI()
- {
- return _rewriteRequestURI;
- }
-
- /**
- * @param rewriteRequestURI true if this handler will rewrite the value
- * returned by {@link HttpServletRequest#getRequestURI()}.
- */
- public void setRewriteRequestURI(boolean rewriteRequestURI)
- {
- _rewriteRequestURI = rewriteRequestURI;
- }
-
- /**
- * @return true if this handler will rewrite the value
- * returned by {@link HttpServletRequest#getPathInfo()}.
- */
- public boolean isRewritePathInfo()
- {
- return _rewritePathInfo;
- }
-
- /**
- * @param rewritePathInfo true if this handler will rewrite the value
- * returned by {@link HttpServletRequest#getPathInfo()}.
- */
- public void setRewritePathInfo(boolean rewritePathInfo)
- {
- _rewritePathInfo = rewritePathInfo;
+ _rules.add(rule);
}
/**
@@ -117,98 +81,64 @@ public class RuleContainer extends Rule implements Dumpable
}
/**
- * @param originalPathAttribte If non null, this string will be used
+ * @param originalPathAttribute If non null, this string will be used
* as the attribute name to store the original request path.
*/
- public void setOriginalPathAttribute(String originalPathAttribte)
+ public void setOriginalPathAttribute(String originalPathAttribute)
{
- _originalPathAttribute = originalPathAttribte;
- _originalQueryStringAttribute = originalPathAttribte + ORIGINAL_QUERYSTRING_ATTRIBUTE_SUFFIX;
+ _originalPathAttribute = originalPathAttribute;
+ _originalQueryStringAttribute = originalPathAttribute + ORIGINAL_QUERYSTRING_ATTRIBUTE_SUFFIX;
}
/**
- * Process the contained rules
+ *
Processes the rules.
*
- * @param target target field to pass on to the contained rules
- * @param request request object to pass on to the contained rules
- * @param response response object to pass on to the contained rules
+ * @param input the input {@code Request} and {@code Processor}
+ * @return a {@code Request} and {@code Processor}, possibly wrapped by rules to implement the rule's logic,
+ * or {@code null} if no rule matched
*/
@Override
- public String matchAndApply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public Request.WrapperProcessor matchAndApply(Request.WrapperProcessor input) throws IOException
{
- return apply(target, request, response);
- }
-
- /**
- * Process the contained rules (called by matchAndApply)
- *
- * @param target target field to pass on to the contained rules
- * @param request request object to pass on to the contained rules
- * @param response response object to pass on to the contained rules
- * @return the target
- * @throws IOException if unable to apply the rule
- */
- protected String apply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException
- {
- boolean originalSet = _originalPathAttribute == null;
-
- if (_rules == null)
- return target;
+ if (_originalPathAttribute != null)
+ {
+ HttpURI httpURI = input.getHttpURI();
+ input.setAttribute(_originalPathAttribute, httpURI.getPath());
+ if (_originalQueryStringAttribute != null)
+ input.setAttribute(_originalQueryStringAttribute, httpURI.getQuery());
+ }
+ boolean match = false;
for (Rule rule : _rules)
{
- String applied = rule.matchAndApply(target, request, response);
- if (applied != null)
+ if (LOG.isDebugEnabled())
+ LOG.debug("applying {}", rule);
+ Request.WrapperProcessor output = rule.matchAndApply(input);
+ if (output == null)
{
- LOG.debug("applied {}", rule);
- LOG.debug("rewrote {} to {}", target, applied);
- if (!originalSet)
- {
- originalSet = true;
- request.setAttribute(_originalPathAttribute, target);
+ if (LOG.isDebugEnabled())
+ LOG.debug("no match {}", rule);
+ }
+ else
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("match {}", rule);
- String query = request.getQueryString();
- if (query != null)
- request.setAttribute(_originalQueryStringAttribute, query);
- }
+ match = true;
- // Ugly hack, we should just pass baseRequest into the API from RewriteHandler itself.
- Request baseRequest = Request.getBaseRequest(request);
-
- if (_rewriteRequestURI)
- {
- String encoded = URIUtil.encodePath(applied);
- if (rule instanceof Rule.ApplyURI)
- ((Rule.ApplyURI)rule).applyURI(baseRequest, baseRequest.getRequestURI(), encoded);
- else
- {
- HttpURI baseUri = baseRequest.getHttpURI();
- baseRequest.setHttpURI(HttpURI.build(baseUri, encoded)
- .param(baseUri.getParam())
- .query(baseUri.getQuery()));
- }
- }
-
- if (_rewritePathInfo)
- baseRequest.setContext(baseRequest.getContext(), applied);
-
- target = applied;
-
- if (rule.isHandling())
- {
- LOG.debug("handling {}", rule);
- baseRequest.setHandled(true);
- }
+ // Chain the rules.
+ input = output;
if (rule.isTerminating())
{
- LOG.debug("terminating {}", rule);
+ if (LOG.isDebugEnabled())
+ LOG.debug("terminating {}", rule);
break;
}
}
}
- return target;
+ return match ? input : null;
}
@Override
diff --git a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/TerminatingPatternRule.java b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/TerminatingPatternRule.java
index 86f3a8df19f..63b6aff20bf 100644
--- a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/TerminatingPatternRule.java
+++ b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/TerminatingPatternRule.java
@@ -15,38 +15,28 @@ package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.server.Request;
/**
- * If this rule matches, terminate the processing of other rules.
- * Allowing the request to be processed by the handlers after the rewrite rules.
+ *
If this rule matches, terminates the processing of other rules, allowing
+ * the request to be processed by the handlers after the {@link RewriteHandler}.
*/
public class TerminatingPatternRule extends PatternRule
{
- public TerminatingPatternRule()
- {
- this(null);
- }
-
public TerminatingPatternRule(String pattern)
{
super(pattern);
- super.setTerminating(true);
}
@Override
- public void setTerminating(boolean terminating)
+ public boolean isTerminating()
{
- if (!terminating)
- {
- throw new RuntimeException("Not allowed to disable terminating on a " + TerminatingPatternRule.class.getName());
- }
+ return true;
}
@Override
- protected String apply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected Request.WrapperProcessor apply(Request.WrapperProcessor input) throws IOException
{
- return target;
+ return input;
}
}
diff --git a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/TerminatingRegexRule.java b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/TerminatingRegexRule.java
index 044709cb140..9cbbc091bd8 100644
--- a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/TerminatingRegexRule.java
+++ b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/TerminatingRegexRule.java
@@ -16,8 +16,7 @@ package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
import java.util.regex.Matcher;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.annotation.Name;
/**
@@ -26,29 +25,20 @@ import org.eclipse.jetty.util.annotation.Name;
*/
public class TerminatingRegexRule extends RegexRule
{
- public TerminatingRegexRule()
- {
- this(null);
- }
-
public TerminatingRegexRule(@Name("regex") String regex)
{
super(regex);
- super.setTerminating(true);
}
@Override
- public void setTerminating(boolean terminating)
+ public boolean isTerminating()
{
- if (!terminating)
- {
- throw new RuntimeException("Not allowed to disable terminating on a " + TerminatingRegexRule.class.getName());
- }
+ return true;
}
@Override
- public String apply(String target, HttpServletRequest request, HttpServletResponse response, Matcher matcher) throws IOException
+ public Request.WrapperProcessor apply(Request.WrapperProcessor input, Matcher matcher) throws IOException
{
- return target;
+ return input;
}
}
diff --git a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainer.java b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainer.java
index 46222fe14b5..51b9f9afa1e 100644
--- a/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainer.java
+++ b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainer.java
@@ -14,94 +14,69 @@
package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.util.ArrayUtil;
+import org.eclipse.jetty.server.Request;
/**
- * Groups rules that apply only to a specific virtual host
- * or sets of virtual hosts
+ *
Groups rules that apply only to one or more specific virtual hosts.
*/
-
public class VirtualHostRuleContainer extends RuleContainer
{
- private String[] _virtualHosts;
+ private final List _virtualHosts = new ArrayList<>();
/**
- * Set the virtual hosts that the rules within this container will apply to
- *
- * @param virtualHosts Array of virtual hosts that the rules within this container are applied to.
- * A null hostname or null/empty array means any hostname is acceptable.
+ * @return the virtual hosts to match
*/
- public void setVirtualHosts(String[] virtualHosts)
- {
- if (virtualHosts == null)
- {
- _virtualHosts = virtualHosts;
- }
- else
- {
- _virtualHosts = new String[virtualHosts.length];
- for (int i = 0; i < virtualHosts.length; i++)
- {
- _virtualHosts[i] = normalizeHostname(virtualHosts[i]);
- }
- }
- }
-
- /**
- * Get the virtual hosts that the rules within this container will apply to
- *
- * @return Array of virtual hosts that the rules within this container are applied to.
- * A null hostname or null/empty array means any hostname is acceptable.
- */
- public String[] getVirtualHosts()
+ public List getVirtualHosts()
{
return _virtualHosts;
}
/**
- * @param virtualHost add a virtual host to the existing list of virtual hosts
- * A null hostname means any hostname is acceptable
+ *
Sets the virtual hosts to match for the rules within this container to be applied.
+ *
+ * @param virtualHosts the virtual hosts to match
*/
- public void addVirtualHost(String virtualHost)
+ public void setVirtualHosts(List virtualHosts)
{
- _virtualHosts = ArrayUtil.addToArray(_virtualHosts, virtualHost, String.class);
+ _virtualHosts.clear();
+ if (virtualHosts != null)
+ virtualHosts.forEach(this::addVirtualHost);
}
/**
- * Process the contained rules if the request is applicable to the virtual hosts of this rule
- *
- * @param target target field to pass on to the contained rules
- * @param request request object to pass on to the contained rules
- * @param response response object to pass on to the contained rules
+ * @param virtualHost the virtual host to add to the existing list of virtual hosts
*/
- @Override
- public String matchAndApply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException
+ public void addVirtualHost(String virtualHost)
{
- if (_virtualHosts != null && _virtualHosts.length > 0)
+ _virtualHosts.add(normalizeHostName(virtualHost));
+ }
+
+ @Override
+ public Request.WrapperProcessor matchAndApply(Request.WrapperProcessor input) throws IOException
+ {
+ if (_virtualHosts.isEmpty())
+ return super.matchAndApply(input);
+
+ String serverName = Request.getServerName(input);
+ for (String virtualHost : getVirtualHosts())
{
- String requestHost = normalizeHostname(request.getServerName());
- for (String ruleHost : _virtualHosts)
- {
- if (ruleHost == null ||
- ruleHost.equalsIgnoreCase(requestHost) ||
- (ruleHost.startsWith("*.") && ruleHost.regionMatches(true, 2, requestHost, requestHost.indexOf(".") + 1, ruleHost.length() - 2))
- )
- {
- return apply(target, request, response);
- }
- }
- }
- else
- {
- return apply(target, request, response);
+ if (virtualHost == null || virtualHost.equalsIgnoreCase(serverName))
+ return super.matchAndApply(input);
+
+ // Handle case-insensitive wildcard host names.
+ if (virtualHost.startsWith("*.") &&
+ virtualHost.regionMatches(true, 2, serverName, serverName.indexOf(".") + 1, virtualHost.length() - 2))
+ return super.matchAndApply(input);
}
+
+ // No virtual host match, skip the other rules.
return null;
}
- private String normalizeHostname(String host)
+ private String normalizeHostName(String host)
{
if (host == null)
return null;
diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/package-info.java b/jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/package-info.java
similarity index 100%
rename from jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/package-info.java
rename to jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/package-info.java
diff --git a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/AbstractRuleTest.java b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/AbstractRuleTest.java
new file mode 100644
index 00000000000..1c2c23872cc
--- /dev/null
+++ b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/AbstractRuleTest.java
@@ -0,0 +1,41 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.rewrite.handler;
+
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.LocalConnector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.component.LifeCycle;
+import org.junit.jupiter.api.AfterEach;
+
+public abstract class AbstractRuleTest
+{
+ protected Server _server = new Server();
+ protected LocalConnector _connector = new LocalConnector(_server);
+ protected RewriteHandler _rewriteHandler = new RewriteHandler();
+
+ @AfterEach
+ public void stop() throws Exception
+ {
+ LifeCycle.stop(_server);
+ }
+
+ protected void start(Handler handler) throws Exception
+ {
+ _server.addConnector(_connector);
+ _server.setHandler(_rewriteHandler);
+ _rewriteHandler.setHandler(handler);
+ _server.start();
+ }
+}
diff --git a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java
index fed5da7ce91..9d471ebd441 100644
--- a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java
+++ b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java
@@ -13,25 +13,16 @@
package org.eclipse.jetty.rewrite.handler;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringReader;
+import java.util.Arrays;
+import java.util.List;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-import org.eclipse.jetty.server.handler.HandlerList;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -40,71 +31,48 @@ import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.jupiter.api.Assertions.fail;
-public class CookiePatternRuleTest
+public class CookiePatternRuleTest extends AbstractRuleTest
{
- private Server server;
- private LocalConnector localConnector;
-
- public void startServer(CookiePatternRule rule) throws Exception
+ private void start(CookiePatternRule rule) throws Exception
{
- server = new Server();
- localConnector = new LocalConnector(server);
- server.addConnector(localConnector);
-
- RewriteHandler rewriteHandler = new RewriteHandler();
-// rewriteHandler.setRewriteRequestURI(false);
- rewriteHandler.addRule(rule);
-
- Handler dummyHandler = new AbstractHandler()
+ _rewriteHandler.addRule(rule);
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ public void process(Request request, Response response, Callback callback)
{
- response.setContentType("text/plain");
- response.setCharacterEncoding("utf-8");
- PrintWriter out = response.getWriter();
- out.printf("target=%s%n", target);
- out.printf("baseRequest.requestUri=%s%n", baseRequest.getRequestURI());
- out.printf("baseRequest.originalUri=%s%n", baseRequest.getOriginalURI());
- out.printf("request.requestUri=%s%n", request.getRequestURI());
- out.printf("request.queryString=%s%n", request.getQueryString());
- baseRequest.setHandled(true);
+ response.setContentType("text/plain;charset=utf-8");
+ response.write(false, Callback.NOOP, "pathInContext=%s%n".formatted(request.getPathInContext()));
+ response.write(false, Callback.NOOP, "path=%s%n".formatted(request.getHttpURI().getPath()));
+ response.write(false, Callback.NOOP, "query=%s%n".formatted(request.getHttpURI().getQuery()));
+ Request original = Request.unWrap(request);
+ response.write(false, Callback.NOOP, "originalPath=%s%n".formatted(original.getHttpURI().getPath()));
+ response.write(false, Callback.NOOP, "originalQuery=%s%n".formatted(original.getHttpURI().getQuery()));
+ callback.succeeded();
}
- };
-
- server.setHandler(new HandlerList(rewriteHandler, dummyHandler));
- server.start();
+ });
}
- @AfterEach
- public void stopServer() throws Exception
- {
- if (server != null)
- {
- server.stop();
- }
- }
-
- @BeforeEach
- public void init() throws Exception
+ @Test
+ public void testRule() throws Exception
{
CookiePatternRule rule = new CookiePatternRule();
rule.setPattern("*");
rule.setName("cookie");
rule.setValue("value");
- startServer(rule);
+ start(rule);
- StringBuilder rawRequest = new StringBuilder();
- rawRequest.append("GET / HTTP/1.1\r\n");
- rawRequest.append("Host: local\r\n");
- rawRequest.append("Connection: close\r\n");
- rawRequest.append("\r\n");
+ String rawRequest = """
+ GET / HTTP/1.1
+ Host: local
+ Connection: close
+
+ """;
- String rawResponse = localConnector.getResponse(rawRequest.toString());
+ String rawResponse = _connector.getResponse(rawRequest);
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
- // verify
HttpField setCookieField = response.getField(HttpHeader.SET_COOKIE);
assertThat("response should have Set-Cookie", setCookieField, notNullValue());
for (String value : setCookieField.getValues())
@@ -116,53 +84,54 @@ public class CookiePatternRuleTest
}
@Test
- public void testSetAlready() throws Exception
+ public void testCookieAlreadySet() throws Exception
{
CookiePatternRule rule = new CookiePatternRule();
rule.setPattern("*");
rule.setName("set");
rule.setValue("already");
- startServer(rule);
+ start(rule);
- StringBuilder rawRequest = new StringBuilder();
- rawRequest.append("GET / HTTP/1.1\r\n");
- rawRequest.append("Host: local\r\n");
- rawRequest.append("Connection: close\r\n");
- rawRequest.append("Cookie: set=already\r\n"); // already present on request
- rawRequest.append("\r\n");
+ // Cookie already present on the request.
+ String rawRequest = """
+ GET / HTTP/1.1
+ Host: local
+ Connection: close
+ Cookie: set=already
+
+ """;
- String rawResponse = localConnector.getResponse(rawRequest.toString());
+ String rawResponse = _connector.getResponse(rawRequest);
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
- // verify
assertThat("response should not have Set-Cookie", response.getField(HttpHeader.SET_COOKIE), nullValue());
}
@Test
- public void testUrlQuery() throws Exception
+ public void testPathQuery() throws Exception
{
CookiePatternRule rule = new CookiePatternRule();
rule.setPattern("*");
rule.setName("fruit");
rule.setValue("banana");
- startServer(rule);
+ start(rule);
- StringBuilder rawRequest = new StringBuilder();
- rawRequest.append("GET /other?fruit=apple HTTP/1.1\r\n");
- rawRequest.append("Host: local\r\n");
- rawRequest.append("Connection: close\r\n");
- rawRequest.append("\r\n");
+ String rawRequest = """
+ GET /other?fruit=apple HTTP/1.1
+ Host: local
+ Connection: close
+
+ """;
- String rawResponse = localConnector.getResponse(rawRequest.toString());
+ String rawResponse = _connector.getResponse(rawRequest);
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
String responseContent = response.getContent();
- assertResponseContentLine(responseContent, "baseRequest.requestUri=", "/other");
- assertResponseContentLine(responseContent, "request.queryString=", "fruit=apple");
+ assertResponseContentLine(responseContent, "path=", "/other");
+ assertResponseContentLine(responseContent, "query=", "fruit=apple");
- // verify
HttpField setCookieField = response.getField(HttpHeader.SET_COOKIE);
assertThat("response should have Set-Cookie", setCookieField, notNullValue());
for (String value : setCookieField.getValues())
@@ -174,28 +143,28 @@ public class CookiePatternRuleTest
}
@Test
- public void testUrlParameter() throws Exception
+ public void testPathParameter() throws Exception
{
CookiePatternRule rule = new CookiePatternRule();
rule.setPattern("*");
rule.setName("fruit");
rule.setValue("banana");
- startServer(rule);
+ start(rule);
- StringBuilder rawRequest = new StringBuilder();
- rawRequest.append("GET /other;fruit=apple HTTP/1.1\r\n");
- rawRequest.append("Host: local\r\n");
- rawRequest.append("Connection: close\r\n");
- rawRequest.append("\r\n");
+ String rawRequest = """
+ GET /other;fruit=apple HTTP/1.1
+ Host: local
+ Connection: close
+
+ """;
- String rawResponse = localConnector.getResponse(rawRequest.toString());
+ String rawResponse = _connector.getResponse(rawRequest);
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
String responseContent = response.getContent();
- assertResponseContentLine(responseContent, "baseRequest.requestUri=", "/other;fruit=apple");
+ assertResponseContentLine(responseContent, "path=", "/other;fruit=apple");
- // verify
HttpField setCookieField = response.getField(HttpHeader.SET_COOKIE);
assertThat("response should have Set-Cookie", setCookieField, notNullValue());
for (String value : setCookieField.getValues())
@@ -206,33 +175,17 @@ public class CookiePatternRuleTest
}
}
- private void assertResponseContentLine(String responseContent, String linePrefix, String expectedEquals) throws IOException
+ private void assertResponseContentLine(String responseContent, String linePrefix, String expectedEquals)
{
- String line;
- try (StringReader stringReader = new StringReader(responseContent);
- BufferedReader bufferedReader = new BufferedReader(stringReader))
- {
- boolean foundIt = false;
- while ((line = bufferedReader.readLine()) != null)
- {
- if (line.startsWith(linePrefix))
- {
- if (foundIt)
- {
- // duplicate lines
- fail("Found multiple lines prefixed with: " + linePrefix);
- }
- // found it
- String actualValue = line.substring(linePrefix.length());
- assertThat("Line:" + linePrefix, actualValue, is(expectedEquals));
- foundIt = true;
- }
- }
+ List matches = Arrays.stream(responseContent.split("\n"))
+ .filter(line -> line.startsWith(linePrefix))
+ .map(line -> line.substring(linePrefix.length()))
+ .filter(line -> line.equals(expectedEquals))
+ .toList();
- if (!foundIt)
- {
- fail("Unable to find line prefixed with: " + linePrefix);
- }
- }
+ if (matches.size() == 0)
+ fail("Unable to find line prefixed with: " + linePrefix);
+ if (matches.size() > 1)
+ fail("Found multiple lines prefixed with: " + linePrefix);
}
}
diff --git a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ForceRequestHeaderValueRuleTest.java b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ForceRequestHeaderValueRuleTest.java
index 5aff2292246..9aee152d520 100644
--- a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ForceRequestHeaderValueRuleTest.java
+++ b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ForceRequestHeaderValueRuleTest.java
@@ -13,24 +13,13 @@
package org.eclipse.jetty.rewrite.handler;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.util.Collections;
-
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-import org.eclipse.jetty.server.handler.HandlerList;
-import org.eclipse.jetty.util.component.LifeCycle;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.BufferUtil;
+import org.eclipse.jetty.util.Callback;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -38,91 +27,65 @@ import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertEquals;
-public class ForceRequestHeaderValueRuleTest
+public class ForceRequestHeaderValueRuleTest extends AbstractRuleTest
{
- private Server server;
- private LocalConnector connector;
- private ForceRequestHeaderValueRule rule;
-
- @BeforeEach
- public void setup() throws Exception
+ public void start(ForceRequestHeaderValueRule rule) throws Exception
{
- server = new Server();
- connector = new LocalConnector(server);
- server.addConnector(connector);
-
- HandlerList handlers = new HandlerList();
-
- RewriteHandler rewriteHandler = new RewriteHandler();
- rule = new ForceRequestHeaderValueRule();
- rewriteHandler.addRule(rule);
-
- Handler handler = new AbstractHandler()
+ _rewriteHandler.addRule(rule);
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ public void process(Request request, Response response, Callback callback)
{
- response.setContentType("text/plain");
- response.setCharacterEncoding("utf-8");
- OutputStream stream = response.getOutputStream();
- OutputStreamWriter out = new OutputStreamWriter(stream);
- out.append("Echo\n");
- for (String headerName : Collections.list(request.getHeaderNames()))
+ response.setContentType("text/plain;charset=utf-8");
+ for (HttpField httpField : request.getHeaders())
{
- // Combine all values for header into single output on response body
- out.append("Request Header[").append(headerName).append("]: [")
- .append(request.getHeader(headerName)).append("]\n");
+ response.write(false, Callback.NOOP, "Request Header[%s]: [%s]%n".formatted(httpField.getName(), httpField.getValue()));
}
- out.flush();
- baseRequest.setHandled(true);
+ response.write(true, callback, BufferUtil.EMPTY_BUFFER);
}
- };
-
- handlers.addHandler(rewriteHandler);
- handlers.addHandler(handler);
- server.setHandler(handlers);
- server.start();
- }
-
- @AfterEach
- public void teardown()
- {
- LifeCycle.stop(server);
+ });
}
@Test
public void testNormalRequest() throws Exception
{
+ ForceRequestHeaderValueRule rule = new ForceRequestHeaderValueRule();
rule.setHeaderName("Accept");
- rule.setForcedValue("*/*");
+ rule.setHeaderValue("*/*");
+ start(rule);
- StringBuilder request = new StringBuilder();
- request.append("GET /echo/foo HTTP/1.1\r\n");
- request.append("Host: local\r\n");
- request.append("Connection: closed\r\n");
- request.append("\r\n");
+ String request = """
+ GET /echo/foo HTTP/1.1
+ Host: local
+ Connection: close
+
+ """;
- HttpTester.Response response = HttpTester.parseResponse(connector.getResponse(request.toString()));
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
assertEquals(200, response.getStatus());
assertThat(response.getContent(), not(containsString("[Accept]")));
assertThat(response.getContent(), containsString("[Host]: [local]"));
- assertThat(response.getContent(), containsString("[Connection]: [closed]"));
+ assertThat(response.getContent(), containsString("[Connection]: [close]"));
}
@Test
public void testOneAcceptHeaderRequest() throws Exception
{
+ ForceRequestHeaderValueRule rule = new ForceRequestHeaderValueRule();
rule.setHeaderName("Accept");
- rule.setForcedValue("*/*");
+ rule.setHeaderValue("*/*");
+ start(rule);
- StringBuilder request = new StringBuilder();
- request.append("GET /echo/foo HTTP/1.1\r\n");
- request.append("Host: local\r\n");
- request.append("Accept: */*\r\n");
- request.append("Connection: closed\r\n");
- request.append("\r\n");
+ String request = """
+ GET /echo/foo HTTP/1.1
+ Host: local
+ Accept: */*
+ Connection: closed
+
+ """;
- String rawResponse = connector.getResponse(request.toString());
+ String rawResponse = _connector.getResponse(request);
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
assertEquals(200, response.getStatus());
assertThat(response.getContent(), containsString("[Accept]: [*/*]"));
@@ -133,19 +96,22 @@ public class ForceRequestHeaderValueRuleTest
@Test
public void testThreeAcceptHeadersRequest() throws Exception
{
+ ForceRequestHeaderValueRule rule = new ForceRequestHeaderValueRule();
rule.setHeaderName("Accept");
- rule.setForcedValue("text/*");
+ rule.setHeaderValue("text/*");
+ start(rule);
- StringBuilder request = new StringBuilder();
- request.append("GET /echo/foo HTTP/1.1\r\n");
- request.append("Host: local\r\n");
- request.append("Accept: images/jpeg\r\n");
- request.append("Accept: text/plain\r\n");
- request.append("Accept: */*\r\n");
- request.append("Connection: closed\r\n");
- request.append("\r\n");
+ String request = """
+ GET /echo/foo HTTP/1.1
+ Host: local
+ Accept: images/jpeg
+ Accept: text/plain
+ Accept: */*
+ Connection: closed
+
+ """;
- String rawResponse = connector.getResponse(request.toString());
+ String rawResponse = _connector.getResponse(request);
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
assertEquals(200, response.getStatus());
assertThat(response.getContent(), containsString("[Accept]: [text/*]"));
@@ -156,21 +122,24 @@ public class ForceRequestHeaderValueRuleTest
@Test
public void testInterleavedAcceptHeadersRequest() throws Exception
{
+ ForceRequestHeaderValueRule rule = new ForceRequestHeaderValueRule();
rule.setHeaderName("Accept");
- rule.setForcedValue("application/*");
+ rule.setHeaderValue("application/*");
+ start(rule);
- StringBuilder request = new StringBuilder();
- request.append("GET /echo/foo HTTP/1.1\r\n");
- request.append("Host: local\r\n");
- request.append("Accept: images/jpeg\r\n"); // not value intended to be forced
- request.append("Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0\r\n");
- request.append("accept: text/plain\r\n"); // interleaved with other headers shouldn't matter
- request.append("Accept-Charset: iso-8859-5, unicode-1-1;q=0.8\r\n");
- request.append("ACCEPT: */*\r\n"); // case shouldn't matter
- request.append("Connection: closed\r\n");
- request.append("\r\n");
+ String request = """
+ GET /echo/foo HTTP/1.1
+ Host: local
+ Accept: images/jpeg
+ Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0
+ accept: text/plain
+ Accept-Charset: iso-8859-5, unicode-1-1;q=0.8
+ ACCEPT: */*
+ Connection: closed
+
+ """;
- String rawResponse = connector.getResponse(request.toString());
+ String rawResponse = _connector.getResponse(request);
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
assertEquals(200, response.getStatus());
assertThat(response.getContent(), containsString("[Accept]: [application/*]"));
diff --git a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRuleTest.java b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRuleTest.java
index 12c3ee0ea22..c4fb6bc2f3d 100644
--- a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRuleTest.java
+++ b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRuleTest.java
@@ -13,76 +13,117 @@
package org.eclipse.jetty.rewrite.handler;
-import org.eclipse.jetty.http.HttpFields;
-import org.eclipse.jetty.http.HttpURI;
-import org.junit.jupiter.api.BeforeEach;
+import org.eclipse.jetty.http.HttpTester;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
-public class ForwardedSchemeHeaderRuleTest extends AbstractRuleTestCase
+public class ForwardedSchemeHeaderRuleTest extends AbstractRuleTest
{
- private ForwardedSchemeHeaderRule _rule;
-
- @BeforeEach
- public void init() throws Exception
+ public void start(ForwardedSchemeHeaderRule rule) throws Exception
{
- start(false);
- _rule = new ForwardedSchemeHeaderRule();
- _request.setHttpURI(HttpURI.build(_request.getRequestURI()).scheme((String)null));
+ _rewriteHandler.addRule(rule);
+ start(new Handler.Processor()
+ {
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ response.setHeader("request-scheme", request.getHttpURI().getScheme());
+ callback.succeeded();
+ }
+ });
}
@Test
public void testDefaultScheme() throws Exception
{
- setRequestHeader("X-Forwarded-Scheme", "https");
- _rule.setHeader("X-Forwarded-Scheme");
- _rule.setHeaderValue("https");
- _rule.matchAndApply("/", _request, _response);
- assertEquals("https", _request.getScheme());
+ ForwardedSchemeHeaderRule rule = new ForwardedSchemeHeaderRule();
+ rule.setHeaderName("X-Forwarded-Scheme");
+ rule.setHeaderValue("https");
+ start(rule);
+
+ String request = """
+ GET / HTTP/1.1
+ Host: local
+ X-Forwarded-Scheme: https
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(200, response.getStatus());
+ assertEquals("https", response.get("request-scheme"));
}
@Test
public void testScheme() throws Exception
{
- setRequestHeader("X-Forwarded-Scheme", "https");
- _rule.setHeader("X-Forwarded-Scheme");
- _rule.setHeaderValue("https");
- _rule.setScheme("https");
- _rule.matchAndApply("/", _request, _response);
- assertEquals("https", _request.getScheme());
+ ForwardedSchemeHeaderRule rule = new ForwardedSchemeHeaderRule();
+ rule.setHeaderName("X-Forwarded-Scheme");
+ rule.setHeaderValue("https");
+ rule.setScheme("wss");
+ start(rule);
- _rule.setScheme("http");
- _rule.matchAndApply("/", _request, _response);
- assertEquals("http", _request.getScheme());
+ String request = """
+ GET / HTTP/1.1
+ Host: local
+ X-Forwarded-Scheme: https
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(200, response.getStatus());
+ assertEquals("wss", response.get("request-scheme"));
}
@Test
public void testHeaderValue() throws Exception
{
- setRequestHeader("Front-End-Https", "on");
- _rule.setHeader("Front-End-Https");
- _rule.setHeaderValue("on");
- _rule.setScheme("https");
- _rule.matchAndApply("/", _request, _response);
- assertEquals("https", _request.getScheme());
+ ForwardedSchemeHeaderRule rule = new ForwardedSchemeHeaderRule();
+ rule.setHeaderName("Front-End-Https");
+ rule.setHeaderValue("on");
+ rule.setScheme("http");
+ start(rule);
- _request.setHttpURI(HttpURI.build(_request.getRequestURI()).scheme("other"));
- // header value doesn't match rule's value
- setRequestHeader("Front-End-Https", "off");
- _rule.matchAndApply("/", _request, _response);
- assertEquals("other", _request.getScheme());
+ String request = """
+ GET / HTTP/1.1
+ Host: local
+ Front-End-Https: on
+
+ """;
- _request.setHttpURI(HttpURI.build(_request.getRequestURI()).scheme((String)null));
- // header value can be any value
- setRequestHeader("Front-End-Https", "any");
- _rule.setHeaderValue(null);
- _rule.matchAndApply("/", _request, _response);
- assertEquals("https", _request.getScheme());
- }
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(200, response.getStatus());
+ assertEquals("http", response.get("request-scheme"));
- private void setRequestHeader(String header, String headerValue)
- {
- _request.setHttpFields(HttpFields.build(_request.getHttpFields()).put(header, headerValue));
+ // Value does not match, scheme is retained.
+ rule.setScheme("other");
+ request = """
+ GET other://local/ HTTP/1.1
+ Host: local
+ Front-End-Https: off
+
+ """;
+
+ response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(200, response.getStatus());
+ assertEquals("other", response.get("request-scheme"));
+
+ rule.setScheme("ws");
+ // Null value should match.
+ rule.setHeaderValue(null);
+ request = """
+ GET / HTTP/1.1
+ Host: local
+ Front-End-Https: any
+
+ """;
+
+ response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(200, response.getStatus());
+ assertEquals("ws", response.get("request-scheme"));
}
}
diff --git a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRuleTest.java b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRuleTest.java
index a107ec70a90..7539d183337 100644
--- a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRuleTest.java
+++ b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRuleTest.java
@@ -13,98 +13,73 @@
package org.eclipse.jetty.rewrite.handler;
-import java.io.IOException;
-import java.util.Iterator;
+import java.util.List;
-import org.junit.jupiter.api.BeforeEach;
+import org.eclipse.jetty.http.HttpTester;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
-public class HeaderPatternRuleTest extends AbstractRuleTestCase
+public class HeaderPatternRuleTest extends AbstractRuleTest
{
- private HeaderPatternRule _rule;
-
- @BeforeEach
- public void init() throws Exception
+ private void start(HeaderPatternRule rule) throws Exception
{
- start(false);
- _rule = new HeaderPatternRule();
- _rule.setPattern("*");
- }
-
- @Test
- public void testHeaderWithTextValues() throws IOException
- {
- // different keys
- String[][] headers = {
- {"hnum#1", "test1"},
- {"hnum#2", "2test2"},
- {"hnum#3", "test3"}
- };
- assertHeaders(headers);
- }
-
- @Test
- public void testHeaderWithNumberValues() throws IOException
- {
- String[][] headers = {
- {"hello", "1"},
- {"hello", "-1"},
- {"hello", "100"},
- {"hello", "100"},
- {"hello", "100"},
- {"hello", "100"},
- {"hello", "100"},
-
- {"hello1", "200"}
- };
- assertHeaders(headers);
- }
-
- @Test
- public void testHeaderOverwriteValues() throws IOException
- {
- String[][] headers = {
- {"size", "100"},
- {"size", "200"},
- {"size", "300"},
- {"size", "400"},
- {"size", "500"},
- {"title", "abc"},
- {"title", "bac"},
- {"title", "cba"},
- {"title1", "abba"},
- {"title1", "abba1"},
- {"title1", "abba"},
- {"title1", "abba1"}
- };
- assertHeaders(headers);
-
- Iterator e = _response.getHeaders("size").iterator();
- int count = 0;
- while (e.hasNext())
+ _rewriteHandler.addRule(rule);
+ start(new Handler.Processor()
{
- e.next();
- count++;
- }
-
- assertEquals(1, count);
- assertEquals("500", _response.getHeader("size"));
- assertEquals("cba", _response.getHeader("title"));
- assertEquals("abba1", _response.getHeader("title1"));
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
}
- private void assertHeaders(String[][] headers) throws IOException
+ @Test
+ public void testHeaderWithTextValue() throws Exception
{
- for (String[] header : headers)
+ String name = "X-Response";
+ String value = "TEXT";
+ HeaderPatternRule rule = new HeaderPatternRule("/", name, value);
+ start(rule);
+
+ String request = """
+ GET / HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(200, response.getStatus());
+ assertEquals(value, response.get(name));
+ }
+
+ @Test
+ public void testHeaderWithNumberValues() throws Exception
+ {
+ String name = "X-Response";
+ List values = List.of("1", "-1", "100");
+
+ for (String value : values)
{
- _rule.setName(header[0]);
- _rule.setValue(header[1]);
+ HeaderPatternRule rule = new HeaderPatternRule("/", name, value);
+ start(rule);
- _rule.apply(null, _request, _response);
+ String request = """
+ GET / HTTP/1.1
+ Host: localhost
+
+ """;
- assertEquals(header[1], _response.getHeader(header[0]));
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(200, response.getStatus());
+ assertEquals(value, response.get(name));
+
+ stop();
}
}
}
diff --git a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderRegexRuleTest.java b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderRegexRuleTest.java
index cf0178a0c32..6c7a1f8d807 100644
--- a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderRegexRuleTest.java
+++ b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderRegexRuleTest.java
@@ -13,118 +13,112 @@
package org.eclipse.jetty.rewrite.handler;
-import java.io.IOException;
-import java.util.Iterator;
+import java.util.List;
-import org.junit.jupiter.api.BeforeEach;
+import org.eclipse.jetty.http.HttpTester;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
-public class HeaderRegexRuleTest extends AbstractRuleTestCase
+public class HeaderRegexRuleTest extends AbstractRuleTest
{
-
- private HeaderRegexRule _rule;
-
- @BeforeEach
- public void init() throws Exception
+ private void start(HeaderRegexRule rule) throws Exception
{
- start(false);
- _rule = new HeaderRegexRule();
- _rule.setRegex("\\*");
- }
-
- @Test
- public void testHeaderWithTextValues() throws IOException
- {
- // different keys
- String[][] headers =
- {
- {"hnum#1", "test1"},
- {"hnum#2", "2test2"},
- {"hnum#3", "test3"}
- };
- assertHeaders(headers);
- }
-
- @Test
- public void testHeaderWithNumberValues() throws IOException
- {
- String[][] headers =
- {
- {"hello", "1"},
- {"hello", "-1"},
- {"hello", "100"},
- {"hello", "100"},
- {"hello", "100"},
- {"hello", "100"},
- {"hello", "100"},
- {"hello1", "200"}
- };
- assertHeaders(headers);
- }
-
- @Test
- public void testHeaderOverwriteValues() throws IOException
- {
- String[][] headers =
- {
- {"size", "100"},
- {"size", "200"},
- {"size", "300"},
- {"size", "400"},
- {"size", "500"},
- {"title", "abc"},
- {"title", "bac"},
- {"title", "cba"},
- {"title1", "abba"},
- {"title1", "abba1"},
- {"title1", "abba"},
- {"title1", "abba1"}
- };
- assertHeaders(headers);
- Iterator e = _response.getHeaders("size").iterator();
- int count = 0;
- while (e.hasNext())
+ _rewriteHandler.addRule(rule);
+ start(new Handler.Processor()
{
- e.next();
- count++;
- }
- assertEquals(1, count);
- assertEquals("500", _response.getHeader("size"));
- assertEquals("cba", _response.getHeader("title"));
- assertEquals("abba1", _response.getHeader("title1"));
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
}
@Test
- public void testMatch() throws Exception
+ public void testHeaderWithTextValue() throws Exception
{
- _rule.setRegex("/my/dir/file/(.*)$");
- _rule.setName("cache-control");
- _rule.setValue("no-store");
- _rule.matchAndApply("/my/dir/file/", _request, _response);
- assertEquals("no-store", _response.getHeader("cache-control"));
+ String name = "X-Response";
+ String value = "TEXT";
+ HeaderRegexRule rule = new HeaderRegexRule("/", name, value);
+ start(rule);
+
+ String request = """
+ GET / HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(200, response.getStatus());
+ assertEquals(value, response.get(name));
}
@Test
- public void testNotMatch() throws Exception
+ public void testHeaderWithNumberValues() throws Exception
{
- reset();
- _rule.setRegex("/my/dir/file/(.*)$");
- _rule.setName("cache-control");
- _rule.setValue("no-store");
- _rule.matchAndApply("/my/dir/file_not_match/", _request, _response);
- assertEquals(null, _response.getHeader("cache-control"));
- }
+ String name = "X-Response";
+ List values = List.of("1", "-1", "100");
- private void assertHeaders(String[][] headers) throws IOException
- {
- for (String[] header : headers)
+ for (String value : values)
{
- _rule.setName(header[0]);
- _rule.setValue(header[1]);
- _rule.apply(null, _request, _response, null);
- assertEquals(header[1], _response.getHeader(header[0]));
+ HeaderRegexRule rule = new HeaderRegexRule("/", name, value);
+ start(rule);
+
+ String request = """
+ GET / HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(200, response.getStatus());
+ assertEquals(value, response.get(name));
+
+ stop();
}
}
+
+ @Test
+ public void testMatchWithGroup() throws Exception
+ {
+ String name = "X-Response";
+ String value = "TEXT";
+ HeaderRegexRule rule = new HeaderRegexRule("/my/dir/([^/]+)", name, "$1");
+ start(rule);
+
+ String request = """
+ GET /my/dir/$V HTTP/1.1
+ Host: localhost
+
+ """.replace("$V", value);
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(200, response.getStatus());
+ assertEquals(value, response.get(name));
+ }
+
+ @Test
+ public void testNoMatch() throws Exception
+ {
+ String name = "X-Response";
+ String value = "TEXT";
+ HeaderRegexRule rule = new HeaderRegexRule("/my/dir/([^/]+)", name, "$1");
+ start(rule);
+
+ String request = """
+ GET /my/no/match HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(200, response.getStatus());
+ assertNull(response.get(name));
+ }
}
diff --git a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/InvalidURIRuleTest.java b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/InvalidURIRuleTest.java
new file mode 100644
index 00000000000..0445c963d73
--- /dev/null
+++ b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/InvalidURIRuleTest.java
@@ -0,0 +1,254 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.rewrite.handler;
+
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.HttpTester;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class InvalidURIRuleTest extends AbstractRuleTest
+{
+ private void start(InvalidURIRule rule) throws Exception
+ {
+ _rewriteHandler.addRule(rule);
+ start(new Handler.Processor()
+ {
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
+ }
+
+ @Test
+ public void testValidUrl() throws Exception
+ {
+ InvalidURIRule rule = new InvalidURIRule();
+ rule.setCode(HttpStatus.NOT_ACCEPTABLE_406);
+ start(rule);
+
+ String request = """
+ GET /valid/uri.html HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ }
+
+ @Test
+ public void testInvalidUrl() throws Exception
+ {
+ InvalidURIRule rule = new InvalidURIRule();
+ rule.setCode(HttpStatus.NOT_ACCEPTABLE_406);
+ start(rule);
+
+ String request = """
+ GET /invalid%0c/uri.html HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.NOT_ACCEPTABLE_406, response.getStatus());
+ }
+
+ @Test
+ public void testInvalidUrlWithMessage() throws Exception
+ {
+ InvalidURIRule rule = new InvalidURIRule();
+ rule.setCode(HttpStatus.NOT_ACCEPTABLE_406);
+ rule.setMessage("foo");
+ start(rule);
+
+ String request = """
+ GET /%01/ HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.NOT_ACCEPTABLE_406, response.getStatus());
+ assertThat(response.getContent(), containsString(rule.getMessage()));
+ }
+
+ @Test
+ public void testInvalidJspWithNullByteEncoded() throws Exception
+ {
+ InvalidURIRule rule = new InvalidURIRule();
+ rule.setCode(HttpStatus.NOT_ACCEPTABLE_406);
+ start(rule);
+
+ String request = """
+ GET /jsp/bean1.jsp%00 HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ // The rule is not invoked because byte NULL is rejected at parsing level.
+ assertEquals(HttpStatus.BAD_REQUEST_400, response.getStatus());
+ }
+
+ @Test
+ public void testInvalidJspWithControlByteEncoded() throws Exception
+ {
+ InvalidURIRule rule = new InvalidURIRule();
+ rule.setCode(HttpStatus.NOT_ACCEPTABLE_406);
+ start(rule);
+
+ String request = """
+ GET /jsp/bean1.jsp%01 HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.NOT_ACCEPTABLE_406, response.getStatus());
+ }
+
+ @Test
+ public void testInvalidJspWithNullByte() throws Exception
+ {
+ InvalidURIRule rule = new InvalidURIRule();
+ rule.setCode(HttpStatus.NOT_ACCEPTABLE_406);
+ start(rule);
+
+ String request = """
+ GET /jsp/bean1.jsp\000 HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ // The rule is not invoked because byte NULL is rejected at parsing level.
+ assertEquals(HttpStatus.BAD_REQUEST_400, response.getStatus());
+ }
+
+ @Test
+ public void testInvalidJspWithControlByte() throws Exception
+ {
+ InvalidURIRule rule = new InvalidURIRule();
+ rule.setCode(HttpStatus.NOT_ACCEPTABLE_406);
+ start(rule);
+
+ String request = """
+ GET /jsp/bean1.jsp\001 HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ // The rule is not invoked because byte CNTL bytes are rejected at parsing level.
+ assertEquals(HttpStatus.BAD_REQUEST_400, response.getStatus());
+ }
+
+ @Test
+ public void testInvalidShamrockWithNullByte() throws Exception
+ {
+ InvalidURIRule rule = new InvalidURIRule();
+ rule.setCode(HttpStatus.NOT_ACCEPTABLE_406);
+ start(rule);
+
+ String request = """
+ GET /jsp/shamrock-%00%E2%98%98.jsp HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ // The rule is not invoked because byte NULL is rejected at parsing level.
+ assertEquals(HttpStatus.BAD_REQUEST_400, response.getStatus());
+ }
+
+ @Test
+ public void testInvalidShamrockWithControlByteEncoded() throws Exception
+ {
+ InvalidURIRule rule = new InvalidURIRule();
+ rule.setCode(HttpStatus.NOT_ACCEPTABLE_406);
+ start(rule);
+
+ String request = """
+ GET /jsp/shamrock-%0F%E2%98%98.jsp HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.NOT_ACCEPTABLE_406, response.getStatus());
+ }
+
+ @Test
+ public void testValidShamrock() throws Exception
+ {
+ InvalidURIRule rule = new InvalidURIRule();
+ rule.setCode(HttpStatus.NOT_ACCEPTABLE_406);
+ start(rule);
+
+ String request = """
+ GET /jsp/shamrock-%E2%98%98.jsp HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ }
+
+ @Test
+ public void testInvalidUTF8() throws Exception
+ {
+ InvalidURIRule rule = new InvalidURIRule();
+ rule.setCode(HttpStatus.NOT_ACCEPTABLE_406);
+ start(rule);
+
+ String request = """
+ GET /jsp/shamrock-%A0%A1.jsp HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ // The rule is not invoked because the UTF-8 sequence is invalid.
+ assertEquals(HttpStatus.BAD_REQUEST_400, response.getStatus());
+ }
+
+ @Test
+ public void testIncompleteUTF8() throws Exception
+ {
+ InvalidURIRule rule = new InvalidURIRule();
+ rule.setCode(HttpStatus.NOT_ACCEPTABLE_406);
+ start(rule);
+
+ String request = """
+ GET /foo%CE%BA%E1 HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ // The rule is not invoked because the UTF-8 sequence is incomplete.
+ assertEquals(HttpStatus.BAD_REQUEST_400, response.getStatus());
+ }
+}
diff --git a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/PatternRuleTest.java b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/PatternRuleTest.java
index 7b225df60f0..f44b680da8f 100644
--- a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/PatternRuleTest.java
+++ b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/PatternRuleTest.java
@@ -13,144 +13,154 @@
package org.eclipse.jetty.rewrite.handler;
-import java.io.IOException;
+import java.util.stream.Stream;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.http.HttpFields;
-import org.eclipse.jetty.http.HttpURI;
-import org.eclipse.jetty.http.HttpVersion;
-import org.eclipse.jetty.http.MetaData;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.HttpTester;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
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 PatternRuleTest
+public class PatternRuleTest extends AbstractRuleTest
{
- private PatternRule _rule;
-
- @BeforeEach
- public void init()
+ public static Stream matches()
{
- _rule = new TestPatternRule();
- }
+ return Stream.of(
+ Arguments.of("/abc", "/abc"),
+ Arguments.of("/abc/", "/abc/"),
- @AfterEach
- public void destroy()
- {
- _rule = null;
- }
+ Arguments.of("/abc/path/longer", "/abc/path/longer"),
+ Arguments.of("/abc/path/longer/", "/abc/path/longer/"),
- @Test
- public void testTrueMatch() throws IOException
- {
- String[][] matchCases = {
- // index 0 - pattern
- // index 1 - URI to match
+ Arguments.of("/abc/*", "/abc/hello.jsp"),
+ Arguments.of("/abc/*", "/abc/a"),
+ Arguments.of("/abc/*", "/abc/a/hello.jsp"),
+ Arguments.of("/abc/*", "/abc/a/b"),
+ Arguments.of("/abc/*", "/abc/a/b/hello.jsp"),
+ Arguments.of("/abc/*", "/abc/a/b/c"),
+ Arguments.of("/abc/*", "/abc/a/b/c/hello.jsp"),
- {"/abc", "/abc"},
- {"/abc/", "/abc/"},
+ Arguments.of("/abc/def/*", "/abc/def/gf"),
+ Arguments.of("/abc/def/*", "/abc/def/gf.html"),
+ Arguments.of("/abc/def/*", "/abc/def/ghi"),
+ Arguments.of("/abc/def/*", "/abc/def/ghi/"),
+ Arguments.of("/abc/def/*", "/abc/def/ghi/hello.html"),
- {"/abc/path/longer", "/abc/path/longer"},
- {"/abc/path/longer/", "/abc/path/longer/"},
+ Arguments.of("*.do", "/abc.do"),
+ Arguments.of("*.do", "/abc/hello.do"),
+ Arguments.of("*.do", "/abc/def/hello.do"),
+ Arguments.of("*.do", "/abc/def/ghi/hello.do"),
- {"/abc/*", "/abc/hello.jsp"},
- {"/abc/*", "/abc/a"},
- {"/abc/*", "/abc/a/hello.jsp"},
- {"/abc/*", "/abc/a/b"},
- {"/abc/*", "/abc/a/b/hello.jsp"},
- {"/abc/*", "/abc/a/b/c"},
- {"/abc/*", "/abc/a/b/c/hello.jsp"},
+ Arguments.of("*.jsp", "/abc.jsp"),
+ Arguments.of("*.jsp", "/abc/hello.jsp"),
+ Arguments.of("*.jsp", "/abc/def/hello.jsp"),
+ Arguments.of("*.jsp", "/abc/def/ghi/hello.jsp"),
- {"/abc/def/*", "/abc/def/gf"},
- {"/abc/def/*", "/abc/def/gf.html"},
- {"/abc/def/*", "/abc/def/ghi"},
- {"/abc/def/*", "/abc/def/ghi/"},
- {"/abc/def/*", "/abc/def/ghi/hello.html"},
+ Arguments.of("/", "/Other"),
+ Arguments.of("/", "/Other/hello.do"),
+ Arguments.of("/", "/Other/path"),
+ Arguments.of("/", "/Other/path/hello.do"),
+ Arguments.of("/", "/abc/def"),
- {"*.do", "/abc.do"},
- {"*.do", "/abc/hello.do"},
- {"*.do", "/abc/def/hello.do"},
- {"*.do", "/abc/def/ghi/hello.do"},
-
- {"*.jsp", "/abc.jsp"},
- {"*.jsp", "/abc/hello.jsp"},
- {"*.jsp", "/abc/def/hello.jsp"},
- {"*.jsp", "/abc/def/ghi/hello.jsp"},
-
- {"/", "/Other"},
- {"/", "/Other/hello.do"},
- {"/", "/Other/path"},
- {"/", "/Other/path/hello.do"},
- {"/", "/abc/def"},
-
- {"/abc:/def", "/abc:/def"}
- };
-
- for (String[] matchCase : matchCases)
- {
- assertMatch(true, matchCase);
- }
- }
-
- @Test
- public void testFalseMatch() throws IOException
- {
- String[][] matchCases = {
-
- {"/abc", "/abcd"},
- {"/abc/", "/abcd/"},
-
- {"/abc/path/longer", "/abc/path/longer/"},
- {"/abc/path/longer", "/abc/path/longer1"},
- {"/abc/path/longer/", "/abc/path/longer"},
- {"/abc/path/longer/", "/abc/path/longer1/"},
-
- {"/*.jsp", "/hello.jsp"},
- {"/abc/*.jsp", "/abc/hello.jsp"},
-
- {"*.jsp", "/hello.1jsp"},
- {"*.jsp", "/hello.jsp1"},
- {"*.jsp", "/hello.do"},
-
- {"*.jsp", "/abc/hello.do"},
- {"*.jsp", "/abc/def/hello.do"},
- {"*.jsp", "/abc.do"}
- };
-
- for (String[] matchCase : matchCases)
- {
- assertMatch(false, matchCase);
- }
- }
-
- private void assertMatch(boolean flag, String[] matchCase) throws IOException
- {
- _rule.setPattern(matchCase[0]);
- final String uri = matchCase[1];
-
- String result = _rule.matchAndApply(uri,
- new Request(null, null)
- {
- {
- setMetaData(new MetaData.Request("GET", HttpURI.from(uri), HttpVersion.HTTP_1_0, HttpFields.EMPTY));
- }
- }, null
+ Arguments.of("/abc:/def", "/abc:/def")
);
-
- assertEquals(flag, result != null, "pattern: " + matchCase[0] + " uri: " + matchCase[1]);
}
- private class TestPatternRule extends PatternRule
+ public static Stream noMatches()
{
- @Override
- public String apply(String target,
- HttpServletRequest request, HttpServletResponse response) throws IOException
+ return Stream.of(
+ Arguments.of("/abc", "/abcd"),
+ Arguments.of("/abc/", "/abcd/"),
+
+ Arguments.of("/abc/path/longer", "/abc/path/longer/"),
+ Arguments.of("/abc/path/longer", "/abc/path/longer1"),
+ Arguments.of("/abc/path/longer/", "/abc/path/longer"),
+ Arguments.of("/abc/path/longer/", "/abc/path/longer1/"),
+
+ Arguments.of("/*.jsp", "/hello.jsp"),
+ Arguments.of("/abc/*.jsp", "/abc/hello.jsp"),
+
+ Arguments.of("*.jsp", "/hello.1jsp"),
+ Arguments.of("*.jsp", "/hello.jsp1"),
+ Arguments.of("*.jsp", "/hello.do"),
+
+ Arguments.of("*.jsp", "/abc/hello.do"),
+ Arguments.of("*.jsp", "/abc/def/hello.do"),
+ Arguments.of("*.jsp", "/abc.do")
+ );
+ }
+
+ private void start(PatternRule rule) throws Exception
+ {
+ _rewriteHandler.addRule(rule);
+ start(new Handler.Processor()
{
- return target;
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
+ }
+
+ @ParameterizedTest
+ @MethodSource("matches")
+ public void testTrueMatch(String pattern, String uri) throws Exception
+ {
+ TestPatternRule rule = new TestPatternRule(pattern);
+ start(rule);
+
+ String request = """
+ GET $U HTTP/1.1
+ Host: localhost
+
+ """.replace("$U", uri);
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertTrue(rule._applied);
+ }
+
+ @ParameterizedTest
+ @MethodSource("noMatches")
+ public void testFalseMatch(String pattern, String uri) throws Exception
+ {
+ TestPatternRule rule = new TestPatternRule(pattern);
+ start(rule);
+
+ String request = """
+ GET $U HTTP/1.1
+ Host: localhost
+
+ """.replace("$U", uri);
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertFalse(rule._applied);
+ }
+
+ private static class TestPatternRule extends PatternRule
+ {
+ private boolean _applied;
+
+ private TestPatternRule(String pattern)
+ {
+ super(pattern);
+ }
+
+ @Override
+ public Request.WrapperProcessor apply(Request.WrapperProcessor input)
+ {
+ _applied = true;
+ return input;
}
}
}
diff --git a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectPatternRuleTest.java b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectPatternRuleTest.java
index 163ba2aa332..2019cbd3a51 100644
--- a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectPatternRuleTest.java
+++ b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectPatternRuleTest.java
@@ -13,54 +13,66 @@
package org.eclipse.jetty.rewrite.handler;
-import java.io.IOException;
-
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
-import org.junit.jupiter.api.BeforeEach;
+import org.eclipse.jetty.http.HttpTester;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
import org.junit.jupiter.api.Test;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertEquals;
-public class RedirectPatternRuleTest extends AbstractRuleTestCase
+public class RedirectPatternRuleTest extends AbstractRuleTest
{
- @BeforeEach
- public void init() throws Exception
+ private void start(RedirectPatternRule rule) throws Exception
{
- start(false);
- }
-
- private void assertRedirectResponse(int expectedStatusCode, String expectedLocation) throws IOException
- {
- assertThat("Response status code", _response.getStatus(), is(expectedStatusCode));
- assertThat("Response location", _response.getHeader(HttpHeader.LOCATION.asString()), is(expectedLocation));
+ _rewriteHandler.addRule(rule);
+ start(new Handler.Processor()
+ {
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
}
@Test
- public void testGlobPattern() throws IOException
+ public void testGlobPattern() throws Exception
{
String location = "http://eclipse.com";
+ RedirectPatternRule rule = new RedirectPatternRule("*", location);
+ start(rule);
- RedirectPatternRule rule = new RedirectPatternRule();
- rule.setPattern("*");
- rule.setLocation(location);
+ String request = """
+ GET / HTTP/1.1
+ Host: localhost
+
+ """;
- rule.apply("/", _request, _response);
- assertRedirectResponse(HttpStatus.FOUND_302, location);
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.FOUND_302, response.getStatus());
+ assertEquals(location, response.get(HttpHeader.LOCATION));
}
@Test
- public void testPrefixPattern() throws IOException
+ public void testPrefixPattern() throws Exception
{
String location = "http://api.company.com/";
-
- RedirectPatternRule rule = new RedirectPatternRule();
- rule.setPattern("/api/*");
- rule.setLocation(location);
+ RedirectPatternRule rule = new RedirectPatternRule("/api/*", location);
rule.setStatusCode(HttpStatus.MOVED_PERMANENTLY_301);
+ start(rule);
- rule.apply("/api/rest?foo=1", _request, _response);
- assertRedirectResponse(HttpStatus.MOVED_PERMANENTLY_301, location);
+ String request = """
+ GET /api/rest?foo=1 HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.MOVED_PERMANENTLY_301, response.getStatus());
+ assertEquals(location, response.get(HttpHeader.LOCATION));
}
}
diff --git a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRuleTest.java b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRuleTest.java
index 72866d201f0..10e3b438a89 100644
--- a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRuleTest.java
+++ b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRuleTest.java
@@ -13,80 +13,98 @@
package org.eclipse.jetty.rewrite.handler;
-import java.io.IOException;
-
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
-import org.junit.jupiter.api.BeforeEach;
+import org.eclipse.jetty.http.HttpTester;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
import org.junit.jupiter.api.Test;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertEquals;
-public class RedirectRegexRuleTest extends AbstractRuleTestCase
+public class RedirectRegexRuleTest extends AbstractRuleTest
{
- @BeforeEach
- public void init() throws Exception
+ private void start(RedirectRegexRule rule) throws Exception
{
- start(false);
- }
-
- private void assertRedirectResponse(int expectedStatusCode, String expectedLocation) throws IOException
- {
- assertThat("Response status code", _response.getStatus(), is(expectedStatusCode));
- assertThat("Response location", _response.getHeader(HttpHeader.LOCATION.asString()), is(expectedLocation));
+ _rewriteHandler.addRule(rule);
+ start(new Handler.Processor()
+ {
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
}
@Test
- public void testLocationWithReplacementGroupEmpty() throws IOException
+ public void testLocationWithReplacementGroupEmpty() throws Exception
{
RedirectRegexRule rule = new RedirectRegexRule("/my/dir/file/(.*)$", "http://www.mortbay.org/$1");
+ start(rule);
- // Resource is dir
- rule.matchAndApply("/my/dir/file/", _request, _response);
- assertRedirectResponse(HttpStatus.FOUND_302, "http://www.mortbay.org/");
+ String request = """
+ GET /my/dir/file/ HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.FOUND_302, response.getStatus());
+ assertEquals("http://www.mortbay.org/", response.get(HttpHeader.LOCATION));
}
@Test
- public void testLocationWithPathReplacement() throws IOException
+ public void testLocationWithPathReplacement() throws Exception
{
RedirectRegexRule rule = new RedirectRegexRule("/documentation/(.*)$", "/docs/$1");
+ start(rule);
- // Resource is dir
- rule.matchAndApply("/documentation/top.html", _request, _response);
- assertRedirectResponse(HttpStatus.FOUND_302, "http://0.0.0.0/docs/top.html");
+ String request = """
+ GET /documentation/top.html HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.FOUND_302, response.getStatus());
+ assertEquals("http://localhost/docs/top.html", response.get(HttpHeader.LOCATION));
}
@Test
- public void testLocationWithReplacmentGroupSimple() throws IOException
+ public void testLocationWithReplacementGroupSimple() throws Exception
{
RedirectRegexRule rule = new RedirectRegexRule("/my/dir/file/(.*)$", "http://www.mortbay.org/$1");
+ start(rule);
- // Resource is an image
- rule.matchAndApply("/my/dir/file/image.png", _request, _response);
- assertRedirectResponse(HttpStatus.FOUND_302, "http://www.mortbay.org/image.png");
+ String request = """
+ GET /my/dir/file/image.png HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.FOUND_302, response.getStatus());
+ assertEquals("http://www.mortbay.org/image.png", response.get(HttpHeader.LOCATION));
}
@Test
- public void testLocationWithReplacementGroupDeepWithParams() throws IOException
+ public void testLocationWithReplacementGroupWithQuery() throws Exception
{
RedirectRegexRule rule = new RedirectRegexRule("/my/dir/file/(.*)$", "http://www.mortbay.org/$1");
-
- // Resource is api with parameters
- rule.matchAndApply("/my/dir/file/api/rest/foo?id=100&sort=date", _request, _response);
- assertRedirectResponse(HttpStatus.FOUND_302, "http://www.mortbay.org/api/rest/foo?id=100&sort=date");
- }
-
- @Test
- public void testMovedPermanently() throws IOException
- {
- RedirectRegexRule rule = new RedirectRegexRule();
- rule.setRegex("/api/(.*)$");
- rule.setLocation("http://api.company.com/$1");
rule.setStatusCode(HttpStatus.MOVED_PERMANENTLY_301);
+ start(rule);
- // Resource is api with parameters
- rule.matchAndApply("/api/rest/foo?id=100&sort=date", _request, _response);
- assertRedirectResponse(HttpStatus.MOVED_PERMANENTLY_301, "http://api.company.com/rest/foo?id=100&sort=date");
+ String request = """
+ GET /my/dir/file/api/rest/foo?id=100&sort=date HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.MOVED_PERMANENTLY_301, response.getStatus());
+ assertEquals("http://www.mortbay.org/api/rest/foo?id=100&sort=date", response.get(HttpHeader.LOCATION));
}
}
diff --git a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RegexRuleTest.java b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RegexRuleTest.java
index 0664bf1afd0..e0397d8560b 100644
--- a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RegexRuleTest.java
+++ b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RegexRuleTest.java
@@ -13,103 +13,121 @@
package org.eclipse.jetty.rewrite.handler;
-import java.io.IOException;
import java.util.regex.Matcher;
+import java.util.stream.Stream;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.HttpTester;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
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 RegexRuleTest
+public class RegexRuleTest extends AbstractRuleTest
{
- private RegexRule _rule;
-
- @BeforeEach
- public void init()
+ public static Stream matches()
{
- _rule = new TestRegexRule();
- }
-
- @AfterEach
- public void destroy()
- {
- _rule = null;
- }
-
- @Test
- public void testTrueMatch() throws IOException
- {
- String[][] matchCases = {
+ return Stream.of(
// regex: *.jsp
- {"/.*.jsp", "/hello.jsp"},
- {"/.*.jsp", "/abc/hello.jsp"},
+ Arguments.of("/.*.jsp", "/hello.jsp"),
+ Arguments.of("/.*.jsp", "/abc/hello.jsp"),
// regex: /abc or /def
- {"/abc|/def", "/abc"},
- {"/abc|/def", "/def"},
+ Arguments.of("/abc|/def", "/abc"),
+ Arguments.of("/abc|/def", "/def"),
// regex: *.do or *.jsp
- {".*\\.do|.*\\.jsp", "/hello.do"},
- {".*\\.do|.*\\.jsp", "/hello.jsp"},
- {".*\\.do|.*\\.jsp", "/abc/hello.do"},
- {".*\\.do|.*\\.jsp", "/abc/hello.jsp"},
+ Arguments.of(".*\\.do|.*\\.jsp", "/hello.do"),
+ Arguments.of(".*\\.do|.*\\.jsp", "/hello.jsp"),
+ Arguments.of(".*\\.do|.*\\.jsp", "/abc/hello.do"),
+ Arguments.of(".*\\.do|.*\\.jsp", "/abc/hello.jsp"),
- {"/abc/.*.htm|/def/.*.htm", "/abc/hello.htm"},
- {"/abc/.*.htm|/def/.*.htm", "/abc/def/hello.htm"},
+ Arguments.of("/abc/.*.htm|/def/.*.htm", "/abc/hello.htm"),
+ Arguments.of("/abc/.*.htm|/def/.*.htm", "/abc/def/hello.htm"),
// regex: /abc/*.jsp
- {"/abc/.*.jsp", "/abc/hello.jsp"},
- {"/abc/.*.jsp", "/abc/def/hello.jsp"}
- };
-
- for (String[] matchCase : matchCases)
- {
- assertMatch(true, matchCase);
- }
- }
-
- @Test
- public void testFalseMatch() throws IOException
- {
- String[][] matchCases = {
- {"/abc/.*.jsp", "/hello.jsp"}
- };
-
- for (String[] matchCase : matchCases)
- {
- assertMatch(false, matchCase);
- }
- }
-
- private void assertMatch(boolean flag, String[] matchCase) throws IOException
- {
- _rule.setRegex(matchCase[0]);
- final String uri = matchCase[1];
- String result = _rule.matchAndApply(uri,
- new Request(null, null)
- {
- @Override
- public String getRequestURI()
- {
- return uri;
- }
- }, null
+ Arguments.of("/abc/.*.jsp", "/abc/hello.jsp"),
+ Arguments.of("/abc/.*.jsp", "/abc/def/hello.jsp")
);
-
- assertEquals(flag, result != null, "regex: " + matchCase[0] + " uri: " + matchCase[1]);
}
- private class TestRegexRule extends RegexRule
+ public static Stream noMatches()
{
- @Override
- public String apply(String target, HttpServletRequest request, HttpServletResponse response, Matcher matcher) throws IOException
+ return Stream.of(
+ Arguments.of("/abc/.*.jsp", "/hello.jsp")
+ );
+ }
+
+ private void start(RegexRule rule) throws Exception
+ {
+ _rewriteHandler.addRule(rule);
+ start(new Handler.Processor()
{
- return target;
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
+ }
+
+ @ParameterizedTest
+ @MethodSource("matches")
+ public void testTrueMatch(String pattern, String uri) throws Exception
+ {
+ TestRegexRule rule = new TestRegexRule(pattern);
+ start(rule);
+
+ String request = """
+ GET $U HTTP/1.1
+ Host: localhost
+
+ """.replace("$U", uri);
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertTrue(rule._applied);
+ }
+
+ @ParameterizedTest
+ @MethodSource("noMatches")
+ public void testFalseMatch(String pattern, String uri) throws Exception
+ {
+ TestRegexRule rule = new TestRegexRule(pattern);
+ start(rule);
+
+ String request = """
+ GET $U HTTP/1.1
+ Host: localhost
+
+ """.replace("$U", uri);
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertFalse(rule._applied);
+ }
+
+ private static class TestRegexRule extends RegexRule
+ {
+ private boolean _applied;
+
+ public TestRegexRule(String pattern)
+ {
+ super(pattern);
+ }
+
+ @Override
+ public Request.WrapperProcessor apply(Request.WrapperProcessor input, Matcher matcher)
+ {
+ _applied = true;
+ return input;
}
}
}
diff --git a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ResponsePatternRuleTest.java b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ResponsePatternRuleTest.java
index 63e8b71efed..e16c8716f67 100644
--- a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ResponsePatternRuleTest.java
+++ b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ResponsePatternRuleTest.java
@@ -13,49 +13,64 @@
package org.eclipse.jetty.rewrite.handler;
-import java.io.IOException;
-
-import org.eclipse.jetty.server.Dispatcher;
-import org.junit.jupiter.api.BeforeEach;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.HttpTester;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
import org.junit.jupiter.api.Test;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-public class ResponsePatternRuleTest extends AbstractRuleTestCase
+public class ResponsePatternRuleTest extends AbstractRuleTest
{
- private ResponsePatternRule _rule;
-
- @BeforeEach
- public void init() throws Exception
+ private void start(ResponsePatternRule rule) throws Exception
{
- start(false);
- _rule = new ResponsePatternRule();
- _rule.setPattern("/test");
- }
-
- @Test
- public void testStatusCodeNoMessage() throws IOException
- {
- for (int i = 1; i < 600; i++)
+ _rewriteHandler.addRule(rule);
+ start(new Handler.Processor()
{
- _rule.setCode("" + i);
- _rule.setMessage(null);
- _rule.apply(null, _request, _response);
-
- assertEquals(i, _response.getStatus());
- assertNull(_request.getAttribute(Dispatcher.ERROR_MESSAGE));
- }
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ callback.succeeded();
+ }
+ });
}
@Test
- public void testStatusCodeMessage() throws IOException
+ public void testStatusCodeNoMessage() throws Exception
{
- _rule.setCode("499");
- _rule.setMessage("Message 499");
- _rule.apply(null, _request, _response);
+ ResponsePatternRule rule = new ResponsePatternRule("/test", HttpStatus.NO_CONTENT_204, null);
+ start(rule);
- assertEquals(499, _response.getStatus());
- assertEquals("Message 499", _request.getAttribute(Dispatcher.ERROR_MESSAGE));
+ String request = """
+ GET /test HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(rule.getCode(), response.getStatus());
+ }
+
+ @Test
+ public void testStatusCodeMessage() throws Exception
+ {
+ ResponsePatternRule rule = new ResponsePatternRule("/test", HttpStatus.BAD_REQUEST_400, "MESSAGE");
+
+ start(rule);
+
+ String request = """
+ GET /test HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(rule.getCode(), response.getStatus());
+ assertThat(response.getContent(), containsString(rule.getMessage()));
}
}
diff --git a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteHandlerTest.java b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteHandlerTest.java
index 88df5b75ae1..0e724a97b03 100644
--- a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteHandlerTest.java
+++ b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteHandlerTest.java
@@ -13,183 +13,113 @@
package org.eclipse.jetty.rewrite.handler;
-import java.io.IOException;
+import java.util.List;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.http.HttpURI;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.HttpTester;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-public class RewriteHandlerTest extends AbstractRuleTestCase
+public class RewriteHandlerTest extends AbstractRuleTest
{
- private RewriteHandler _handler;
- private RewritePatternRule _rule1;
- private RewritePatternRule _rule2;
- private RewritePatternRule _rule3;
- private RewriteRegexRule _rule4;
-
@BeforeEach
public void init() throws Exception
{
- _handler = new RewriteHandler();
- _handler.setServer(_server);
- _handler.setHandler(new AbstractHandler()
+ RewritePatternRule rule1 = new RewritePatternRule("/aaa/*", "/bbb");
+ RewritePatternRule rule2 = new RewritePatternRule("/bbb/*", "/ccc");
+ RewritePatternRule rule3 = new RewritePatternRule("/ccc/*", "/ddd");
+ RewriteRegexRule rule4 = new RewriteRegexRule("/xxx/(.*)", "/$1/zzz");
+ _rewriteHandler.setRules(List.of(rule1, rule2, rule3, rule4));
+ _rewriteHandler.setOriginalPathAttribute("originalPath");
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ public void process(Request request, Response response, Callback callback)
{
- response.setStatus(201);
- request.setAttribute("target", target);
- request.setAttribute("URI", request.getRequestURI());
- request.setAttribute("info", request.getPathInfo());
+ response.setStatus(HttpStatus.OK_200);
+ response.setHeader("X-Path", request.getHttpURI().getPath());
+ response.setHeader("X-Original-Path", (String)request.getAttribute(_rewriteHandler.getOriginalPathAttribute()));
+ callback.succeeded();
}
});
- _handler.start();
-
- _rule1 = new RewritePatternRule();
- _rule1.setPattern("/aaa/*");
- _rule1.setReplacement("/bbb");
- _rule2 = new RewritePatternRule();
- _rule2.setPattern("/bbb/*");
- _rule2.setReplacement("/ccc");
- _rule3 = new RewritePatternRule();
- _rule3.setPattern("/ccc/*");
- _rule3.setReplacement("/ddd");
- _rule4 = new RewriteRegexRule();
- _rule4.setRegex("/xxx/(.*)");
- _rule4.setReplacement("/$1/zzz");
-
- _handler.setRules(new Rule[]{_rule1, _rule2, _rule3, _rule4});
-
- start(false);
}
@Test
- public void test() throws Exception
+ public void testXXXtoBar() throws Exception
{
- _response.setStatus(200);
- _request.setHandled(false);
- _handler.setOriginalPathAttribute("/before");
- _handler.setRewriteRequestURI(true);
- _handler.setRewritePathInfo(true);
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/xxx/bar"));
- _request.setContext(_request.getContext(), "/xxx/bar");
- _handler.handle("/xxx/bar", _request, _request, _response);
- assertEquals(201, _response.getStatus());
- assertEquals("/bar/zzz", _request.getAttribute("target"));
- assertEquals("/bar/zzz", _request.getAttribute("URI"));
- assertEquals("/bar/zzz", _request.getAttribute("info"));
- assertEquals(null, _request.getAttribute("before"));
+ String request = """
+ GET /xxx/bar HTTP/1.1
+ Host: localhost
+
+ """;
- _response.setStatus(200);
- _request.setHandled(false);
- _handler.setOriginalPathAttribute("/before");
- _handler.setRewriteRequestURI(false);
- _handler.setRewritePathInfo(false);
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/foo/bar"));
- _request.setContext(_request.getContext(), "/foo/bar");
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertEquals("/bar/zzz", response.get("X-Path"), "X-Path response value");
+ }
- _handler.handle("/foo/bar", _request, _request, _response);
- assertEquals(201, _response.getStatus());
- assertEquals("/foo/bar", _request.getAttribute("target"));
- assertEquals("/foo/bar", _request.getAttribute("URI"));
- assertEquals("/foo/bar", _request.getAttribute("info"));
- assertEquals(null, _request.getAttribute("before"));
+ @Test
+ public void testFooNoChange() throws Exception
+ {
+ String request = """
+ GET /foo/bar HTTP/1.1
+ Host: localhost
+
+ """;
- _response.setStatus(200);
- _request.setHandled(false);
- _handler.setOriginalPathAttribute(null);
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/aaa/bar"));
- _request.setContext(_request.getContext(), "/aaa/bar");
- _handler.handle("/aaa/bar", _request, _request, _response);
- assertEquals(201, _response.getStatus());
- assertEquals("/ddd/bar", _request.getAttribute("target"));
- assertEquals("/aaa/bar", _request.getAttribute("URI"));
- assertEquals("/aaa/bar", _request.getAttribute("info"));
- assertEquals(null, _request.getAttribute("before"));
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertEquals("/foo/bar", response.get("X-Path"), "X-Path response value");
+ }
- _response.setStatus(200);
- _request.setHandled(false);
- _handler.setOriginalPathAttribute("before");
- _handler.setRewriteRequestURI(true);
- _handler.setRewritePathInfo(true);
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/aaa/bar"));
- _request.setContext(_request.getContext(), "/aaa/bar");
- _handler.handle("/aaa/bar", _request, _request, _response);
- assertEquals(201, _response.getStatus());
- assertEquals("/ddd/bar", _request.getAttribute("target"));
- assertEquals("/ddd/bar", _request.getAttribute("URI"));
- assertEquals("/ddd/bar", _request.getAttribute("info"));
- assertEquals("/aaa/bar", _request.getAttribute("before"));
+ @Test
+ public void testAAAtoDDD() throws Exception
+ {
+ String request = """
+ GET /aaa/bar HTTP/1.1
+ Host: localhost
+
+ """;
- _response.setStatus(200);
- _request.setHandled(false);
- _rule2.setTerminating(true);
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/aaa/bar"));
- _request.setContext(_request.getContext(), "/aaa/bar");
- _handler.handle("/aaa/bar", _request, _request, _response);
- assertEquals(201, _response.getStatus());
- assertEquals("/ccc/bar", _request.getAttribute("target"));
- assertEquals("/ccc/bar", _request.getAttribute("URI"));
- assertEquals("/ccc/bar", _request.getAttribute("info"));
- assertEquals("/aaa/bar", _request.getAttribute("before"));
-
- _response.setStatus(200);
- _request.setHandled(false);
- _rule2.setHandling(true);
- _request.setAttribute("before", null);
- _request.setAttribute("target", null);
- _request.setAttribute("URI", null);
- _request.setAttribute("info", null);
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/aaa/bar"));
- _request.setContext(_request.getContext(), "/aaa/bar");
- _handler.handle("/aaa/bar", _request, _request, _response);
- assertEquals(200, _response.getStatus());
- assertEquals(null, _request.getAttribute("target"));
- assertEquals(null, _request.getAttribute("URI"));
- assertEquals(null, _request.getAttribute("info"));
- assertEquals("/aaa/bar", _request.getAttribute("before"));
- assertTrue(_request.isHandled());
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertEquals("/ddd/bar", response.get("X-Path"), "X-Path response value");
+ assertEquals("/aaa/bar", response.get("X-Original-Path"), "X-Original-Path response value");
}
@Test
public void testEncodedPattern() throws Exception
{
- _response.setStatus(200);
- _request.setHandled(false);
- _handler.setOriginalPathAttribute("/before");
- _handler.setRewriteRequestURI(true);
- _handler.setRewritePathInfo(false);
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/ccc/x%20y"));
- _request.setContext(_request.getContext(), "/ccc/x y");
- _handler.handle("/ccc/x y", _request, _request, _response);
- assertEquals(201, _response.getStatus());
- assertEquals("/ddd/x y", _request.getAttribute("target"));
- assertEquals("/ddd/x%20y", _request.getAttribute("URI"));
- assertEquals("/ccc/x y", _request.getAttribute("info"));
+ String request = """
+ GET /ccc/x%20y HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertEquals("/ddd/x%20y", response.get("X-Path"));
+ assertEquals("/ccc/x%20y", response.get("X-Original-Path"));
}
@Test
public void testEncodedRegex() throws Exception
{
- _response.setStatus(200);
- _request.setHandled(false);
- _handler.setOriginalPathAttribute("/before");
- _handler.setRewriteRequestURI(true);
- _handler.setRewritePathInfo(false);
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/xxx/x%20y"));
- _request.setContext(_request.getContext(), "/xxx/x y");
- _handler.handle("/xxx/x y", _request, _request, _response);
- assertEquals(201, _response.getStatus());
- assertEquals("/x y/zzz", _request.getAttribute("target"));
- assertEquals("/x%20y/zzz", _request.getAttribute("URI"));
- assertEquals("/xxx/x y", _request.getAttribute("info"));
+ String request = """
+ GET /xxx/x%20y HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertEquals("/x%20y/zzz", response.get("X-Path"));
+ assertEquals("/xxx/x%20y", response.get("X-Original-Path"));
}
}
diff --git a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewritePatternRuleTest.java b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewritePatternRuleTest.java
index 23747faace7..2ffc25ffaa0 100644
--- a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewritePatternRuleTest.java
+++ b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewritePatternRuleTest.java
@@ -13,110 +13,105 @@
package org.eclipse.jetty.rewrite.handler;
-import java.io.IOException;
+import java.util.stream.Stream;
-import org.eclipse.jetty.http.HttpURI;
-import org.junit.jupiter.api.BeforeEach;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.HttpTester;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
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.is;
+import static org.junit.jupiter.api.Assertions.assertEquals;
-public class RewritePatternRuleTest extends AbstractRuleTestCase
+public class RewritePatternRuleTest extends AbstractRuleTest
{
- // TODO: Parameterize
- private final String[][] _tests =
+ public static Stream data()
+ {
+ return Stream.of(
+ Arguments.of("/", "/replace", "/foo/bar", "/replace"),
+ Arguments.of("/*", "/replace/foo/bar", "/foo/bar", "/replace/foo/bar/foo/bar"),
+ Arguments.of("/foo/*", "/replace/bar", "/foo/bar", "/replace/bar/bar"),
+ Arguments.of("/foo/bar", "/replace", "/foo/bar", "/replace"),
+ Arguments.of("*.txt", "/replace", "/foo/bar.txt", "/replace"),
+ Arguments.of("/foo/*", "/replace", "/foo/bar/%20x", "/replace/bar/%20x"),
+ Arguments.of("/old/context", "/replace?given=param", "/old/context", "/replace?given=param")
+ );
+ }
+
+ private void start(RewritePatternRule rule) throws Exception
+ {
+ _rewriteHandler.addRule(rule);
+ start(new Handler.Processor()
{
- {"/foo/bar", "/", "/replace"},
- {"/foo/bar", "/*", "/replace/foo/bar"},
- {"/foo/bar", "/foo/*", "/replace/bar"},
- {"/foo/bar", "/foo/bar", "/replace"},
- {"/foo/bar.txt", "*.txt", "/replace"},
- {"/foo/bar/%20x", "/foo/*", "/replace/bar/%20x"},
- };
- private RewritePatternRule _rule;
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ response.setHeader("X-URI", request.getHttpURI().getPathQuery());
+ callback.succeeded();
+ }
+ });
+ }
- @BeforeEach
- public void init() throws Exception
+ @ParameterizedTest
+ @MethodSource("data")
+ public void testRewritePatternRule(String pattern, String replacement, String inputURI, String expectURI) throws Exception
{
- start(false);
- _rule = new RewritePatternRule();
- _rule.setReplacement("/replace");
+ RewritePatternRule rule = new RewritePatternRule(pattern, replacement);
+ start(rule);
+
+ String request = """
+ GET $U HTTP/1.1
+ Host: localhost
+ Connection: close
+
+ """.replace("$U", inputURI);
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertEquals(expectURI, response.get("X-URI"), "X-URI response header value");
}
@Test
- public void testMatchAndApplyAndApplyURI() throws IOException
- {
- for (String[] test : _tests)
- {
- _rule.setPattern(test[1]);
- String result = _rule.matchAndApply(test[0], _request, _response);
- assertThat(test[1], test[2], is(result));
-
- _rule.applyURI(_request, null, result);
- assertThat(_request.getRequestURI(), is(test[2]));
- }
- }
-
- @Test
- public void testReplacementWithQueryString() throws IOException
- {
- String replacement = "/replace?given=param";
- String[] split = replacement.split("\\?", 2);
- String path = split[0];
- String queryString = split[1];
-
- RewritePatternRule rewritePatternRule = new RewritePatternRule();
- rewritePatternRule.setPattern("/old/context");
- rewritePatternRule.setReplacement(replacement);
-
- String result = rewritePatternRule.matchAndApply("/old/context", _request, _response);
- assertThat(result, is(path));
-
- rewritePatternRule.applyURI(_request, null, result);
- assertThat("queryString matches expected", _request.getQueryString(), is(queryString));
- assertThat("request URI matches expected", _request.getRequestURI(), is(path));
- }
-
- @Test
- public void testRequestWithQueryString() throws IOException
+ public void testRequestWithQueryString() throws Exception
{
String replacement = "/replace";
- String queryString = "request=parameter";
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/old/context", null, queryString).asImmutable());
+ RewritePatternRule rule = new RewritePatternRule("/context", replacement);
+ start(rule);
- RewritePatternRule rewritePatternRule = new RewritePatternRule();
- rewritePatternRule.setPattern("/old/context");
- rewritePatternRule.setReplacement(replacement);
+ String query = "a=b";
+ String request = """
+ GET /context?$Q HTTP/1.1
+ Host: localhost
+
+ """.replace("$Q", query);
- String result = rewritePatternRule.matchAndApply("/old/context", _request, _response);
- assertThat("result matches expected", result, is(replacement));
-
- rewritePatternRule.applyURI(_request, null, result);
- assertThat("request URI matches expected", _request.getRequestURI(), is(replacement));
- assertThat("queryString matches expected", _request.getQueryString(), is(queryString));
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertEquals(replacement + "?" + query, response.get("X-URI"));
}
@Test
- public void testRequestAndReplacementWithQueryString() throws IOException
+ public void testRequestAndReplacementWithQueryString() throws Exception
{
- String requestQueryString = "request=parameter";
- String replacement = "/replace?given=param";
- String[] split = replacement.split("\\?", 2);
- String path = split[0];
- String queryString = split[1];
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/old/context", null, requestQueryString).asImmutable());
+ String replacementPath = "/replace";
+ String replacementQuery = "c=d";
+ RewritePatternRule rule = new RewritePatternRule("/context", replacementPath + "?" + replacementQuery);
+ start(rule);
- RewritePatternRule rewritePatternRule = new RewritePatternRule();
- rewritePatternRule.setPattern("/old/context");
- rewritePatternRule.setReplacement(replacement);
+ String query = "a=b";
+ String request = """
+ GET /context?$Q HTTP/1.1
+ Host: localhost
+
+ """.replace("$Q", query);
- String result = rewritePatternRule.matchAndApply("/old/context", _request, _response);
- assertThat(result, is(path));
-
- rewritePatternRule.applyURI(_request, null, result);
- assertThat("queryString matches expected", _request.getQueryString(),
- is(requestQueryString + "&" + queryString));
- assertThat("request URI matches expected", _request.getRequestURI(), is(path));
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertEquals(replacementPath + "?" + query + "&" + replacementQuery, response.get("X-URI"));
}
}
diff --git a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java
index f0a6ed9a596..68574bad6f3 100644
--- a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java
+++ b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java
@@ -13,127 +13,135 @@
package org.eclipse.jetty.rewrite.handler;
-import java.nio.charset.StandardCharsets;
import java.util.stream.Stream;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.http.HttpURI;
-import org.eclipse.jetty.util.MultiMap;
-import org.eclipse.jetty.util.URIUtil;
-import org.eclipse.jetty.util.UrlEncoded;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
+import org.eclipse.jetty.util.StringUtil;
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.is;
import static org.junit.jupiter.api.Assertions.assertEquals;
-public class RewriteRegexRuleTest extends AbstractRuleTestCase
+public class RewriteRegexRuleTest extends AbstractRuleTest
{
public static Stream scenarios()
{
return Stream.of(
- new Scenario("/foo0/bar", null, ".*", "/replace", "/replace", null),
- new Scenario("/foo1/bar", "n=v", ".*", "/replace", "/replace", "n=v"),
- new Scenario("/foo2/bar", null, "/xxx.*", "/replace", null, null),
- new Scenario("/foo3/bar", null, "/(.*)/(.*)", "/$2/$1/xxx", "/bar/foo3/xxx", null),
- new Scenario("/f%20o3/bar", null, "/(.*)/(.*)", "/$2/$1/xxx", "/bar/f%20o3/xxx", null),
- new Scenario("/foo4/bar", null, "/(.*)/(.*)", "/test?p2=$2&p1=$1", "/test", "p2=bar&p1=foo4"),
- new Scenario("/foo5/bar", "n=v", "/(.*)/(.*)", "/test?p2=$2&p1=$1", "/test", "n=v&p2=bar&p1=foo5"),
- new Scenario("/foo6/bar", null, "/(.*)/(.*)", "/foo6/bar?p2=$2&p1=$1", "/foo6/bar", "p2=bar&p1=foo6"),
- new Scenario("/foo7/bar", "n=v", "/(.*)/(.*)", "/foo7/bar?p2=$2&p1=$1", "/foo7/bar", "n=v&p2=bar&p1=foo7"),
- new Scenario("/foo8/bar", null, "/(foo8)/(.*)(bar)", "/$3/$1/xxx$2", "/bar/foo8/xxx", null),
- new Scenario("/foo9/$bar", null, ".*", "/$replace", "/$replace", null),
- new Scenario("/fooA/$bar", null, "/fooA/(.*)", "/$1/replace", "/$bar/replace", null),
- new Scenario("/fooB/bar/info", null, "/fooB/(NotHere)?([^/]*)/(.*)", "/$3/other?p1=$2", "/info/other", "p1=bar"),
- new Scenario("/fooC/bar/info", null, "/fooC/(NotHere)?([^/]*)/(.*)", "/$3/other?p1=$2&$Q", "/info/other", "p1=bar&"),
- new Scenario("/fooD/bar/info", "n=v", "/fooD/(NotHere)?([^/]*)/(.*)", "/$3/other?p1=$2&$Q", "/info/other", "p1=bar&n=v"),
- new Scenario("/fooE/bar/info", "n=v", "/fooE/(NotHere)?([^/]*)/(.*)", "/$3/other?p1=$2", "/info/other", "n=v&p1=bar")
+ // Simple replacement
+ new Scenario("/foo0/bar", "/.*", "/replace", "/replace", null),
+ // Non-matching rule (no replacement done)
+ new Scenario("/foo2/bar", "/xxx.*", "/replace", "/foo2/bar", null),
+ // Replacement with named references
+ new Scenario("/foo1/bar?n=v", "^/.*\\?(?.*)$", "/replace?${query}", "/replace", "n=v"),
+ // group of everything after last slash
+ new Scenario("/foo3/bar", "/(.*)/(.*)", "/$2/$1/xxx", "/bar/foo3/xxx", null),
+ // TODO: path is not encoded when it reaches the X-Path handler
+ new Scenario("/f%20o3/bar", "/(.*)/(.*)", "/$2/$1/xxx", "/bar/f%20o3/xxx", null),
+ new Scenario("/foo4/bar", "/(.*)/(.*)", "/test?p2=$2&p1=$1", "/test", "p2=bar&p1=foo4"),
+ new Scenario("/foo4.2/bar/zed", "/(.*)/(.*)", "/test?p2=$2&p1=$1", "/test", "p2=zed&p1=foo4.2/bar"),
+ new Scenario("/foo4.3/bar/zed", "/([^/]*)/([^/]*)/.*", "/test?p2=$2&p1=$1", "/test", "p2=bar&p1=foo4.3"),
+ // Example of bad regex group (accidentally covered query)
+ new Scenario("/foo4.4/bar?x=y", "/(.*)/(.*)", "/test?p2=$2&p1=$1", "/test", "p2=bar?x=y&p1=foo4.4"),
+ // Fixed Example of above bad regex group (covered query properly)
+ new Scenario("/foo4.5/bar?x=y", "/([^/]*)/([^/?]*).*", "/test?p2=$2&p1=$1", "/test", "p2=bar&p1=foo4.5"),
+ // specific regex groups
+ new Scenario("/foo5/bar", "^/(foo5)/(.*)(bar)", "/$3/$1/xxx$2", "/bar/foo5/xxx", null),
+ // target input with raw "$"
+ new Scenario("/foo6/$bar", "/.*", "/replace", "/replace", null),
+ // target input with raw "$", and replacement with "$" character
+ new Scenario("/foo6/$bar", "/.*", "/\\$replace", "/$replace", null),
+ new Scenario("/fooA/$bar", "/fooA/(.*)", "/$1/replace", "/$bar/replace", null),
+ new Scenario("/fooB/bar/info", "/fooB/(NotHere)?([^/]*)/(.*)", "/$3/other?p1=$2", "/info/other", "p1=bar"),
+ new Scenario("/fooC/bar/info", "/fooC/(NotHere)?([^/]*)/([^?]*)(?:\\?|/\\?|/|)(?.*)", "/$3/other?p1=$2&${query}", "/info/other", "p1=bar&"),
+ new Scenario("/fooD/bar/info?n=v", "/fooD/(NotHere)?([^/]*)/([^?]*)(?:\\?|/\\?|/|)(?.*)", "/$3/other?p1=$2&${query}", "/info/other", "p1=bar&n=v"),
+ new Scenario("/fooE/bar/info?n=v", "/fooE/(NotHere)?([^/]*)/([^?]*)(?:\\?|/\\?|/|)(?.*)", "/$3/other?p1=$2", "/info/other", "p1=bar")
).map(Arguments::of);
}
+ private void start(RewriteRegexRule rule) throws Exception
+ {
+ _rewriteHandler.addRule(rule);
+ start(new Handler.Processor()
+ {
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ HttpURI httpURI = request.getHttpURI();
+ response.setHeader("X-Path", httpURI.getPath());
+ if (httpURI.getQuery() != null)
+ response.setHeader("X-Query", httpURI.getQuery());
+ callback.succeeded();
+ }
+ });
+ }
+
@ParameterizedTest
@MethodSource("scenarios")
public void testRequestUriEnabled(Scenario scenario) throws Exception
{
- start(false);
- RewriteRegexRule rule = new RewriteRegexRule();
+ RewriteRegexRule rule = new RewriteRegexRule(scenario.regex, scenario.replacement);
+ start(rule);
- reset();
- _request.setHttpURI(HttpURI.build(_request.getHttpURI()));
+ String request = """
+ GET $T HTTP/1.1
+ Host: localhost
+
+ """.replace("$T", scenario.pathQuery);
- rule.setRegex(scenario.regex);
- rule.setReplacement(scenario.replacement);
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus(), "Response status code");
+ assertEquals(scenario.expectedPath, response.get("X-Path"), "Response X-Path header value");
+ if (scenario.expectedQuery != null)
+ assertEquals(scenario.expectedQuery, response.get("X-Query"), "Response X-Query header value");
+ }
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), scenario.uriPathQuery, null, scenario.queryString));
-
- String result = rule.matchAndApply(scenario.uriPathQuery, _request, _response);
- assertEquals(scenario.expectedRequestURI, result);
- rule.applyURI(_request, scenario.uriPathQuery, result);
-
- if (result != null)
- {
- assertEquals(scenario.expectedRequestURI, _request.getRequestURI());
- assertEquals(scenario.expectedQueryString, _request.getQueryString());
- }
-
- if (scenario.expectedQueryString != null)
- {
- MultiMap params = new MultiMap();
- UrlEncoded.decodeTo(scenario.expectedQueryString, params, StandardCharsets.UTF_8);
-
- for (String n : params.keySet())
- {
- assertEquals(params.getString(n), _request.getParameter(n));
- }
- }
+ public static Stream inputPathQueries()
+ {
+ return Stream.of(
+ Arguments.of("/foo/bar", "/test?&p2=bar&p1=foo"),
+ Arguments.of("/foo/bar/", "/test?&p2=bar&p1=foo"),
+ Arguments.of("/foo/bar?", "/test?&p2=bar&p1=foo"),
+ Arguments.of("/foo/bar/?", "/test?&p2=bar&p1=foo"),
+ Arguments.of("/foo/bar?a=b", "/test?a=b&p2=bar&p1=foo"),
+ Arguments.of("/foo/bar/?a=b", "/test?a=b&p2=bar&p1=foo")
+ );
}
@ParameterizedTest
- @MethodSource("scenarios")
- public void testContainedRequestUriEnabled(Scenario scenario) throws Exception
+ @MethodSource("inputPathQueries")
+ public void testRegexOptionalTargetQuery(String target, String expectedResult) throws Exception
{
- start(false);
- RewriteRegexRule rule = new RewriteRegexRule();
+ String regex = "^/([^/]*)/([^/\\?]*)(?:\\?|/\\?|/|)(?.*)$";
+ String replacement = "/test?${query}&p2=$2&p1=$1";
+ RewriteRegexRule rule = new RewriteRegexRule(regex, replacement);
+ start(rule);
- RuleContainer container = new RuleContainer();
- container.setRewriteRequestURI(true);
- container.addRule(rule);
+ String request = """
+ GET $T HTTP/1.1
+ Host: localhost
+
+ """.replace("$T", target);
- reset();
- rule.setRegex(scenario.regex);
- rule.setReplacement(scenario.replacement);
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus(), "Response status code");
+ String result = response.get("X-Path");
+ String query = response.get("X-Query");
+ if (StringUtil.isNotBlank(query))
+ result = result + '?' + query;
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), scenario.uriPathQuery, null, scenario.queryString));
- _request.getAttributes().clearAttributes();
-
- String result = container.apply(URIUtil.decodePath(scenario.uriPathQuery), _request, _response);
- assertEquals(URIUtil.decodePath(scenario.expectedRequestURI == null ? scenario.uriPathQuery : scenario.expectedRequestURI), result);
- assertEquals(scenario.expectedRequestURI == null ? scenario.uriPathQuery : scenario.expectedRequestURI, _request.getRequestURI());
- assertEquals(scenario.expectedQueryString, _request.getQueryString());
+ assertThat(result, is(expectedResult));
}
- private static class Scenario
+ private record Scenario(String pathQuery, String regex, String replacement, String expectedPath, String expectedQuery)
{
- String uriPathQuery;
- String queryString;
- String regex;
- String replacement;
- String expectedRequestURI;
- String expectedQueryString;
-
- public Scenario(String uriPathQuery, String queryString, String regex, String replacement, String expectedRequestURI, String expectedQueryString)
- {
- this.uriPathQuery = uriPathQuery;
- this.queryString = queryString;
- this.regex = regex;
- this.replacement = replacement;
- this.expectedRequestURI = expectedRequestURI;
- this.expectedQueryString = expectedQueryString;
- }
-
- @Override
- public String toString()
- {
- return String.format("%s?%s>%s|%s", uriPathQuery, queryString, regex, replacement);
- }
}
}
diff --git a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/TerminatingPatternRuleTest.java b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/TerminatingPatternRuleTest.java
index 1dcd04fd434..1de18bef32c 100644
--- a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/TerminatingPatternRuleTest.java
+++ b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/TerminatingPatternRuleTest.java
@@ -13,83 +13,68 @@
package org.eclipse.jetty.rewrite.handler;
-import java.io.IOException;
-
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.HttpTester;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
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.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
-public class TerminatingPatternRuleTest extends AbstractRuleTestCase
+public class TerminatingPatternRuleTest extends AbstractRuleTest
{
- private RewriteHandler rewriteHandler;
-
@BeforeEach
public void init() throws Exception
{
- rewriteHandler = new RewriteHandler();
- rewriteHandler.setServer(_server);
- rewriteHandler.setHandler(new AbstractHandler()
+ TerminatingPatternRule rule1 = new TerminatingPatternRule("/login.jsp");
+ _rewriteHandler.addRule(rule1);
+ RedirectRegexRule rule2 = new RedirectRegexRule("^/login.*$", "http://login.company.com/");
+ rule2.setStatusCode(HttpStatus.SEE_OTHER_303);
+ _rewriteHandler.addRule(rule2);
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException,
- ServletException
+ public void process(Request request, Response response, Callback callback)
{
response.setStatus(HttpStatus.CREATED_201);
- request.setAttribute("target", target);
- request.setAttribute("URI", request.getRequestURI());
- request.setAttribute("info", request.getPathInfo());
+ callback.succeeded();
}
});
- rewriteHandler.start();
-
- TerminatingPatternRule rule1 = new TerminatingPatternRule();
- rule1.setPattern("/login.jsp");
- rewriteHandler.addRule(rule1);
- RedirectRegexRule rule2 = new RedirectRegexRule("^/login.*$", "http://login.company.com/");
- rewriteHandler.addRule(rule2);
-
- start(false);
- }
-
- private void assertIsRedirect(int expectedStatus, String expectedLocation)
- {
- assertThat("Response Status", _response.getStatus(), is(expectedStatus));
- assertThat("Response Location Header", _response.getHeader(HttpHeader.LOCATION.asString()), is(expectedLocation));
- }
-
- private void assertIsRequest(String expectedRequestPath)
- {
- assertThat("Response Status", _response.getStatus(), is(HttpStatus.CREATED_201));
- assertThat("Request Target", _request.getAttribute("target"), is(expectedRequestPath));
}
@Test
- public void testTerminatingEarly() throws IOException, ServletException
+ public void testTerminatingEarly() throws Exception
{
- rewriteHandler.handle("/login.jsp", _request, _request, _response);
- assertIsRequest("/login.jsp");
+ String request = """
+ GET /login.jsp HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.CREATED_201, response.getStatus());
+ assertNull(response.get(HttpHeader.LOCATION));
}
- @Test
- public void testNoTerminationDo() throws IOException, ServletException
+ @ParameterizedTest
+ @ValueSource(strings = {"/login.do", "/login/"})
+ public void testNonTerminating(String uri) throws Exception
{
- rewriteHandler.handle("/login.do", _request, _request, _response);
- assertIsRedirect(HttpStatus.MOVED_TEMPORARILY_302, "http://login.company.com/");
- }
+ String request = """
+ GET $U HTTP/1.1
+ Host: localhost
+
+ """.replace("$U", uri);
- @Test
- public void testNoTerminationDir() throws IOException, ServletException
- {
- rewriteHandler.handle("/login/", _request, _request, _response);
- assertIsRedirect(HttpStatus.MOVED_TEMPORARILY_302, "http://login.company.com/");
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.SEE_OTHER_303, response.getStatus());
+ assertEquals("http://login.company.com/", response.get(HttpHeader.LOCATION));
}
}
diff --git a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/TerminatingRegexRuleTest.java b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/TerminatingRegexRuleTest.java
index ddff1cb9362..82004469b6d 100644
--- a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/TerminatingRegexRuleTest.java
+++ b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/TerminatingRegexRuleTest.java
@@ -13,83 +13,68 @@
package org.eclipse.jetty.rewrite.handler;
-import java.io.IOException;
-
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.HttpTester;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
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.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
-public class TerminatingRegexRuleTest extends AbstractRuleTestCase
+public class TerminatingRegexRuleTest extends AbstractRuleTest
{
- private RewriteHandler rewriteHandler;
-
@BeforeEach
public void init() throws Exception
{
- rewriteHandler = new RewriteHandler();
- rewriteHandler.setServer(_server);
- rewriteHandler.setHandler(new AbstractHandler()
+ TerminatingRegexRule rule1 = new TerminatingRegexRule("^/login.jsp$");
+ _rewriteHandler.addRule(rule1);
+ RedirectRegexRule rule2 = new RedirectRegexRule("^/login.*$", "http://login.company.com/");
+ rule2.setStatusCode(HttpStatus.SEE_OTHER_303);
+ _rewriteHandler.addRule(rule2);
+ start(new Handler.Processor()
{
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException,
- ServletException
+ public void process(Request request, Response response, Callback callback)
{
response.setStatus(HttpStatus.CREATED_201);
- request.setAttribute("target", target);
- request.setAttribute("URI", request.getRequestURI());
- request.setAttribute("info", request.getPathInfo());
+ callback.succeeded();
}
});
- rewriteHandler.start();
-
- TerminatingRegexRule rule1 = new TerminatingRegexRule();
- rule1.setRegex("^/login.jsp$");
- rewriteHandler.addRule(rule1);
- RedirectRegexRule rule2 = new RedirectRegexRule("^/login.*$", "http://login.company.com/");
- rewriteHandler.addRule(rule2);
-
- start(false);
- }
-
- private void assertIsRedirect(int expectedStatus, String expectedLocation)
- {
- assertThat("Response Status", _response.getStatus(), is(expectedStatus));
- assertThat("Response Location Header", _response.getHeader(HttpHeader.LOCATION.asString()), is(expectedLocation));
- }
-
- private void assertIsRequest(String expectedRequestPath)
- {
- assertThat("Response Status", _response.getStatus(), is(HttpStatus.CREATED_201));
- assertThat("Request Target", _request.getAttribute("target"), is(expectedRequestPath));
}
@Test
- public void testTerminatingEarly() throws IOException, ServletException
+ public void testTerminatingEarly() throws Exception
{
- rewriteHandler.handle("/login.jsp", _request, _request, _response);
- assertIsRequest("/login.jsp");
+ String request = """
+ GET /login.jsp HTTP/1.1
+ Host: localhost
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.CREATED_201, response.getStatus());
+ assertNull(response.get(HttpHeader.LOCATION));
}
- @Test
- public void testNoTerminationDo() throws IOException, ServletException
+ @ParameterizedTest
+ @ValueSource(strings = {"/login.do", "/login/"})
+ public void testNonTerminating(String uri) throws Exception
{
- rewriteHandler.handle("/login.do", _request, _request, _response);
- assertIsRedirect(HttpStatus.MOVED_TEMPORARILY_302, "http://login.company.com/");
- }
+ String request = """
+ GET $U HTTP/1.1
+ Host: localhost
+
+ """.replace("$U", uri);
- @Test
- public void testNoTerminationDir() throws IOException, ServletException
- {
- rewriteHandler.handle("/login/", _request, _request, _response);
- assertIsRedirect(HttpStatus.MOVED_TEMPORARILY_302, "http://login.company.com/");
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.SEE_OTHER_303, response.getStatus());
+ assertEquals("http://login.company.com/", response.get(HttpHeader.LOCATION));
}
}
diff --git a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainerTest.java b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainerTest.java
index d057598244a..5c542ca3214 100644
--- a/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainerTest.java
+++ b/jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainerTest.java
@@ -13,186 +13,226 @@
package org.eclipse.jetty.rewrite.handler;
-import org.eclipse.jetty.http.HttpURI;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.HttpTester;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
-public class VirtualHostRuleContainerTest extends AbstractRuleTestCase
+public class VirtualHostRuleContainerTest extends AbstractRuleTest
{
- private RewriteHandler _handler;
- private RewritePatternRule _rule;
- private RewritePatternRule _fooRule;
- private VirtualHostRuleContainer _fooContainerRule;
+ private VirtualHostRuleContainer _virtualHostRules;
@BeforeEach
public void init() throws Exception
{
- _handler = new RewriteHandler();
- _handler.setRewriteRequestURI(true);
-
- _rule = new RewritePatternRule();
- _rule.setPattern("/cheese/*");
- _rule.setReplacement("/rule");
-
- _fooRule = new RewritePatternRule();
- _fooRule.setPattern("/cheese/bar/*");
- _fooRule.setReplacement("/cheese/fooRule");
-
- _fooContainerRule = new VirtualHostRuleContainer();
- _fooContainerRule.setVirtualHosts(new String[]{"foo.com"});
- _fooContainerRule.setRules(new Rule[]{_fooRule});
-
- start(false);
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/cheese/bar"));
-
- _handler.setServer(_server);
- _handler.start();
+ _virtualHostRules = new VirtualHostRuleContainer();
+ start(new Handler.Processor()
+ {
+ @Override
+ public void process(Request request, Response response, Callback callback)
+ {
+ response.setHeader("X-Path", request.getHttpURI().getPath());
+ callback.succeeded();
+ }
+ });
}
@Test
public void testArbitraryHost() throws Exception
{
- _request.setHttpURI(HttpURI.build(_request.getRequestURI()).authority("cheese.com", 0));
- _handler.setRules(new Rule[]{_rule, _fooContainerRule});
- handleRequest();
- assertEquals("/rule/bar", _request.getRequestURI(), "{_rule, _fooContainerRule, Host: cheese.com}: applied _rule");
+ _rewriteHandler.addRule(new RewritePatternRule("/cheese/*", "/rule"));
+ _rewriteHandler.addRule(_virtualHostRules);
+ _virtualHostRules.setVirtualHosts(List.of("foo.com"));
+ _virtualHostRules.addRule(new RewritePatternRule("/cheese/bar/*", "/cheese/fooRule"));
+
+ String request = """
+ GET /cheese/bar HTTP/1.1
+ Host: cheese.com
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ // VirtualHost rule does not apply, host does not match.
+ assertEquals("/rule/bar", response.get("X-Path"));
}
@Test
public void testVirtualHost() throws Exception
{
- _request.setHttpURI(HttpURI.build(_request.getRequestURI()).authority("foo.com", 0));
- _handler.setRules(new Rule[]{_fooContainerRule});
- handleRequest();
- assertEquals("/cheese/fooRule", _request.getRequestURI(), "{_fooContainerRule, Host: foo.com}: applied _fooRule");
+ _rewriteHandler.addRule(_virtualHostRules);
+ _virtualHostRules.setVirtualHosts(List.of("foo.com"));
+ _virtualHostRules.addRule(new RewritePatternRule("/cheese/bar/*", "/cheese/fooRule"));
+
+ String request = """
+ GET /cheese/bar HTTP/1.1
+ Host: foo.com
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertEquals("/cheese/fooRule", response.get("X-Path"));
}
@Test
public void testCascadingRules() throws Exception
{
- _request.setHttpURI(HttpURI.build(_request.getRequestURI()).authority("foo.com", 0));
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/cheese/bar"));
+ RewritePatternRule rule = new RewritePatternRule("/cheese/*", "/rule");
+ _rewriteHandler.addRule(rule);
+ _rewriteHandler.addRule(_virtualHostRules);
+ _virtualHostRules.setVirtualHosts(List.of("foo.com"));
+ _virtualHostRules.addRule(new RewritePatternRule("/cheese/bar/*", "/cheese/fooRule"));
- _rule.setTerminating(false);
- _fooRule.setTerminating(false);
- _fooContainerRule.setTerminating(false);
+ String request = """
+ GET /cheese/bar HTTP/1.1
+ Host: foo.com
+
+ """;
- _handler.setRules(new Rule[]{_rule, _fooContainerRule});
- handleRequest();
- assertEquals("/rule/bar", _request.getRequestURI(), "{_rule, _fooContainerRule}: applied _rule, didn't match _fooRule");
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertEquals("/rule/bar", response.get("X-Path"));
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/cheese/bar"));
- _handler.setRules(new Rule[]{_fooContainerRule, _rule});
- handleRequest();
- assertEquals("/rule/fooRule", _request.getRequestURI(), "{_fooContainerRule, _rule}: applied _fooRule, _rule");
+ _rewriteHandler.setRules(List.of(_virtualHostRules, rule));
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/cheese/bar"));
- _fooRule.setTerminating(true);
- handleRequest();
- assertEquals("/rule/fooRule", _request.getRequestURI(), "{_fooContainerRule, _rule}: (_fooRule is terminating); applied _fooRule, _rule");
+ request = """
+ GET /cheese/bar HTTP/1.1
+ Host: foo.com
+
+ """;
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/cheese/bar"));
- _fooRule.setTerminating(false);
- _fooContainerRule.setTerminating(true);
- handleRequest();
- assertEquals("/cheese/fooRule", _request.getRequestURI(), "{_fooContainerRule, _rule}: (_fooContainerRule is terminating); applied _fooRule, terminated before _rule");
+ response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertEquals("/rule/fooRule", response.get("X-Path"));
+
+ _virtualHostRules.setTerminating(true);
+
+ request = """
+ GET /cheese/bar HTTP/1.1
+ Host: foo.com
+
+ """;
+
+ response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertEquals("/cheese/fooRule", response.get("X-Path"));
}
@Test
public void testCaseInsensitiveHostname() throws Exception
{
- _request.setHttpURI(HttpURI.build(_request.getRequestURI()).authority("Foo.com", 0));
- _fooContainerRule.setVirtualHosts(new String[]{"foo.com"});
+ _rewriteHandler.addRule(_virtualHostRules);
+ _virtualHostRules.setVirtualHosts(List.of("foo.com"));
+ _virtualHostRules.addRule(new RewritePatternRule("/cheese/bar/*", "/cheese/fooRule"));
- _handler.setRules(new Rule[]{_fooContainerRule});
- handleRequest();
- assertEquals("/cheese/fooRule", _request.getRequestURI(), "Foo.com and foo.com are equivalent");
+ String request = """
+ GET /cheese/bar HTTP/1.1
+ Host: Foo.com
+
+ """;
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertEquals("/cheese/fooRule", response.get("X-Path"));
}
@Test
public void testEmptyVirtualHost() throws Exception
{
- _request.setHttpURI(HttpURI.build(_request.getRequestURI()).authority("cheese.com", 0));
+ _rewriteHandler.addRule(_virtualHostRules);
+ _virtualHostRules.addRule(new RewritePatternRule("/cheese/bar/*", "/cheese/fooRule"));
- _handler.setRules(new Rule[]{_fooContainerRule});
- _fooContainerRule.setVirtualHosts(null);
- handleRequest();
- assertEquals("/cheese/fooRule", _request.getRequestURI(), "{_fooContainerRule: virtual hosts array is null, Host: cheese.com}: apply _fooRule");
+ List> cases = Arrays.asList(null, List.of(), Collections.singletonList(null));
+ for (List virtualHosts : cases)
+ {
+ _virtualHostRules.setVirtualHosts(virtualHosts);
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/cheese/bar"));
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/cheese/bar"));
- _fooContainerRule.setVirtualHosts(new String[]{});
- handleRequest();
- assertEquals("/cheese/fooRule", _request.getRequestURI(), "{_fooContainerRule: virtual hosts array is empty, Host: cheese.com}: apply _fooRule");
+ String request = """
+ GET /cheese/bar HTTP/1.1
+ Host: cheese.com
+
+ """;
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/cheese/bar"));
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/cheese/bar"));
- _fooContainerRule.setVirtualHosts(new String[]{null});
- handleRequest();
- assertEquals("/cheese/fooRule", _request.getRequestURI(), "{_fooContainerRule: virtual host is null, Host: cheese.com}: apply _fooRule");
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertEquals("/cheese/fooRule", response.get("X-Path"));
+ }
}
@Test
public void testMultipleVirtualHosts() throws Exception
{
- _request.setHttpURI(HttpURI.build(_request.getRequestURI()).authority("foo.com", 0));
- _handler.setRules(new Rule[]{_fooContainerRule});
+ _rewriteHandler.addRule(_virtualHostRules);
+ _virtualHostRules.setVirtualHosts(List.of("cheese.com"));
+ _virtualHostRules.addRule(new RewritePatternRule("/cheese/bar/*", "/cheese/fooRule"));
- _fooContainerRule.setVirtualHosts(new String[]{"cheese.com"});
- handleRequest();
- assertEquals("/cheese/bar", _request.getRequestURI(), "{_fooContainerRule: vhosts[cheese.com], Host: foo.com}: no effect");
+ String request = """
+ GET /cheese/bar HTTP/1.1
+ Host: foo.com
+
+ """;
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/cheese/bar"));
- _fooContainerRule.addVirtualHost("foo.com");
- handleRequest();
- assertEquals("/cheese/fooRule", _request.getRequestURI(), "{_fooContainerRule: vhosts[cheese.com, foo.com], Host: foo.com}: apply _fooRule");
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertEquals("/cheese/bar", response.get("X-Path"));
+
+ _virtualHostRules.addVirtualHost("foo.com");
+
+ request = """
+ GET /cheese/bar HTTP/1.1
+ Host: foo.com
+
+ """;
+
+ response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertEquals("/cheese/fooRule", response.get("X-Path"));
}
@Test
public void testWildcardVirtualHosts() throws Exception
{
- checkWildcardHost(true, null, new String[]{"foo.com", ".foo.com", "vhost.foo.com"});
- checkWildcardHost(true, new String[]{null}, new String[]{"foo.com", ".foo.com", "vhost.foo.com"});
-
- checkWildcardHost(true, new String[]{"foo.com", "*.foo.com"}, new String[]{"foo.com", ".foo.com", "vhost.foo.com"});
- checkWildcardHost(false, new String[]{"foo.com", "*.foo.com"}, new String[]{
- "badfoo.com", ".badfoo.com", "vhost.badfoo.com"
- });
-
- checkWildcardHost(false, new String[]{"*."}, new String[]{"anything.anything"});
-
- checkWildcardHost(true, new String[]{"*.foo.com"}, new String[]{"vhost.foo.com", ".foo.com"});
- checkWildcardHost(false, new String[]{"*.foo.com"}, new String[]{"vhost.www.foo.com", "foo.com", "www.vhost.foo.com"});
-
- checkWildcardHost(true, new String[]{"*.sub.foo.com"}, new String[]{"vhost.sub.foo.com", ".sub.foo.com"});
- checkWildcardHost(false, new String[]{"*.sub.foo.com"}, new String[]{".foo.com", "sub.foo.com", "vhost.foo.com"});
-
- checkWildcardHost(false, new String[]{"foo.*.com", "foo.com.*"}, new String[]{
- "foo.vhost.com", "foo.com.vhost", "foo.com"
- });
+ testWildcardVirtualHost(true, List.of("foo.com", "*.foo.com"), List.of("foo.com", ".foo.com", "vhost.foo.com"));
+ testWildcardVirtualHost(false, List.of("foo.com", "*.foo.com"), List.of("badfoo.com", ".badfoo.com", "vhost.badfoo.com"));
+ testWildcardVirtualHost(false, List.of("*."), List.of("anything.anything"));
+ testWildcardVirtualHost(true, List.of("*.foo.com"), List.of("vhost.foo.com", ".foo.com"));
+ testWildcardVirtualHost(false, List.of("*.foo.com"), List.of("vhost.www.foo.com", "foo.com", "www.vhost.foo.com"));
+ testWildcardVirtualHost(true, List.of("*.sub.foo.com"), List.of("vhost.sub.foo.com", ".sub.foo.com"));
+ testWildcardVirtualHost(false, List.of("*.sub.foo.com"), List.of(".foo.com", "sub.foo.com", "vhost.foo.com"));
+ testWildcardVirtualHost(false, List.of("foo.*.com", "foo.com.*"), List.of("foo.vhost.com", "foo.com.vhost", "foo.com"));
}
- private void checkWildcardHost(boolean succeed, String[] ruleHosts, String[] requestHosts) throws Exception
+ private void testWildcardVirtualHost(boolean succeed, List ruleHosts, List requestHosts) throws Exception
{
- _fooContainerRule.setVirtualHosts(ruleHosts);
- _handler.setRules(new Rule[]{_fooContainerRule});
+ _rewriteHandler.addRule(_virtualHostRules);
+ _virtualHostRules.setVirtualHosts(ruleHosts);
+ _virtualHostRules.addRule(new RewritePatternRule("/cheese/bar/*", "/cheese/fooRule"));
- for (String host : requestHosts)
+ for (String requestHost : requestHosts)
{
- _request.setHttpURI(HttpURI.build(_request.getRequestURI()).authority(host, 0));
- _request.setHttpURI(HttpURI.build(_request.getHttpURI(), "/cheese/bar"));
- handleRequest();
+ String request = """
+ GET /cheese/bar HTTP/1.1
+ Host: $H
+
+ """.replace("$H", requestHost);
+
+ HttpTester.Response response = HttpTester.parseResponse(_connector.getResponse(request));
+ assertEquals(HttpStatus.OK_200, response.getStatus());
if (succeed)
- assertEquals("/cheese/fooRule", _request.getRequestURI(), "{_fooContainerRule, Host: " + host + "}: should apply _fooRule");
+ assertEquals("/cheese/fooRule", response.get("X-Path"));
else
- assertEquals("/cheese/bar", _request.getRequestURI(), "{_fooContainerRule, Host: " + host + "}: should not apply _fooRule");
+ assertEquals("/cheese/bar", response.get("X-Path"));
}
}
-
- private void handleRequest() throws Exception
- {
- _handler.handle("/cheese/bar", _request, _request, _response);
- }
}
diff --git a/jetty-core/jetty-rewrite/src/test/resources/jetty-logging.properties b/jetty-core/jetty-rewrite/src/test/resources/jetty-logging.properties
new file mode 100644
index 00000000000..481be7a1eaf
--- /dev/null
+++ b/jetty-core/jetty-rewrite/src/test/resources/jetty-logging.properties
@@ -0,0 +1,2 @@
+#org.eclipse.jetty.LEVEL=DEBUG
+#org.eclipse.jetty.rewrite.LEVEL=DEBUG
diff --git a/jetty-rewrite/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml b/jetty-core/jetty-rewrite/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml
similarity index 99%
rename from jetty-rewrite/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml
rename to jetty-core/jetty-rewrite/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml
index 2688e21964c..4c1bfd390b5 100644
--- a/jetty-rewrite/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml
+++ b/jetty-core/jetty-rewrite/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml
@@ -53,7 +53,7 @@
AVAILABLE
- // STARTING -----false--> UNAVAILABLE
- // AVAILABLE ----false--> UNAVAILABLE
- if (available)
- {
- while (true)
- {
- Availability availability = _availability.get();
- switch (availability)
- {
- case AVAILABLE:
- break;
- case UNAVAILABLE:
- if (!_availability.compareAndSet(availability, Availability.AVAILABLE))
- continue;
- break;
- default:
- throw new IllegalStateException(availability.toString());
- }
- break;
- }
- }
- else
- {
- while (true)
- {
- Availability availability = _availability.get();
- switch (availability)
- {
- case STARTING:
- case AVAILABLE:
- if (!_availability.compareAndSet(availability, Availability.UNAVAILABLE))
- continue;
- break;
- default:
- break;
- }
- break;
- }
- }
- }
-
- public Logger getLogger()
- {
- return _logger;
- }
-
- public void setLogger(Logger logger)
- {
- _logger = logger;
+ // TODO
}
@Override
protected void doStart() throws Exception
{
- if (_contextPath == null)
+ if (getContextPath() == null)
throw new IllegalStateException("Null contextPath");
- if (getBaseResource() != null && getBaseResource().isAlias())
- LOG.warn("BaseResource {} is aliased to {} in {}. May not be supported in future releases.",
- getBaseResource(), getBaseResource().getAlias(), this);
-
- _availability.set(Availability.STARTING);
-
- if (_logger == null)
- _logger = LoggerFactory.getLogger(ContextHandler.class.getName() + getLogNameSuffix());
-
- ClassLoader oldClassloader = null;
- Thread currentThread = null;
- Context oldContext = null;
-
- _attributes.setAttribute("org.eclipse.jetty.server.Executor", getServer().getThreadPool());
-
- if (_mimeTypes == null)
- _mimeTypes = new MimeTypes();
-
- _durableListeners.addAll(getEventListeners());
-
- try
- {
- // Set the classloader, context and enter scope
- if (_classLoader != null)
- {
- currentThread = Thread.currentThread();
- oldClassloader = currentThread.getContextClassLoader();
- currentThread.setContextClassLoader(_classLoader);
- }
- oldContext = __context.get();
- __context.set(_scontext);
- enterScope(null, getState());
-
- // defers the calling of super.doStart()
- startContext();
-
- contextInitialized();
-
- _availability.compareAndSet(Availability.STARTING, Availability.AVAILABLE);
- LOG.info("Started {}", this);
- }
- finally
- {
- _availability.compareAndSet(Availability.STARTING, Availability.UNAVAILABLE);
- exitScope(null);
- __context.set(oldContext);
- // reset the classloader
- if (_classLoader != null && currentThread != null)
- currentThread.setContextClassLoader(oldClassloader);
- }
- }
-
- private String getLogNameSuffix()
- {
- // Use display name first
- String logName = getDisplayName();
- if (StringUtil.isBlank(logName))
- {
- // try context path
- logName = getContextPath();
- if (logName != null)
- {
- // Strip prefix slash
- if (logName.startsWith("/"))
- {
- logName = logName.substring(1);
- }
- }
-
- if (StringUtil.isBlank(logName))
- {
- // an empty context path is the ROOT context
- logName = "ROOT";
- }
- }
-
- // Replace bad characters.
- return '.' + logName.replaceAll("\\W", "_");
- }
-
- /**
- * Extensible startContext. this method is called from {@link ContextHandler#doStart()} instead of a call to super.doStart(). This allows derived classes to
- * insert additional handling (Eg configuration) before the call to super.doStart by this method will start contained handlers.
- *
- * @throws Exception if unable to start the context
- * @see ContextHandler.Context
- */
- protected void startContext() throws Exception
- {
- String managedAttributes = _initParams.get(MANAGED_ATTRIBUTES);
- if (managedAttributes != null)
- addEventListener(new ManagedAttributeListener(this, StringUtil.csvSplit(managedAttributes)));
-
- super.doStart();
- }
-
- /**
- * Call the ServletContextListeners contextInitialized methods.
- * This can be called from a ServletHandler during the proper sequence
- * of initializing filters, servlets and listeners. However, if there is
- * no ServletHandler, the ContextHandler will call this method during
- * doStart().
- */
- public void contextInitialized() throws Exception
- {
- // Call context listeners
- if (_contextStatus == ContextStatus.NOTSET)
- {
- _contextStatus = ContextStatus.INITIALIZED;
- _destroyServletContextListeners.clear();
- if (!_servletContextListeners.isEmpty())
- {
- ServletContextEvent event = new ServletContextEvent(_scontext);
- for (ServletContextListener listener : _servletContextListeners)
- {
- callContextInitialized(listener, event);
- _destroyServletContextListeners.add(listener);
- }
- }
- }
- }
-
- /**
- * Call the ServletContextListeners with contextDestroyed.
- * This method can be called from a ServletHandler in the
- * proper sequence of destroying filters, servlets and listeners.
- * If there is no ServletHandler, the ContextHandler must ensure
- * these listeners are called instead.
- */
- public void contextDestroyed() throws Exception
- {
- switch (_contextStatus)
- {
- case INITIALIZED:
- {
- try
- {
- //Call context listeners
- MultiException ex = new MultiException();
- ServletContextEvent event = new ServletContextEvent(_scontext);
- Collections.reverse(_destroyServletContextListeners);
- for (ServletContextListener listener : _destroyServletContextListeners)
- {
- try
- {
- callContextDestroyed(listener, event);
- }
- catch (Exception x)
- {
- ex.add(x);
- }
- }
- ex.ifExceptionThrow();
- }
- finally
- {
- _contextStatus = ContextStatus.DESTROYED;
- }
- break;
- }
- default:
- break;
- }
- }
-
- protected void stopContext() throws Exception
- {
- // stop all the handler hierarchy
- super.doStop();
- }
-
- protected void callContextInitialized(ServletContextListener l, ServletContextEvent e)
- {
- if (getServer().isDryRun())
- return;
-
- if (LOG.isDebugEnabled())
- LOG.debug("contextInitialized: {}->{}", e, l);
- l.contextInitialized(e);
- }
-
- protected void callContextDestroyed(ServletContextListener l, ServletContextEvent e)
- {
- if (getServer().isDryRun())
- return;
-
- if (LOG.isDebugEnabled())
- LOG.debug("contextDestroyed: {}->{}", e, l);
- l.contextDestroyed(e);
+ // TODO lots of stuff in previous doStart. Some might go here, but most probably goes to the ServletContentHandler ?
+ _context.call(super::doStart, null);
}
@Override
protected void doStop() throws Exception
{
- // Should we attempt a graceful shutdown?
- MultiException mex = null;
-
- _availability.set(Availability.STOPPED);
-
- ClassLoader oldClassloader = null;
- ClassLoader oldWebapploader = null;
- Thread currentThread = null;
- Context oldContext = __context.get();
- enterScope(null, "doStop");
- __context.set(_scontext);
- try
- {
- // Set the classloader
- if (_classLoader != null)
- {
- oldWebapploader = _classLoader;
- currentThread = Thread.currentThread();
- oldClassloader = currentThread.getContextClassLoader();
- currentThread.setContextClassLoader(_classLoader);
- }
-
- stopContext();
-
- contextDestroyed();
-
- // retain only durable listeners
- setEventListeners(_durableListeners);
- _durableListeners.clear();
-
- if (_errorHandler != null)
- _errorHandler.stop();
-
- for (EventListener l : _programmaticListeners)
- {
- removeEventListener(l);
- if (l instanceof ContextScopeListener)
- {
- try
- {
- ((ContextScopeListener)l).exitScope(_scontext, null);
- }
- catch (Throwable e)
- {
- LOG.warn("Unable to exit scope", e);
- }
- }
- }
- _programmaticListeners.clear();
- }
- catch (Throwable x)
- {
- if (mex == null)
- mex = new MultiException();
- mex.add(x);
- }
- finally
- {
- _contextStatus = ContextStatus.NOTSET;
- __context.set(oldContext);
- exitScope(null);
- LOG.info("Stopped {}", this);
- // reset the classloader
- if ((oldClassloader == null || (oldClassloader != oldWebapploader)) && currentThread != null)
- currentThread.setContextClassLoader(oldClassloader);
-
- _scontext.clearAttributes();
- }
-
- if (mex != null)
- mex.ifExceptionThrow();
+ // TODO lots of stuff in previous doStart. Some might go here, but most probably goes to the ServletContentHandler ?
+ _context.call(super::doStop, null);
}
- public boolean checkVirtualHost(final Request baseRequest)
+ public boolean checkVirtualHost(Request request)
{
- if (_vhosts == null || _vhosts.length == 0)
+ if (_vhosts.isEmpty())
return true;
- String vhost = normalizeHostname(baseRequest.getServerName());
- String connectorName = baseRequest.getHttpChannel().getConnector().getName();
+ // TODO is this correct?
+ String host = request.getHttpURI().getHost();
- for (int i = 0; i < _vhosts.length; i++)
+ String connectorName = request.getConnectionMetaData().getConnector().getName();
+
+ for (VHost vhost : _vhosts)
{
- String contextVhost = _vhosts[i];
- String contextVConnector = _vconnectors[i];
+ String contextVhost = vhost._vHost;
+ String contextVConnector = vhost._vConnector;
if (contextVConnector != null)
{
@@ -1152,16 +503,16 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
if (contextVhost != null)
{
- if (_vhostswildcard[i])
+ if (vhost._wild)
{
// wildcard only at the beginning, and only for one additional subdomain level
- int index = vhost.indexOf(".");
- if (index >= 0 && vhost.substring(index).equalsIgnoreCase(contextVhost))
+ int index = host.indexOf(".");
+ if (index >= 0 && host.substring(index).equalsIgnoreCase(contextVhost))
{
return true;
}
}
- else if (vhost.equalsIgnoreCase(contextVhost))
+ else if (host.equalsIgnoreCase(contextVhost))
{
return true;
}
@@ -1170,451 +521,91 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
return false;
}
- public boolean checkContextPath(String uri)
+ protected String getPathInContext(Request request)
{
- // Are we not the root context?
- if (_contextPath.length() > 1)
- {
- // reject requests that are not for us
- if (!uri.startsWith(_contextPath))
- return false;
- if (uri.length() > _contextPath.length() && uri.charAt(_contextPath.length()) != '/')
- return false;
- }
- return true;
- }
-
- /*
- * @see org.eclipse.jetty.server.Handler#handle(jakarta.servlet.http.HttpServletRequest, jakarta.servlet.http.HttpServletResponse)
- */
- public boolean checkContext(final String target, final Request baseRequest, final HttpServletResponse response) throws IOException
- {
- DispatcherType dispatch = baseRequest.getDispatcherType();
-
- // Check the vhosts
- if (!checkVirtualHost(baseRequest))
- return false;
-
- if (!checkContextPath(target))
- return false;
-
- // Are we not the root context?
- // redirect null path infos
- if (!_allowNullPathInfo && _contextPath.length() == target.length() && _contextPath.length() > 1)
- {
- // context request must end with /
- baseRequest.setHandled(true);
- String queryString = baseRequest.getQueryString();
- baseRequest.getResponse().sendRedirect(
- HttpServletResponse.SC_MOVED_TEMPORARILY,
- baseRequest.getRequestURI() + (queryString == null ? "/" : ("/?" + queryString)),
- true);
- return false;
- }
-
- switch (_availability.get())
- {
- case STOPPED:
- return false;
- case SHUTDOWN:
- case UNAVAILABLE:
- baseRequest.setHandled(true);
- response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
- return false;
- default:
- if ((DispatcherType.REQUEST.equals(dispatch) && baseRequest.isHandled()))
- return false;
- }
-
- return true;
+ String path = request.getPathInContext();
+ if (!path.startsWith(_context.getContextPath()))
+ return null;
+ if ("/".equals(_context.getContextPath()))
+ return path;
+ if (path.length() == _context.getContextPath().length())
+ return "";
+ if (path.charAt(_context.getContextPath().length()) != '/')
+ return null;
+ return path.substring(_context.getContextPath().length());
}
@Override
- public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ public void destroy()
{
- if (LOG.isDebugEnabled())
- LOG.debug("scope {}|{}|{} @ {}", baseRequest.getContextPath(), baseRequest.getServletPath(), baseRequest.getPathInfo(), this);
-
- final Thread currentThread = Thread.currentThread();
- final ClassLoader oldClassloader = currentThread.getContextClassLoader();
- Context oldContext;
- String oldPathInContext = baseRequest.getPathInContext();;
- String pathInContext = target;
-
- DispatcherType dispatch = baseRequest.getDispatcherType();
-
- oldContext = baseRequest.getContext();
-
- // Are we already in this context?
- if (oldContext != _scontext)
- {
- // check the target.
- if (DispatcherType.REQUEST.equals(dispatch) || DispatcherType.ASYNC.equals(dispatch))
- {
- // TODO: remove this once isCompact() has been deprecated for several releases.
- if (isCompactPath())
- target = URIUtil.compactPath(target);
- if (!checkContext(target, baseRequest, response))
- return;
-
- if (target.length() > _contextPath.length())
- {
- if (_contextPath.length() > 1)
- target = target.substring(_contextPath.length());
- pathInContext = target;
- }
- else if (_contextPath.length() == 1)
- {
- target = URIUtil.SLASH;
- pathInContext = URIUtil.SLASH;
- }
- else
- {
- target = URIUtil.SLASH;
- pathInContext = null;
- }
- }
- }
-
- if (_classLoader != null)
- currentThread.setContextClassLoader(_classLoader);
-
- try
- {
- // Update the paths
- baseRequest.setContext(_scontext,
- (DispatcherType.INCLUDE.equals(dispatch) || !target.startsWith("/")) ? oldPathInContext : pathInContext);
-
- if (oldContext != _scontext)
- {
- __context.set(_scontext);
- enterScope(baseRequest, dispatch);
- }
-
- if (LOG.isDebugEnabled())
- LOG.debug("context={}|{}|{} @ {}", baseRequest.getContextPath(), baseRequest.getServletPath(), baseRequest.getPathInfo(), this);
-
- nextScope(target, baseRequest, request, response);
- }
- finally
- {
- if (oldContext != _scontext)
- {
- exitScope(baseRequest);
-
- // reset the classloader
- if (_classLoader != null)
- currentThread.setContextClassLoader(oldClassloader);
-
- // reset the context
- __context.set(oldContext);
- }
-
- // reset pathInContext
- baseRequest.setContext(oldContext, oldPathInContext);
- }
- }
-
- protected void requestInitialized(Request baseRequest, HttpServletRequest request)
- {
- // Handle the REALLY SILLY request events!
- if (!_servletRequestAttributeListeners.isEmpty())
- for (ServletRequestAttributeListener l : _servletRequestAttributeListeners)
- {
- baseRequest.addEventListener(l);
- }
-
- if (!_servletRequestListeners.isEmpty())
- {
- final ServletRequestEvent sre = new ServletRequestEvent(_scontext, request);
- for (ServletRequestListener l : _servletRequestListeners)
- {
- l.requestInitialized(sre);
- }
- }
- }
-
- protected void requestDestroyed(Request baseRequest, HttpServletRequest request)
- {
- // Handle more REALLY SILLY request events!
- if (!_servletRequestListeners.isEmpty())
- {
- final ServletRequestEvent sre = new ServletRequestEvent(_scontext, request);
- for (int i = _servletRequestListeners.size(); i-- > 0; )
- {
- _servletRequestListeners.get(i).requestDestroyed(sre);
- }
- }
-
- if (!_servletRequestAttributeListeners.isEmpty())
- {
- for (int i = _servletRequestAttributeListeners.size(); i-- > 0; )
- {
- baseRequest.removeEventListener(_servletRequestAttributeListeners.get(i));
- }
- }
+ _context.run(super::destroy);
}
@Override
- public void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ public Request.Processor handle(Request request) throws Exception
{
- final DispatcherType dispatch = baseRequest.getDispatcherType();
- final boolean new_context = baseRequest.takeNewContext();
- try
- {
- if (new_context)
- requestInitialized(baseRequest, request);
-
- if (dispatch == DispatcherType.REQUEST && isProtectedTarget(target))
- {
- baseRequest.setHandled(true);
- response.sendError(HttpServletResponse.SC_NOT_FOUND);
- return;
- }
-
- nextHandle(target, baseRequest, request, response);
- }
- finally
- {
- if (new_context)
- requestDestroyed(baseRequest, request);
- }
- }
-
- /**
- * @param request A request that is applicable to the scope, or null
- * @param reason An object that indicates the reason the scope is being entered.
- */
- protected void enterScope(Request request, Object reason)
- {
- if (!_contextListeners.isEmpty())
- {
- for (ContextScopeListener listener : _contextListeners)
- {
- try
- {
- listener.enterScope(_scontext, request, reason);
- }
- catch (Throwable e)
- {
- LOG.warn("Unable to enter scope", e);
- }
- }
- }
- }
-
- /**
- * @param request A request that is applicable to the scope, or null
- */
- protected void exitScope(Request request)
- {
- if (!_contextListeners.isEmpty())
- {
- for (int i = _contextListeners.size(); i-- > 0; )
- {
- try
- {
- _contextListeners.get(i).exitScope(_scontext, request);
- }
- catch (Throwable e)
- {
- LOG.warn("Unable to exit scope", e);
- }
- }
- }
- }
-
- /**
- * Handle a runnable in the scope of this context and a particular request
- *
- * @param request The request to scope the thread to (may be null if no particular request is in scope)
- * @param runnable The runnable to run.
- */
- public void handle(Request request, Runnable runnable)
- {
- ClassLoader oldClassloader = null;
- Thread currentThread = null;
- Context oldContext = __context.get();
-
- // Are we already in the scope?
- if (oldContext == _scontext)
- {
- runnable.run();
- return;
- }
-
- // Nope, so enter the scope and then exit
- try
- {
- __context.set(_scontext);
-
- // Set the classloader
- if (_classLoader != null)
- {
- currentThread = Thread.currentThread();
- oldClassloader = currentThread.getContextClassLoader();
- currentThread.setContextClassLoader(_classLoader);
- }
-
- enterScope(request, runnable);
- runnable.run();
- }
- finally
- {
- exitScope(request);
-
- __context.set(oldContext);
- if (oldClassloader != null)
- {
- currentThread.setContextClassLoader(oldClassloader);
- }
- }
- }
-
- /*
- * Handle a runnable in the scope of this context
- */
- public void handle(Runnable runnable)
- {
- handle(null, runnable);
- }
-
- /**
- * Check the target. Called by {@link #handle(String, Request, HttpServletRequest, HttpServletResponse)} when a target within a context is determined. If
- * the target is protected, 404 is returned.
- *
- * @param target the target to test
- * @return true if target is a protected target
- */
- public boolean isProtectedTarget(String target)
- {
- if (target == null || _protectedTargets.isEmpty())
- return false;
-
- if (target.startsWith("//"))
- target = URIUtil.compactPath(target);
-
- ProtectedTargetType type = _protectedTargets.getBest(target);
-
- return type == ProtectedTargetType.PREFIX ||
- type == ProtectedTargetType.EXACT && _protectedTargets.get(target) == ProtectedTargetType.EXACT;
- }
-
- /**
- * @param targets Array of URL prefix. Each prefix is in the form /path and will match either /path exactly or /path/anything
- */
- public void setProtectedTargets(String[] targets)
- {
- Index.Builder builder = new Index.Builder<>();
- if (targets != null)
- {
- for (String t : targets)
- {
- if (!t.startsWith("/"))
- throw new IllegalArgumentException("Bad protected target: " + t);
-
- builder.with(t, ProtectedTargetType.EXACT);
- builder.with(t + "/", ProtectedTargetType.PREFIX);
- builder.with(t + "?", ProtectedTargetType.PREFIX);
- builder.with(t + "#", ProtectedTargetType.PREFIX);
- builder.with(t + ";", ProtectedTargetType.PREFIX);
- }
- }
- _protectedTargets = builder.caseSensitive(false).build();
- }
-
- public String[] getProtectedTargets()
- {
- if (_protectedTargets == null)
+ if (getHandler() == null)
return null;
- return _protectedTargets.keySet().stream()
- .filter(s -> _protectedTargets.get(s) == ProtectedTargetType.EXACT)
- .toArray(String[]::new);
+ if (!checkVirtualHost(request))
+ return null;
+
+ String pathInContext = getPathInContext(request);
+ if (pathInContext == null)
+ return null;
+
+ if (pathInContext.isEmpty() && !getAllowNullPathInContext())
+ return this::processMovedPermanently;
+
+ // TODO check availability and maybe return a 503
+ if (!isAvailable() && isStarted())
+ return this::processUnavailable;
+
+ ContextRequest contextRequest = wrap(request, pathInContext);
+ // wrap might fail (eg ServletContextHandler could not match a servlet)
+ if (contextRequest == null)
+ return null;
+
+ Request.Processor processor = processByContextHandler(contextRequest);
+ if (processor != null)
+ return processor;
+
+ return contextRequest.wrapProcessor(_context.get(contextRequest, contextRequest));
}
- @Override
- public void removeAttribute(String name)
+ protected void processMovedPermanently(Request request, Response response, Callback callback)
{
- _attributes.removeAttribute(name);
+ String location = _contextPath + "/";
+ if (request.getHttpURI().getParam() != null)
+ location += ";" + request.getHttpURI().getParam();
+ if (request.getHttpURI().getQuery() != null)
+ location += ";" + request.getHttpURI().getQuery();
+
+ response.setStatus(HttpStatus.MOVED_PERMANENTLY_301);
+ response.getHeaders().add(new HttpField(HttpHeader.LOCATION, location));
+ callback.succeeded();
}
- /*
- * Set a context attribute. Attributes set via this API cannot be overridden by the ServletContext.setAttribute API. Their lifecycle spans the stop/start of
- * a context. No attribute listener events are triggered by this API.
- *
- * @see jakarta.servlet.ServletContext#setAttribute(java.lang.String, java.lang.Object)
- */
- @Override
- public void setAttribute(String name, Object value)
+ protected void processUnavailable(Request request, Response response, Callback callback)
{
- _attributes.setAttribute(name, value);
+ Response.writeError(request, response, callback, HttpStatus.SERVICE_UNAVAILABLE_503, null);
}
- /**
- * @param attributes The attributes to set.
- */
- public void setAttributes(Attributes attributes)
+ protected Request.Processor processByContextHandler(ContextRequest contextRequest)
{
- _attributes.clearAttributes();
- _attributes.addAll(attributes);
- }
-
- @Override
- public void clearAttributes()
- {
- _attributes.clearAttributes();
- }
-
- /**
- * @param classLoader The classLoader to set.
- */
- public void setClassLoader(ClassLoader classLoader)
- {
- if (isStarted())
- throw new IllegalStateException(getState());
- _classLoader = classLoader;
- }
-
- /**
- * Set the default context path.
- * A default context path may be overriden by a default-context-path element
- * in a web.xml
- *
- * @param contextPath The _contextPath to set.
- */
- public void setDefaultContextPath(String contextPath)
- {
- setContextPath(contextPath);
- _contextPathDefault = true;
- }
-
- public void setDefaultRequestCharacterEncoding(String encoding)
- {
- _defaultRequestCharacterEncoding = encoding;
- }
-
- public String getDefaultRequestCharacterEncoding()
- {
- return _defaultRequestCharacterEncoding;
- }
-
- public void setDefaultResponseCharacterEncoding(String encoding)
- {
- _defaultResponseCharacterEncoding = encoding;
- }
-
- public String getDefaultResponseCharacterEncoding()
- {
- return _defaultResponseCharacterEncoding;
- }
-
- /**
- * @return True if the current contextPath is from default settings
- */
- public boolean isContextPathDefault()
- {
- return _contextPathDefault;
+ if (!_allowNullPathInContext && StringUtil.isEmpty(contextRequest.getPathInContext()))
+ {
+ return (request, response, callback) ->
+ {
+ // context request must end with /
+ String queryString = request.getHttpURI().getQuery();
+ Response.sendRedirect(request, response, callback,
+ HttpStatus.MOVED_TEMPORARILY_302,
+ request.getHttpURI().getPath() + (queryString == null ? "/" : ("/?" + queryString)),
+ true);
+ };
+ }
+ return null;
}
/**
@@ -1622,42 +613,9 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
*/
public void setContextPath(String contextPath)
{
- if (contextPath == null)
- throw new IllegalArgumentException("null contextPath");
-
- if (contextPath.endsWith("/*"))
- {
- LOG.warn("{} contextPath ends with /*", this);
- contextPath = contextPath.substring(0, contextPath.length() - 2);
- }
- else if (contextPath.length() > 1 && contextPath.endsWith("/"))
- {
- LOG.warn("{} contextPath ends with /", this);
- contextPath = contextPath.substring(0, contextPath.length() - 1);
- }
-
- if (contextPath.length() == 0)
- {
- LOG.warn("Empty contextPath");
- contextPath = "/";
- }
-
+ if (isStarted())
+ throw new IllegalStateException(getState());
_contextPath = contextPath;
- _contextPathEncoded = URIUtil.encodePath(contextPath);
- _contextPathDefault = false;
-
- if (getServer() != null && (getServer().isStarting() || getServer().isStarted()))
- {
- Class handlerClass = ContextHandlerCollection.class;
- Handler[] contextCollections = getServer().getChildHandlersByClass(handlerClass);
- if (contextCollections != null)
- {
- for (Handler contextCollection : contextCollections)
- {
- handlerClass.cast(contextCollection).mapContexts();
- }
- }
- }
}
/**
@@ -1668,384 +626,82 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
_displayName = servletContextName;
}
- /**
- * @return Returns the resourceBase.
- */
- public Resource getBaseResource()
- {
- if (_baseResource == null)
- return null;
- return _baseResource;
- }
-
/**
* @return Returns the base resource as a string.
*/
@ManagedAttribute("document root for context")
- public String getResourceBase()
+ public Path getResourceBase()
{
- if (_baseResource == null)
- return null;
- return _baseResource.toString();
+ return _resourceBase;
}
/**
* Set the base resource for this context.
*
- * @param base The resource used as the base for all static content of this context.
- * @see #setResourceBase(String)
+ * @param resourceBase The Path of the base resource for the context.
*/
- public void setBaseResource(Resource base)
+ public void setResourceBase(Path resourceBase)
{
if (isStarted())
- throw new IllegalStateException("Cannot call setBaseResource after starting");
- _baseResource = base;
- }
-
- /**
- * Set the base resource for this context.
- *
- * @param resourceBase A string representing the base resource for the context. Any string accepted by {@link Resource#newResource(String)} may be passed and the
- * call is equivalent to setBaseResource(newResource(resourceBase));
- */
- public void setResourceBase(String resourceBase)
- {
- try
- {
- setBaseResource(newResource(resourceBase));
- }
- catch (Exception e)
- {
- if (LOG.isDebugEnabled())
- LOG.warn("Unable to set baseResource: {}", resourceBase, e);
- else
- LOG.warn(e.toString());
- throw new IllegalArgumentException(resourceBase);
- }
- }
-
- /**
- * @return Returns the mimeTypes.
- */
- public MimeTypes getMimeTypes()
- {
- if (_mimeTypes == null)
- _mimeTypes = new MimeTypes();
- return _mimeTypes;
- }
-
- /**
- * @param mimeTypes The mimeTypes to set.
- */
- public void setMimeTypes(MimeTypes mimeTypes)
- {
- _mimeTypes = mimeTypes;
- }
-
- public void setWelcomeFiles(String[] files)
- {
- _welcomeFiles = files;
- }
-
- /**
- * @return The names of the files which the server should consider to be welcome files in this context.
- * @see The Servlet Specification
- * @see #setWelcomeFiles
- */
- @ManagedAttribute(value = "Partial URIs of directory welcome files", readonly = true)
- public String[] getWelcomeFiles()
- {
- return _welcomeFiles;
+ throw new IllegalStateException(getState());
+ _resourceBase = resourceBase;
}
/**
* @return Returns the errorHandler.
*/
- @ManagedAttribute("The error handler to use for the context")
- public ErrorHandler getErrorHandler()
+ @ManagedAttribute("The error processor to use for the context")
+ public Request.Processor getErrorProcessor()
{
- return _errorHandler;
+ // TODO, do we need to wrap this so that we can establish the context
+ // Classloader? Or will the caller already do that?
+ return _errorProcessor;
}
/**
- * @param errorHandler The errorHandler to set.
+ * @param errorProcessor The error processor to set.
*/
- public void setErrorHandler(ErrorHandler errorHandler)
+ public void setErrorProcessor(Request.Processor errorProcessor)
{
- if (errorHandler != null)
- errorHandler.setServer(getServer());
- updateBean(_errorHandler, errorHandler, true);
- _errorHandler = errorHandler;
+ updateBean(_errorProcessor, errorProcessor, true);
+ _errorProcessor = errorProcessor;
}
- @ManagedAttribute("The maximum content size")
- public int getMaxFormContentSize()
+ protected ContextRequest wrap(Request request, String pathInContext)
{
- return _maxFormContentSize;
+ return new ContextRequest(this, _context, request, pathInContext);
}
- /**
- * Set the maximum size of a form post, to protect against DOS attacks from large forms.
- *
- * @param maxSize the maximum size of the form content (in bytes)
- */
- public void setMaxFormContentSize(int maxSize)
+ @Override
+ public void clearAttributes()
{
- _maxFormContentSize = maxSize;
- }
-
- public int getMaxFormKeys()
- {
- return _maxFormKeys;
- }
-
- /**
- * Set the maximum number of form Keys to protect against DOS attack from crafted hash keys.
- *
- * @param max the maximum number of form keys
- */
- public void setMaxFormKeys(int max)
- {
- _maxFormKeys = max;
- }
-
- /**
- * @return True if URLs are compacted to replace multiple '/'s with a single '/'
- * @deprecated use {@code CompactPathRule} with {@code RewriteHandler} instead.
- */
- @Deprecated
- public boolean isCompactPath()
- {
- return _compactPath;
- }
-
- /**
- * @param compactPath True if URLs are compacted to replace multiple '/'s with a single '/'
- */
- @Deprecated
- public void setCompactPath(boolean compactPath)
- {
- _compactPath = compactPath;
+ _persistentAttributes.clearAttributes();
}
@Override
public String toString()
{
- final String[] vhosts = getVirtualHosts();
-
+ List vhosts = getVirtualHosts();
StringBuilder b = new StringBuilder();
- Package pkg = getClass().getPackage();
- if (pkg != null)
- {
- String p = pkg.getName();
- if (p != null && p.length() > 0)
- {
- String[] ss = p.split("\\.");
- for (String s : ss)
- {
- b.append(s.charAt(0)).append('.');
- }
- }
- }
- b.append(getClass().getSimpleName()).append('@').append(Integer.toString(hashCode(), 16));
+ b.append(TypeUtil.toShortName(getClass())).append('@').append(Integer.toString(hashCode(), 16));
b.append('{');
if (getDisplayName() != null)
b.append(getDisplayName()).append(',');
- b.append(getContextPath()).append(',').append(getBaseResource()).append(',').append(_availability.get());
+ b.append(getContextPath()).append(',').append(getResourceBase()).append(',').append(isAvailable());
- if (vhosts != null && vhosts.length > 0)
- b.append(',').append(vhosts[0]);
+ for (String vh : vhosts)
+ {
+ b.append(',').append(vh);
+ }
b.append('}');
return b.toString();
}
- public Class> loadClass(String className) throws ClassNotFoundException
- {
- if (className == null)
- return null;
-
- if (_classLoader == null)
- return Loader.loadClass(className);
-
- return _classLoader.loadClass(className);
- }
-
- public void addLocaleEncoding(String locale, String encoding)
- {
- if (_localeEncodingMap == null)
- _localeEncodingMap = new HashMap<>();
- _localeEncodingMap.put(locale, encoding);
- }
-
- public String getLocaleEncoding(String locale)
- {
- if (_localeEncodingMap == null)
- return null;
- String encoding = _localeEncodingMap.get(locale);
- return encoding;
- }
-
- /**
- * Get the character encoding for a locale. The full locale name is first looked up in the map of encodings. If no encoding is found, then the locale
- * language is looked up.
- *
- * @param locale a Locale value
- * @return a String representing the character encoding for the locale or null if none found.
- */
- public String getLocaleEncoding(Locale locale)
- {
- if (_localeEncodingMap == null)
- return null;
- String encoding = _localeEncodingMap.get(locale.toString());
- if (encoding == null)
- encoding = _localeEncodingMap.get(locale.getLanguage());
- return encoding;
- }
-
- /**
- * Get all of the locale encodings
- *
- * @return a map of all the locale encodings: key is name of the locale and value is the char encoding
- */
- public Map getLocaleEncodings()
- {
- if (_localeEncodingMap == null)
- return null;
- return Collections.unmodifiableMap(_localeEncodingMap);
- }
-
- /**
- * Attempt to get a Resource from the Context.
- *
- * @param pathInContext the path within the base resource to attempt to get
- * @return the resource, or null if not available.
- * @throws MalformedURLException if unable to form a Resource from the provided path
- */
- public Resource getResource(String pathInContext) throws MalformedURLException
- {
- if (pathInContext == null || !pathInContext.startsWith(URIUtil.SLASH))
- throw new MalformedURLException(pathInContext);
-
- if (_baseResource == null)
- return null;
-
- try
- {
- // addPath with accept non-canonical paths that don't go above the root,
- // but will treat them as aliases. So unless allowed by an AliasChecker
- // they will be rejected below.
- Resource resource = _baseResource.addPath(pathInContext);
-
- if (checkAlias(pathInContext, resource))
- return resource;
- return null;
- }
- catch (Exception e)
- {
- LOG.trace("IGNORED", e);
- }
-
- return null;
- }
-
- /**
- * @param path the path to check the alias for
- * @param resource the resource
- * @return True if the alias is OK
- */
- public boolean checkAlias(String path, Resource resource)
- {
- // Is the resource aliased?
- if (resource.isAlias())
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Aliased resource: {}~={}", resource, resource.getAlias());
-
- // alias checks
- for (AliasCheck check : getAliasChecks())
- {
- if (check.check(path, resource))
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Aliased resource: {} approved by {}", resource, check);
- return true;
- }
- }
- return false;
- }
- return true;
- }
-
- /**
- * Convert URL to Resource wrapper for {@link Resource#newResource(URL)} enables extensions to provide alternate resource implementations.
- *
- * @param url the url to convert to a Resource
- * @return the Resource for that url
- * @throws IOException if unable to create a Resource from the URL
- */
- public Resource newResource(URL url) throws IOException
- {
- return Resource.newResource(url);
- }
-
- /**
- * Convert URL to Resource wrapper for {@link Resource#newResource(URL)} enables extensions to provide alternate resource implementations.
- *
- * @param uri the URI to convert to a Resource
- * @return the Resource for that URI
- * @throws IOException if unable to create a Resource from the URL
- */
- public Resource newResource(URI uri) throws IOException
- {
- return Resource.newResource(uri);
- }
-
- /**
- * Convert a URL or path to a Resource. The default implementation is a wrapper for {@link Resource#newResource(String)}.
- *
- * @param urlOrPath The URL or path to convert
- * @return The Resource for the URL/path
- * @throws IOException The Resource could not be created.
- */
- public Resource newResource(String urlOrPath) throws IOException
- {
- return Resource.newResource(urlOrPath);
- }
-
- public Set getResourcePaths(String path)
- {
- try
- {
- Resource resource = getResource(path);
-
- if (resource != null && resource.exists())
- {
- if (!path.endsWith(URIUtil.SLASH))
- path = path + URIUtil.SLASH;
-
- String[] l = resource.list();
- if (l != null)
- {
- HashSet set = new HashSet<>();
- for (int i = 0; i < l.length; i++)
- {
- set.add(path + l[i]);
- }
- return set;
- }
- }
- }
- catch (Exception e)
- {
- LOG.trace("IGNORED", e);
- }
- return Collections.emptySet();
- }
-
private String normalizeHostname(String host)
{
+ // TODO is this needed? if so, should be it somewhere eles?
if (host == null)
return null;
int connectorIndex = host.indexOf('@');
@@ -2064,964 +720,219 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
return host;
}
- /**
- * Add an AliasCheck instance to possibly permit aliased resources
- *
- * @param check The alias checker
- */
- public void addAliasCheck(AliasCheck check)
+ public class Context extends Attributes.Layer implements org.eclipse.jetty.server.Context
{
- _aliasChecks.add(check);
- if (check instanceof LifeCycle)
- addManaged((LifeCycle)check);
- else
- addBean(check);
- }
-
- /**
- * @return Immutable list of Alias checks
- */
- public List getAliasChecks()
- {
- return Collections.unmodifiableList(_aliasChecks);
- }
-
- /**
- * @param checks list of AliasCheck instances
- */
- public void setAliasChecks(List checks)
- {
- clearAliasChecks();
- checks.forEach(this::addAliasCheck);
- }
-
- /**
- * clear the list of AliasChecks
- */
- public void clearAliasChecks()
- {
- _aliasChecks.forEach(this::removeBean);
- _aliasChecks.clear();
- }
-
- /**
- * Context.
- *
- * A partial implementation of {@link jakarta.servlet.ServletContext}. A complete implementation is provided by the
- * derived {@link ContextHandler} implementations.
- *
- */
- public class Context extends StaticContext
- {
- protected boolean _enabled = true; // whether or not the dynamic API is enabled for callers
- protected boolean _extendedListenerTypes = false;
-
- protected Context()
+ public Context()
{
+ // TODO Should the ScopedContext attributes be a layer over the ServerContext attributes?
+ super(_persistentAttributes);
}
- public ContextHandler getContextHandler()
+ @SuppressWarnings("unchecked")
+ public H getContextHandler()
{
- return ContextHandler.this;
- }
-
- @Override
- public ServletContext getContext(String uripath)
- {
- List contexts = new ArrayList<>();
- Handler[] handlers = getServer().getChildHandlersByClass(ContextHandler.class);
- String matchedPath = null;
-
- for (Handler handler : handlers)
- {
- if (handler == null)
- continue;
- ContextHandler ch = (ContextHandler)handler;
- String contextPath = ch.getContextPath();
-
- if (uripath.equals(contextPath) ||
- (uripath.startsWith(contextPath) && uripath.charAt(contextPath.length()) == '/') ||
- "/".equals(contextPath))
- {
- // look first for vhost matching context only
- if (getVirtualHosts() != null && getVirtualHosts().length > 0)
- {
- if (ch.getVirtualHosts() != null && ch.getVirtualHosts().length > 0)
- {
- for (String h1 : getVirtualHosts())
- {
- for (String h2 : ch.getVirtualHosts())
- {
- if (h1.equals(h2))
- {
- if (matchedPath == null || contextPath.length() > matchedPath.length())
- {
- contexts.clear();
- matchedPath = contextPath;
- }
-
- if (matchedPath.equals(contextPath))
- contexts.add(ch);
- }
- }
- }
- }
- }
- else
- {
- if (matchedPath == null || contextPath.length() > matchedPath.length())
- {
- contexts.clear();
- matchedPath = contextPath;
- }
-
- if (matchedPath.equals(contextPath))
- contexts.add(ch);
- }
- }
- }
-
- if (contexts.size() > 0)
- return contexts.get(0)._scontext;
-
- // try again ignoring virtual hosts
- matchedPath = null;
- for (Handler handler : handlers)
- {
- if (handler == null)
- continue;
- ContextHandler ch = (ContextHandler)handler;
- String contextPath = ch.getContextPath();
-
- if (uripath.equals(contextPath) || (uripath.startsWith(contextPath) && uripath.charAt(contextPath.length()) == '/') || "/".equals(contextPath))
- {
- if (matchedPath == null || contextPath.length() > matchedPath.length())
- {
- contexts.clear();
- matchedPath = contextPath;
- }
-
- if (matchedPath.equals(contextPath))
- contexts.add(ch);
- }
- }
-
- if (contexts.size() > 0)
- return contexts.get(0)._scontext;
- return null;
- }
-
- @Override
- public String getMimeType(String file)
- {
- if (_mimeTypes == null)
- return null;
- return _mimeTypes.getMimeByExtension(file);
- }
-
- @Override
- public RequestDispatcher getRequestDispatcher(String uriInContext)
- {
- // uriInContext is encoded, potentially with query.
- if (uriInContext == null)
- return null;
-
- if (!uriInContext.startsWith("/"))
- return null;
-
- try
- {
- String contextPath = getContextPath();
- // uriInContext is canonicalized by HttpURI.
- HttpURI.Mutable uri = HttpURI.build(uriInContext);
- String pathInfo = uri.getDecodedPath();
- if (StringUtil.isEmpty(pathInfo))
- return null;
-
- if (!StringUtil.isEmpty(contextPath))
- {
- uri.path(URIUtil.addPaths(contextPath, uri.getPath()));
- pathInfo = uri.getDecodedPath().substring(contextPath.length());
- }
- return new Dispatcher(ContextHandler.this, uri, pathInfo);
- }
- catch (Exception e)
- {
- LOG.trace("IGNORED", e);
- }
- return null;
- }
-
- @Override
- public String getRealPath(String path)
- {
- // This is an API call from the application which may have arbitrary non canonical paths passed
- // Thus we canonicalize here, to avoid the enforcement of only canonical paths in
- // ContextHandler.this.getResource(path).
- path = URIUtil.canonicalPath(path);
- if (path == null)
- return null;
- if (path.length() == 0)
- path = URIUtil.SLASH;
- else if (path.charAt(0) != '/')
- path = URIUtil.SLASH + path;
-
- try
- {
- Resource resource = ContextHandler.this.getResource(path);
- if (resource != null)
- {
- File file = resource.getFile();
- if (file != null)
- return file.getCanonicalPath();
- }
- }
- catch (Exception e)
- {
- LOG.trace("IGNORED", e);
- }
-
- return null;
- }
-
- @Override
- public URL getResource(String path) throws MalformedURLException
- {
- // This is an API call from the application which may have arbitrary non canonical paths passed
- // Thus we canonicalize here, to avoid the enforcement of only canonical paths in
- // ContextHandler.this.getResource(path).
- path = URIUtil.canonicalPath(path);
- if (path == null)
- return null;
- Resource resource = ContextHandler.this.getResource(path);
- if (resource != null && resource.exists())
- return resource.getURI().toURL();
- return null;
- }
-
- @Override
- public InputStream getResourceAsStream(String path)
- {
- try
- {
- URL url = getResource(path);
- if (url == null)
- return null;
- Resource r = Resource.newResource(url);
- // Cannot serve directories as an InputStream
- if (r.isDirectory())
- return null;
- return r.getInputStream();
- }
- catch (Exception e)
- {
- LOG.trace("IGNORED", e);
- return null;
- }
- }
-
- @Override
- public Set getResourcePaths(String path)
- {
- // This is an API call from the application which may have arbitrary non canonical paths passed
- // Thus we canonicalize here, to avoid the enforcement of only canonical paths in
- // ContextHandler.this.getResource(path).
- path = URIUtil.canonicalPath(path);
- if (path == null)
- return null;
- return ContextHandler.this.getResourcePaths(path);
- }
-
- @Override
- public void log(Exception exception, String msg)
- {
- _logger.warn(msg, exception);
- }
-
- @Override
- public void log(String msg)
- {
- _logger.info(msg);
- }
-
- @Override
- public void log(String message, Throwable throwable)
- {
- if (throwable == null)
- _logger.warn(message);
- else
- _logger.warn(message, throwable);
- }
-
- @Override
- public String getInitParameter(String name)
- {
- return ContextHandler.this.getInitParameter(name);
- }
-
- @Override
- public Enumeration getInitParameterNames()
- {
- return ContextHandler.this.getInitParameterNames();
+ return (H)ContextHandler.this;
}
@Override
public Object getAttribute(String name)
{
- Object o = ContextHandler.this.getAttribute(name);
- if (o == null)
- o = super.getAttribute(name);
- return o;
+ // TODO the Attributes.Layer is a little different to previous
+ // behaviour. We need to verify if that is OK
+ return super.getAttribute(name);
}
@Override
- public Enumeration getAttributeNames()
+ public Request.Processor getErrorProcessor()
{
- HashSet set = new HashSet<>();
- Enumeration e = super.getAttributeNames();
- while (e.hasMoreElements())
- {
- set.add(e.nextElement());
- }
- e = ContextHandler.this.getAttributeNames();
- while (e.hasMoreElements())
- {
- set.add(e.nextElement());
- }
- return Collections.enumeration(set);
- }
-
- @Override
- public void setAttribute(String name, Object value)
- {
- Object oldValue = super.getAttribute(name);
-
- if (value == null)
- super.removeAttribute(name);
- else
- super.setAttribute(name, value);
-
- if (!_servletContextAttributeListeners.isEmpty())
- {
- ServletContextAttributeEvent event = new ServletContextAttributeEvent(_scontext, name, oldValue == null ? value : oldValue);
-
- for (ServletContextAttributeListener listener : _servletContextAttributeListeners)
- {
- if (oldValue == null)
- listener.attributeAdded(event);
- else if (value == null)
- listener.attributeRemoved(event);
- else
- listener.attributeReplaced(event);
- }
- }
- }
-
- @Override
- public void removeAttribute(String name)
- {
- Object oldValue = super.getAttribute(name);
- super.removeAttribute(name);
- if (oldValue != null && !_servletContextAttributeListeners.isEmpty())
- {
- ServletContextAttributeEvent event = new ServletContextAttributeEvent(_scontext, name, oldValue);
- for (ServletContextAttributeListener listener : _servletContextAttributeListeners)
- {
- listener.attributeRemoved(event);
- }
- }
- }
-
- @Override
- public String getServletContextName()
- {
- String name = ContextHandler.this.getDisplayName();
- if (name == null)
- name = ContextHandler.this.getContextPath();
- return name;
+ Request.Processor processor = ContextHandler.this.getErrorProcessor();
+ if (processor == null)
+ processor = getServer().getErrorProcessor();
+ return processor;
}
@Override
public String getContextPath()
{
- return getRequestContextPath();
+ return _contextPath;
}
@Override
public String toString()
{
- return "ServletContext@" + ContextHandler.this.toString();
- }
-
- @Override
- public boolean setInitParameter(String name, String value)
- {
- if (ContextHandler.this.getInitParameter(name) != null)
- return false;
- ContextHandler.this.getInitParams().put(name, value);
- return true;
- }
-
- @Override
- public void addListener(String className)
- {
- if (!_enabled)
- throw new UnsupportedOperationException();
-
- try
- {
- @SuppressWarnings(
- {"unchecked", "rawtypes"})
- Class extends EventListener> clazz = _classLoader == null ? Loader.loadClass(className) : (Class)_classLoader.loadClass(className);
- addListener(clazz);
- }
- catch (ClassNotFoundException e)
- {
- throw new IllegalArgumentException(e);
- }
- }
-
- @Override
- public void addListener(T t)
- {
- if (!_enabled)
- throw new UnsupportedOperationException();
-
- checkListener(t.getClass());
-
- ContextHandler.this.addEventListener(t);
- ContextHandler.this.addProgrammaticListener(t);
- }
-
- @Override
- public void addListener(Class extends EventListener> listenerClass)
- {
- if (!_enabled)
- throw new UnsupportedOperationException();
-
- try
- {
- EventListener e = createListener(listenerClass);
- addListener(e);
- }
- catch (ServletException e)
- {
- throw new IllegalArgumentException(e);
- }
- }
-
- public void checkListener(Class extends EventListener> listener) throws IllegalStateException
- {
- boolean ok = false;
- int startIndex = (isExtendedListenerTypes() ? EXTENDED_LISTENER_TYPE_INDEX : DEFAULT_LISTENER_TYPE_INDEX);
- for (int i = startIndex; i < SERVLET_LISTENER_TYPES.length; i++)
- {
- if (SERVLET_LISTENER_TYPES[i].isAssignableFrom(listener))
- {
- ok = true;
- break;
- }
- }
- if (!ok)
- throw new IllegalArgumentException("Inappropriate listener class " + listener.getName());
- }
-
- public void setExtendedListenerTypes(boolean extended)
- {
- _extendedListenerTypes = extended;
- }
-
- public boolean isExtendedListenerTypes()
- {
- return _extendedListenerTypes;
+ return "%s@%x".formatted(getClass().getSimpleName(), hashCode());
}
@Override
public ClassLoader getClassLoader()
{
- if (!_enabled)
- throw new UnsupportedOperationException();
+ return _classLoader;
+ }
- // no security manager just return the classloader
- if (!isUsingSecurityManager())
+ @Override
+ public Path getResourceBase()
+ {
+ return _resourceBase;
+ }
+
+ @Override
+ public List getVirtualHosts()
+ {
+ return ContextHandler.this.getVirtualHosts();
+ }
+
+ public T get(Supplier supplier, Request request)
+ {
+ Context lastContext = __context.get();
+ if (lastContext == this)
+ return supplier.get();
+
+ ClassLoader loader = getClassLoader();
+ ClassLoader lastLoader = Thread.currentThread().getContextClassLoader();
+ try
{
- return _classLoader;
+ __context.set(this);
+ if (loader != null)
+ Thread.currentThread().setContextClassLoader(loader);
+
+ enterScope(request);
+ return supplier.get();
}
+ finally
+ {
+ exitScope(request);
+ __context.set(lastContext);
+ if (loader != null)
+ Thread.currentThread().setContextClassLoader(lastLoader);
+ }
+ }
+
+ public void call(Invocable.Callable callable, Request request) throws Exception
+ {
+ Context lastContext = __context.get();
+ if (lastContext == this)
+ callable.call();
else
{
- // check to see if the classloader of the caller is the same as the context
- // classloader, or a parent of it, as required by the javadoc specification.
-
- // Wrap in a PrivilegedAction so that only Jetty code will require the
- // "createSecurityManager" permission, not also application code that calls this method.
- Caller caller = AccessController.doPrivileged((PrivilegedAction)Caller::new);
- ClassLoader callerLoader = caller.getCallerClassLoader(2);
- while (callerLoader != null)
+ ClassLoader loader = getClassLoader();
+ ClassLoader lastLoader = Thread.currentThread().getContextClassLoader();
+ try
{
- if (callerLoader == _classLoader)
- return _classLoader;
- else
- callerLoader = callerLoader.getParent();
+ __context.set(this);
+ if (loader != null)
+ Thread.currentThread().setContextClassLoader(loader);
+
+ enterScope(request);
+ callable.call();
+ }
+ finally
+ {
+ exitScope(request);
+ __context.set(lastContext);
+ if (loader != null)
+ Thread.currentThread().setContextClassLoader(lastLoader);
}
- System.getSecurityManager().checkPermission(new RuntimePermission("getClassLoader"));
- return _classLoader;
}
}
- @Override
- public JspConfigDescriptor getJspConfigDescriptor()
+ public void accept(Consumer consumer, Throwable t, Request request)
{
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getJspConfigDescriptor()");
- return null;
- }
-
- public void setJspConfigDescriptor(JspConfigDescriptor d)
- {
-
- }
-
- @Override
- public void declareRoles(String... roleNames)
- {
- if (!isStarting())
- throw new IllegalStateException();
- if (!_enabled)
- throw new UnsupportedOperationException();
- }
-
- public void setEnabled(boolean enabled)
- {
- _enabled = enabled;
- }
-
- public boolean isEnabled()
- {
- return _enabled;
- }
-
- @Override
- public String getVirtualServerName()
- {
- String[] hosts = getVirtualHosts();
- if (hosts != null && hosts.length > 0)
- return hosts[0];
- return null;
- }
- }
-
- /**
- * A simple implementation of ServletContext that is used when there is no
- * ContextHandler. This is also used as the base for all other ServletContext
- * implementations.
- */
- public static class StaticContext extends AttributesMap implements ServletContext
- {
- private int _effectiveMajorVersion = SERVLET_MAJOR_VERSION;
- private int _effectiveMinorVersion = SERVLET_MINOR_VERSION;
-
- @Override
- public ServletContext getContext(String uripath)
- {
- return null;
- }
-
- @Override
- public int getMajorVersion()
- {
- return SERVLET_MAJOR_VERSION;
- }
-
- @Override
- public String getMimeType(String file)
- {
- return null;
- }
-
- @Override
- public int getMinorVersion()
- {
- return SERVLET_MINOR_VERSION;
- }
-
- @Override
- public RequestDispatcher getNamedDispatcher(String name)
- {
- return null;
- }
-
- @Override
- public RequestDispatcher getRequestDispatcher(String uriInContext)
- {
- return null;
- }
-
- @Override
- public String getRealPath(String path)
- {
- return null;
- }
-
- @Override
- public URL getResource(String path) throws MalformedURLException
- {
- return null;
- }
-
- @Override
- public InputStream getResourceAsStream(String path)
- {
- return null;
- }
-
- @Override
- public Set getResourcePaths(String path)
- {
- return null;
- }
-
- @Override
- public String getServerInfo()
- {
- return ContextHandler.getServerInfo();
- }
-
- @Override
- @Deprecated(since = "Servlet API 2.1")
- public Servlet getServlet(String name) throws ServletException
- {
- return null;
- }
-
- @Override
- @Deprecated(since = "Servlet API 2.1")
- public Enumeration getServletNames()
- {
- return Collections.enumeration(Collections.EMPTY_LIST);
- }
-
- @Override
- @Deprecated(since = "Servlet API 2.0")
- public Enumeration getServlets()
- {
- return Collections.enumeration(Collections.EMPTY_LIST);
- }
-
- @Override
- @Deprecated(since = "Servlet API 2.1")
- public void log(Exception exception, String msg)
- {
- LOG.warn(msg, exception);
- }
-
- @Override
- public void log(String msg)
- {
- LOG.info(msg);
- }
-
- @Override
- public void log(String message, Throwable throwable)
- {
- LOG.warn(message, throwable);
- }
-
- @Override
- public String getInitParameter(String name)
- {
- return null;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Enumeration getInitParameterNames()
- {
- return Collections.enumeration(Collections.EMPTY_LIST);
- }
-
- @Override
- public String getServletContextName()
- {
- return "No Context";
- }
-
- @Override
- public String getContextPath()
- {
- return null;
- }
-
- @Override
- public boolean setInitParameter(String name, String value)
- {
- return false;
- }
-
- @Override
- public Dynamic addFilter(String filterName, Class extends Filter> filterClass)
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addFilter(String, Class)");
- return null;
- }
-
- @Override
- public Dynamic addFilter(String filterName, Filter filter)
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addFilter(String, Filter)");
- return null;
- }
-
- @Override
- public Dynamic addFilter(String filterName, String className)
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addFilter(String, String)");
- return null;
- }
-
- @Override
- public jakarta.servlet.ServletRegistration.Dynamic addServlet(String servletName, Class extends Servlet> servletClass)
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addServlet(String, Class)");
- return null;
- }
-
- @Override
- public jakarta.servlet.ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet)
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addServlet(String, Servlet)");
- return null;
- }
-
- @Override
- public jakarta.servlet.ServletRegistration.Dynamic addServlet(String servletName, String className)
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addServlet(String, String)");
- return null;
- }
-
- /**
- * @since Servlet 4.0
- */
- @Override
- public ServletRegistration.Dynamic addJspFile(String servletName, String jspFile)
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addJspFile(String, String)");
- return null;
- }
-
- @Override
- public Set getDefaultSessionTrackingModes()
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getDefaultSessionTrackingModes()");
- return null;
- }
-
- @Override
- public Set getEffectiveSessionTrackingModes()
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getEffectiveSessionTrackingModes()");
- return null;
- }
-
- @Override
- public FilterRegistration getFilterRegistration(String filterName)
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getFilterRegistration(String)");
- return null;
- }
-
- @Override
- public Map getFilterRegistrations()
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getFilterRegistrations()");
- return null;
- }
-
- @Override
- public ServletRegistration getServletRegistration(String servletName)
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getServletRegistration(String)");
- return null;
- }
-
- @Override
- public Map getServletRegistrations()
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getServletRegistrations()");
- return null;
- }
-
- @Override
- public SessionCookieConfig getSessionCookieConfig()
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getSessionCookieConfig()");
- return null;
- }
-
- @Override
- public void setSessionTrackingModes(Set sessionTrackingModes)
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "setSessionTrackingModes(Set)");
- }
-
- @Override
- public void addListener(String className)
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addListener(String)");
- }
-
- @Override
- public void addListener(T t)
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addListener(T)");
- }
-
- @Override
- public void addListener(Class extends EventListener> listenerClass)
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addListener(Class)");
- }
-
- public T createInstance(Class clazz) throws ServletException
- {
- try
+ Context lastContext = __context.get();
+ if (lastContext == this)
+ consumer.accept(t);
+ else
{
- return clazz.getDeclaredConstructor().newInstance();
+ ClassLoader loader = getClassLoader();
+ ClassLoader lastLoader = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ __context.set(this);
+ if (loader != null)
+ Thread.currentThread().setContextClassLoader(loader);
+ enterScope(request);
+ consumer.accept(t);
+ }
+ finally
+ {
+ exitScope(request);
+ __context.set(lastContext);
+ if (loader != null)
+ Thread.currentThread().setContextClassLoader(lastLoader);
+ }
}
- catch (Exception e)
+ }
+
+ @Override
+ public void run(Runnable runnable)
+ {
+ run(runnable, null);
+ }
+
+ public void run(Runnable runnable, Request request)
+ {
+ Context lastContext = __context.get();
+ if (lastContext == this)
+ runnable.run();
+ else
{
- throw new ServletException(e);
+ ClassLoader loader = getClassLoader();
+ ClassLoader lastLoader = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ __context.set(this);
+ if (loader != null)
+ Thread.currentThread().setContextClassLoader(loader);
+ enterScope(request);
+ runnable.run();
+ }
+ finally
+ {
+ exitScope(request);
+ __context.set(lastContext);
+ if (loader != null)
+ Thread.currentThread().setContextClassLoader(lastLoader);
+ }
}
}
@Override
- public T createListener(Class clazz) throws ServletException
+ public void execute(Runnable runnable)
{
- return createInstance(clazz);
+ getServer().getContext().execute(() -> run(runnable));
+ }
+
+ protected DecoratedObjectFactory getDecoratedObjectFactory()
+ {
+ DecoratedObjectFactory factory = ContextHandler.this.getBean(DecoratedObjectFactory.class);
+ if (factory != null)
+ return factory;
+ return getServer().getBean(DecoratedObjectFactory.class);
}
@Override
- public T createServlet(Class clazz) throws ServletException
+ public T decorate(T o)
{
- return createInstance(clazz);
+ DecoratedObjectFactory factory = getDecoratedObjectFactory();
+ if (factory != null)
+ return factory.decorate(o);
+ return o;
}
@Override
- public T createFilter(Class clazz) throws ServletException
+ public void destroy(Object o)
{
- return createInstance(clazz);
- }
-
- @Override
- public ClassLoader getClassLoader()
- {
- return ContextHandler.class.getClassLoader();
- }
-
- @Override
- public int getEffectiveMajorVersion()
- {
- return _effectiveMajorVersion;
- }
-
- @Override
- public int getEffectiveMinorVersion()
- {
- return _effectiveMinorVersion;
- }
-
- public void setEffectiveMajorVersion(int v)
- {
- _effectiveMajorVersion = v;
- }
-
- public void setEffectiveMinorVersion(int v)
- {
- _effectiveMinorVersion = v;
- }
-
- @Override
- public JspConfigDescriptor getJspConfigDescriptor()
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getJspConfigDescriptor()");
- return null;
- }
-
- @Override
- public void declareRoles(String... roleNames)
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "declareRoles(String...)");
- }
-
- @Override
- public String getVirtualServerName()
- {
- return null;
- }
-
- /**
- * @since Servlet 4.0
- */
- @Override
- public int getSessionTimeout()
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getSessionTimeout()");
- return 0;
- }
-
- /**
- * @since Servlet 4.0
- */
- @Override
- public void setSessionTimeout(int sessionTimeout)
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "setSessionTimeout(int)");
- }
-
- /**
- * @since Servlet 4.0
- */
- @Override
- public String getRequestCharacterEncoding()
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getRequestCharacterEncoding()");
- return null;
- }
-
- /**
- * @since Servlet 4.0
- */
- @Override
- public void setRequestCharacterEncoding(String encoding)
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "setRequestCharacterEncoding(String)");
- }
-
- /**
- * @since Servlet 4.0
- */
- @Override
- public String getResponseCharacterEncoding()
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getResponseCharacterEncoding()");
- return null;
- }
-
- /**
- * @since Servlet 4.0
- */
- @Override
- public void setResponseCharacterEncoding(String encoding)
- {
- LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "setResponseCharacterEncoding(String)");
+ DecoratedObjectFactory factory = getDecoratedObjectFactory();
+ if (factory != null)
+ factory.destroy(o);
}
}
/**
* Interface to check aliases
+ * TODO REVIEW!!!
*/
public interface AliasCheck
{
-
/**
* Check an alias
*
@@ -3032,78 +943,40 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
boolean check(String pathInContext, Resource resource);
}
- /**
- * Approve all aliases.
- * @deprecated use {@link org.eclipse.jetty.server.AllowedResourceAliasChecker} instead.
- */
- @Deprecated
- public static class ApproveAliases implements AliasCheck
- {
- public ApproveAliases()
- {
- LOG.warn("ApproveAliases is deprecated");
- }
-
- @Override
- public boolean check(String pathInContext, Resource resource)
- {
- return true;
- }
- }
-
- /**
- * Approve Aliases of a non existent directory. If a directory "/foobar/" does not exist, then the resource is aliased to "/foobar". Accept such aliases.
- */
- @Deprecated
- public static class ApproveNonExistentDirectoryAliases implements AliasCheck
- {
- @Override
- public boolean check(String pathInContext, Resource resource)
- {
- if (resource.exists())
- return false;
-
- String a = resource.getAlias().toString();
- String r = resource.getURI().toString();
-
- if (a.length() > r.length())
- return a.startsWith(r) && a.length() == r.length() + 1 && a.endsWith("/");
- if (a.length() < r.length())
- return r.startsWith(a) && r.length() == a.length() + 1 && r.endsWith("/");
-
- return a.equals(r);
- }
- }
-
/**
* Listener for all threads entering context scope, including async IO callbacks
*/
- public static interface ContextScopeListener extends EventListener
+ public interface ContextScopeListener extends EventListener
{
/**
* @param context The context being entered
* @param request A request that is applicable to the scope, or null
- * @param reason An object that indicates the reason the scope is being entered.
*/
- void enterScope(Context context, Request request, Object reason);
+ default void enterScope(org.eclipse.jetty.server.Context context, Request request) {}
/**
* @param context The context being exited
* @param request A request that is applicable to the scope, or null
*/
- void exitScope(Context context, Request request);
+ default void exitScope(org.eclipse.jetty.server.Context context, Request request) {}
}
- private static class Caller extends SecurityManager
+ private static class VHost
{
- public ClassLoader getCallerClassLoader(int depth)
+ private final String _vHost;
+ private final boolean _wild;
+ private final String _vConnector;
+
+ private VHost(String vHost, boolean wild, String vConnector)
{
- if (depth < 0)
- return null;
- Class>[] classContext = getClassContext();
- if (classContext.length <= depth)
- return null;
- return classContext[depth].getClassLoader();
+ _vHost = vHost;
+ _wild = wild;
+ _vConnector = vConnector;
+ }
+
+ String getVHost()
+ {
+ return _vHost;
}
}
}
diff --git a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java
index bdabf31e19a..caa2bfe731b 100644
--- a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java
+++ b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java
@@ -13,21 +13,17 @@
package org.eclipse.jetty.server.handler;
-import java.io.IOException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.HandlerContainer;
-import org.eclipse.jetty.server.HttpChannelState;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.ArrayUtil;
import org.eclipse.jetty.util.Callback;
@@ -39,28 +35,23 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * This {@link org.eclipse.jetty.server.handler.HandlerCollection} is creates a
+ * Creates a
* Map of contexts to it's contained handlers based
- * on the context path and virtual hosts of any contained {@link org.eclipse.jetty.server.handler.ContextHandler}s.
+ * on the context path and virtual hosts of any contained {@link ContextHandler}s.
* The contexts do not need to be directly contained, only children of the contained handlers.
* Multiple contexts may have the same context path and they are called in order until one
* handles the request.
*/
@ManagedObject("Context Handler Collection")
-public class ContextHandlerCollection extends HandlerCollection
+public class ContextHandlerCollection extends Handler.Collection
{
private static final Logger LOG = LoggerFactory.getLogger(ContextHandlerCollection.class);
private final SerializedExecutor _serializedExecutor = new SerializedExecutor();
- public ContextHandlerCollection()
- {
- super(true);
- }
-
public ContextHandlerCollection(ContextHandler... contexts)
{
- super(true);
- setHandlers(contexts);
+ if (contexts.length > 0)
+ setHandlers(contexts);
}
/**
@@ -78,20 +69,19 @@ public class ContextHandlerCollection extends HandlerCollection
{
while (true)
{
- Handlers handlers = _handlers.get();
+ List handlers = getHandlers();
if (handlers == null)
break;
- if (updateHandlers(handlers, newHandlers(handlers.getHandlers())))
- break;
+ super.setHandlers(newHandlers(handlers));
}
});
}
@Override
- protected Handlers newHandlers(Handler[] handlers)
+ protected List newHandlers(List handlers)
{
- if (handlers == null || handlers.length == 0)
- return null;
+ if (handlers == null || handlers.size() == 0)
+ return Collections.emptyList();
// Create map of contextPath to handler Branch
// A branch is a Handler that could contain 0 or more ContextHandlers
@@ -132,88 +122,73 @@ public class ContextHandlerCollection extends HandlerCollection
}
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ public Request.Processor handle(Request request) throws Exception
{
- Mapping mapping = (Mapping)_handlers.get();
+ List handlers = getHandlers();
// Handle no contexts
- if (mapping == null)
- return;
- Handler[] handlers = mapping.getHandlers();
- if (handlers == null || handlers.length == 0)
- return;
+ if (handlers == null || handlers.isEmpty())
+ return null;
+
+ if (!(handlers instanceof Mapping))
+ return super.handle(request);
+
+ Mapping mapping = (Mapping)getHandlers();
// handle only a single context.
- if (handlers.length == 1)
- {
- handlers[0].handle(target, baseRequest, request, response);
- return;
- }
-
- // handle async dispatch to specific context
- HttpChannelState async = baseRequest.getHttpChannelState();
- if (async.isAsync())
- {
- ContextHandler context = async.getContextHandler();
- if (context != null)
- {
- Handler branch = mapping._contextBranches.get(context);
-
- if (branch == null)
- context.handle(target, baseRequest, request, response);
- else
- branch.handle(target, baseRequest, request, response);
- return;
- }
- }
+ if (handlers.size() == 1)
+ return handlers.get(0).handle(request);
// handle many contexts
- if (target.startsWith("/"))
+ Index> pathBranches = mapping._pathBranches;
+ if (pathBranches == null)
+ return null;
+
+ String path = request.getPathInContext();
+ if (!path.startsWith("/"))
{
- Index> pathBranches = mapping._pathBranches;
- if (pathBranches == null)
- return;
+ super.handle(request);
+ return null;
+ }
- int limit = target.length() - 1;
+ int limit = path.length() - 1;
- while (limit >= 0)
+ while (limit >= 0)
+ {
+ // Get best match
+ Map.Entry branches = pathBranches.getBest(path, 1, limit);
+
+ if (branches == null)
+ break;
+
+ int l = branches.getKey().length();
+ if (l == 1 || path.length() == l || path.charAt(l) == '/')
{
- // Get best match
- Map.Entry branches = pathBranches.getBest(target, 1, limit);
-
- if (branches == null)
- break;
-
- int l = branches.getKey().length();
- if (l == 1 || target.length() == l || target.charAt(l) == '/')
+ for (Branch branch : branches.getValue())
{
- for (Branch branch : branches.getValue())
+ try
{
- branch.getHandler().handle(target, baseRequest, request, response);
- if (baseRequest.isHandled())
- return;
+ Request.Processor processor = branch.getHandler().handle(request);
+ if (processor != null)
+ return processor;
+ }
+ catch (Throwable t)
+ {
+ LOG.warn("Unaccepted error {}", this, t);
}
}
+ }
- limit = l - 2;
- }
- }
- else
- {
- for (Handler handler : handlers)
- {
- handler.handle(target, baseRequest, request, response);
- if (baseRequest.isHandled())
- return;
- }
+ limit = l - 2;
}
+ return null;
}
/**
* Thread safe deploy of a Handler.
*
* This method is the equivalent of {@link #addHandler(Handler)},
- * but its execution is non-block and mutually excluded from all
+ * but its execution is non-blocking and mutually excluded from all
* other calls to {@link #deployHandler(Handler, Callback)} and
* {@link #undeployHandler(Handler, Callback)}.
* The handler may be added after this call returns.
@@ -224,9 +199,6 @@ public class ContextHandlerCollection extends HandlerCollection
*/
public void deployHandler(Handler handler, Callback callback)
{
- if (handler.getServer() != getServer())
- handler.setServer(getServer());
-
_serializedExecutor.execute(new SerializedExecutor.ErrorHandlingTask()
{
@Override
@@ -289,11 +261,11 @@ public class ContextHandlerCollection extends HandlerCollection
{
_contexts = new ContextHandler[]{(ContextHandler)handler};
}
- else if (handler instanceof HandlerContainer)
+ else if (handler instanceof Handler.Container)
{
- Handler[] contexts = ((HandlerContainer)handler).getChildHandlersByClass(ContextHandler.class);
- _contexts = new ContextHandler[contexts.length];
- System.arraycopy(contexts, 0, _contexts, 0, contexts.length);
+ List contexts = ((Handler.Container)handler).getDescendants(ContextHandler.class);
+ _contexts = new ContextHandler[contexts.size()];
+ System.arraycopy(contexts, 0, _contexts, 0, contexts.size());
}
else
_contexts = new ContextHandler[0];
@@ -313,7 +285,7 @@ public class ContextHandlerCollection extends HandlerCollection
{
for (ContextHandler context : _contexts)
{
- if (context.getVirtualHosts() != null && context.getVirtualHosts().length > 0)
+ if (context.getVirtualHosts() != null && context.getVirtualHosts().size() > 0)
return true;
}
return false;
@@ -336,12 +308,12 @@ public class ContextHandlerCollection extends HandlerCollection
}
}
- private static class Mapping extends Handlers
+ private static class Mapping extends ArrayList
{
private final Map _contextBranches;
private final Index> _pathBranches;
- private Mapping(Handler[] handlers, Map path2Branches)
+ private Mapping(List handlers, Map path2Branches)
{
super(handlers);
_pathBranches = new Index.Builder>()
diff --git a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextRequest.java b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextRequest.java
new file mode 100644
index 00000000000..099d646b11c
--- /dev/null
+++ b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextRequest.java
@@ -0,0 +1,134 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.server.handler;
+
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+
+import org.eclipse.jetty.http.BadMessageException;
+import org.eclipse.jetty.io.QuietException;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
+import org.eclipse.jetty.util.thread.Invocable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ContextRequest extends Request.WrapperProcessor implements Invocable, Supplier, Runnable
+{
+ private static final Logger LOG = LoggerFactory.getLogger(ContextRequest.class);
+ private final String _pathInContext;
+ private final ContextHandler _contextHandler;
+ private final ContextHandler.Context _context;
+ private Response _response;
+ private Callback _callback;
+
+ protected ContextRequest(ContextHandler contextHandler, ContextHandler.Context context, Request wrapped, String pathInContext)
+ {
+ super(wrapped);
+ _pathInContext = pathInContext;
+ _contextHandler = contextHandler;
+ _context = context;
+ }
+
+ @Override
+ public Processor get()
+ {
+ try
+ {
+ return _contextHandler.getHandler().handle(this);
+ }
+ catch (Throwable t)
+ {
+ // Let's be less verbose with BadMessageExceptions & QuietExceptions
+ if (!LOG.isDebugEnabled() && (t instanceof BadMessageException || t instanceof QuietException))
+ LOG.warn("context bad message {}", t.getMessage());
+ else
+ LOG.warn("context handle failed {}", this, t);
+ }
+ return null;
+ }
+
+ @Override
+ public void process(Request request, Response response, Callback callback) throws Exception
+ {
+ _response = response;
+ _callback = callback;
+ _context.run(this, this);
+ }
+
+ public Callback getCallback()
+ {
+ return _callback;
+ }
+
+ protected ContextResponse newContextResponse(Request request, Response response)
+ {
+ return new ContextResponse(_context, request, response);
+ }
+
+ @Override
+ public void run()
+ {
+ try
+ {
+ super.process(this, newContextResponse(this, _response), _callback);
+ }
+ catch (Throwable t)
+ {
+ Response.writeError(this, _response, _callback, t);
+ }
+ }
+
+ @Override
+ public void demandContent(Runnable onContentAvailable)
+ {
+ super.demandContent(() -> _context.run(onContentAvailable, this));
+ }
+
+ @Override
+ public boolean addErrorListener(Predicate onError)
+ {
+ return super.addErrorListener(t ->
+ {
+ // TODO: implement the line below
+ // return _context.apply(onError::test, t, ContextRequest.this);
+ _context.accept(onError::test, t, ContextRequest.this);
+ return true;
+ });
+ }
+
+ @Override
+ public org.eclipse.jetty.server.Context getContext()
+ {
+ return _context;
+ }
+
+ public String getPathInContext()
+ {
+ return _pathInContext;
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ // return some hidden attributes for requestLog
+ return switch (name)
+ {
+ case "o.e.j.s.h.ScopedRequest.contextPath" -> _context.getContextPath();
+ case "o.e.j.s.h.ScopedRequest.pathInContext" -> _pathInContext;
+ default -> super.getAttribute(name);
+ };
+ }
+}
diff --git a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextResponse.java b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextResponse.java
new file mode 100644
index 00000000000..129752b590f
--- /dev/null
+++ b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextResponse.java
@@ -0,0 +1,51 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.server.handler;
+
+import java.nio.ByteBuffer;
+
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
+
+public class ContextResponse extends Response.Wrapper
+{
+ private final ContextHandler.Context _context;
+
+ public ContextResponse(ContextHandler.Context context, Request request, Response response)
+ {
+ super(request, response);
+ _context = context;
+ }
+
+ @Override
+ public void write(boolean last, Callback callback, ByteBuffer... content)
+ {
+ Callback contextCallback = new Callback()
+ {
+ @Override
+ public void succeeded()
+ {
+ _context.run(callback::succeeded, getRequest());
+ }
+
+ @Override
+ public void failed(Throwable t)
+ {
+ _context.accept(callback::failed, t, getRequest());
+ }
+ };
+ super.write(last, contextCallback, content);
+ }
+}
diff --git a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DebugHandler.java b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DebugHandler.java
index d3ba3831a1a..52a5451a0ed 100644
--- a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DebugHandler.java
+++ b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DebugHandler.java
@@ -13,19 +13,15 @@
package org.eclipse.jetty.server.handler;
-import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Locale;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.server.AbstractConnector;
import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.DateCache;
import org.eclipse.jetty.util.RolloverFileOutputStream;
@@ -36,12 +32,20 @@ import org.eclipse.jetty.util.RolloverFileOutputStream;
* and the current thread name is updated with information that will link
* to the details in that output.
*/
-public class DebugHandler extends HandlerWrapper implements Connection.Listener
+public class DebugHandler extends Handler.Wrapper implements Connection.Listener
{
private DateCache _date = new DateCache("HH:mm:ss", Locale.US);
private OutputStream _out;
private PrintStream _print;
+ @Override
+ public Request.Processor handle(Request request) throws Exception
+ {
+ // TODO
+ return super.handle(request);
+ }
+
+ /*
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
@@ -100,7 +104,7 @@ public class DebugHandler extends HandlerWrapper implements Connection.Listener
print(name, "RESPONSE " + base_response.getStatus() + (ex == null ? "" : ("/" + ex)) + " " + base_response.getContentType());
}
}
-
+ */
private void print(String name, String message)
{
long now = System.currentTimeMillis();
diff --git a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java
index 6b79269419c..56d3d185189 100644
--- a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java
+++ b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java
@@ -14,23 +14,29 @@
package org.eclipse.jetty.server.handler;
import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
+import java.nio.ByteBuffer;
+import java.util.Collections;
+import java.util.List;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.http.DateGenerator;
+import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
+import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.http.PreEncodedHttpField;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.BufferUtil;
+import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.resource.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,12 +51,13 @@ import static java.nio.charset.StandardCharsets.UTF_8;
* For requests to '/' a 404 with a list of known contexts is served.
* For all other requests a normal 404 is served.
*/
-public class DefaultHandler extends AbstractHandler
+public class DefaultHandler extends Handler.Processor
{
private static final Logger LOG = LoggerFactory.getLogger(DefaultHandler.class);
- final long _faviconModified = (System.currentTimeMillis() / 1000) * 1000L;
- final byte[] _favicon;
+ final long _faviconModifiedMs = (System.currentTimeMillis() / 1000) * 1000L;
+ final HttpField _faviconModified = new PreEncodedHttpField(HttpHeader.LAST_MODIFIED, DateGenerator.formatDate(_faviconModifiedMs));
+ final ByteBuffer _favicon;
boolean _serveIcon = true;
boolean _showContexts = true;
@@ -73,44 +80,41 @@ public class DefaultHandler extends AbstractHandler
}
finally
{
- _favicon = favbytes;
+ _favicon = BufferUtil.toBuffer(favbytes);
}
}
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ public void process(Request request, Response response, Callback callback) throws Exception
{
- if (response.isCommitted() || baseRequest.isHandled())
- return;
-
- baseRequest.setHandled(true);
-
String method = request.getMethod();
// little cheat for common request
- if (_serveIcon && _favicon != null && HttpMethod.GET.is(method) && target.equals("/favicon.ico"))
+ if (isServeIcon() && _favicon != null && HttpMethod.GET.is(method) && request.getPathInContext().equals("/favicon.ico"))
{
- if (request.getDateHeader(HttpHeader.IF_MODIFIED_SINCE.toString()) == _faviconModified)
- response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+ ByteBuffer content = BufferUtil.EMPTY_BUFFER;
+ if (_faviconModifiedMs > 0 && request.getHeaders().getDateField(HttpHeader.IF_MODIFIED_SINCE) == _faviconModifiedMs)
+ response.setStatus(HttpStatus.NOT_MODIFIED_304);
else
{
- response.setStatus(HttpServletResponse.SC_OK);
+ response.setStatus(HttpStatus.OK_200);
response.setContentType("image/x-icon");
- response.setContentLength(_favicon.length);
- response.setDateHeader(HttpHeader.LAST_MODIFIED.toString(), _faviconModified);
- response.setHeader(HttpHeader.CACHE_CONTROL.toString(), "max-age=360000,public");
- response.getOutputStream().write(_favicon);
+ response.setContentLength(_favicon.remaining());
+ response.getHeaders().add(_faviconModified);
+ response.getHeaders().put(HttpHeader.CACHE_CONTROL.toString(), "max-age=360000,public");
+ content = _favicon.slice();
}
+ response.write(true, callback, content);
return;
}
- if (!_showContexts || !HttpMethod.GET.is(method) || !request.getRequestURI().equals("/"))
+ if (!isShowContexts() || !HttpMethod.GET.is(method) || !request.getPathInContext().equals("/"))
{
- response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ Response.writeError(request, response, callback, HttpStatus.NOT_FOUND_404, null);
return;
}
- response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ response.setStatus(HttpStatus.NOT_FOUND_404);
response.setContentType(MimeTypes.Type.TEXT_HTML_UTF_8.toString());
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
@@ -134,13 +138,11 @@ public class DefaultHandler extends AbstractHandler
writer.append("\n");
Server server = getServer();
- Handler[] handlers = server == null ? null : server.getChildHandlersByClass(ContextHandler.class);
+ List handlers = server == null ? Collections.emptyList() : server.getDescendants(ContextHandler.class);
- for (int i = 0; handlers != null && i < handlers.length; i++)
+ for (ContextHandler context : handlers)
{
writer.append("