From eb35e42cb6098dae06acd013cbc9ba869f9cf9e1 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Thu, 10 Aug 2023 16:47:37 +0200 Subject: [PATCH] Fixed documentation that was still referring to `Handler.process()` which has now become `Handler.handle()`. Signed-off-by: Simone Bordet --- .../programming-guide/.asciidoctorconfig | 3 +++ .../migration/migration-11-to-12.adoc | 6 +++++ .../http/server-http-handler-implement.adoc | 27 ++++++++++++++----- .../server/http/server-http-handler-use.adoc | 19 +++++++------ .../server/http/server-http-handler.adoc | 12 ++++----- .../programming-guide/server/server.adoc | 2 +- .../server/http/HTTPServerDocs.java | 19 ++++++++----- .../org/eclipse/jetty/server/Handler.java | 5 ++-- 8 files changed, 61 insertions(+), 32 deletions(-) diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/.asciidoctorconfig b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/.asciidoctorconfig index 32851d8dfbd..3dd174b7369 100644 --- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/.asciidoctorconfig +++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/.asciidoctorconfig @@ -1,5 +1,8 @@ // Asciidoctor IDE configuration file. // See https://github.com/asciidoctor/asciidoctor-intellij-plugin/wiki/Support-project-specific-configurations +:ee-all: ee{8,9,10} +:ee-current: ee10 +:ee-current-caps: EE 10 :experimental: :imagesdir: images :doc_code: ../../java diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/migration/migration-11-to-12.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/migration/migration-11-to-12.adoc index f5f95229f51..66f7f857eea 100644 --- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/migration/migration-11-to-12.adoc +++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/migration/migration-11-to-12.adoc @@ -46,6 +46,12 @@ | `org.eclipse.jetty.http2.client.**http**.*` | `org.eclipse.jetty.http2.client.**transport**.*` |=== +[[pg-migration-11-to-12-servlet-to-handler]] +==== Migrate Servlets to Jetty Handlers + + + + [[pg-migration-11-to-12-api-changes]] ==== APIs Changes diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http-handler-implement.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http-handler-implement.adoc index b992534b64c..61b43256d16 100644 --- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http-handler-implement.adoc +++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http-handler-implement.adoc @@ -21,12 +21,24 @@ The `Handler` API consist fundamentally of just one method: include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java[tags=handlerAPI] ---- -The `target` parameter is an identifier for the resource. -This is normally the URI that is parsed from an HTTP request. -However, a request could be forwarded to either a named resource, in which case `target` will be the name of the resource, or to a different URI, in which case `target` will be the new URI. +The code that implements the `handle(\...)` method must respect the following contract: -Applications may wrap the request or response (or both) and forward the wrapped request or response to a different URI (which may be possibly handled by a different `Handler`). -This is the reason why there are two request parameters in the `Handler` APIs: the first is the unwrapped, original, request that also gives access to Jetty-specific APIs, while the second is the application-wrapped Servlet request. +* It may inspect `Request` immutable information such as URI and headers, typically to decide whether to return `true` or `false` (see below). +* Returning `false` means that the implementation does not handle the request, and it **must not** complete the `callback` parameter, nor read the request content, nor write response content. +* Returning `true` means that the implementation wants to handle the request, and it **must** eventually complete the `callback` parameter. +The completion of the `callback` parameter may happen synchronously within the invocation to `handle(\...)`, or at a later time, asynchronously, possibly from another thread. +If the response has not been explicitly written when `handle(\...)` returns, the implementation will write a `200` response with no content. + +[CAUTION] +==== +Violating the contract above may result in undefined or unexpected behavior. + +For example, returning `true` from `handle(\...)`, but not completing the `callback` parameter may result in the request or the response never be completed, likely causing the client to time out. + +Similarly, returning `false` from `handle(\...)` but then either writing the response or completing the `callback` parameter will likely result in a garbled response be sent to the client, as the implementation will either invoke another `Handler` (that may write a response) or write a default response. +==== + +Applications may wrap the request or response (or both) and forward the wrapped request or response to a child `Handler`. [[pg-server-http-handler-impl-hello]] ====== Hello World Handler @@ -38,7 +50,10 @@ A simple "Hello World" `Handler` is the following: include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java[tags=handlerHello] ---- -Such a simple `Handler` extends from `AbstractHandler` and can access the request and response main features, such as reading request headers and content, or writing response headers and content. +Such a simple `Handler` extends from `Handler.Abstract` and can access the request and response main features, such as reading request headers and content, or writing response headers and content. + +Note how the `callback` parameter is passed to `Content.Sink.write(\...)` (a utility method that eventually calls `Response.write(\...)`), so that when the write completes, also the `callback` parameter is completed. +Note also that because the `callback` parameter will eventually be completed, the value returned from `handle(\...)` is `true`. [[pg-server-http-handler-impl-filter]] ====== Filtering Handler 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 b0e1a62da87..5abb2c3aeaf 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 @@ -40,7 +40,7 @@ Web applications can be written using exclusively the Servlet APIs, since develo Embedded web applications based on the Servlet APIs are described in xref:pg-server-http-handler-use-servlet[this section]. Embedded web applications may also require additional features such as access to Jetty specific APIs, or utility features such as redirection from HTTP to HTTPS, support for `gzip` content compression, etc. -The Jetty Server Libraries provides a number of out-of-the-box __Handler__s that implement the most common functionalities and are described in xref:pg-server-http-handler-use[this section]. +The Jetty Server Libraries provides a number of out-of-the-box ``Handler``s that implement the most common functionalities and are described in the next sections. [[pg-server-http-handler-use-util-context]] ====== ContextHandler @@ -75,9 +75,9 @@ However, this has no knowledge of the concept of _context_ and just iterates thr A better choice for multiple web application is `ContextHandlerCollection`, that matches a _context_ from either its _context path_ or _virtual host_, without iterating through the ``Handler``s. -If `ContextHandlerCollection` does not find a match, it just returns `false` from its `process(\...)` method. +If `ContextHandlerCollection` does not find a match, it just returns `false` from its `handle(\...)` method. What happens next depends on the `Handler` tree structure: other ``Handler``s may be invoked after `ContextHandlerCollection`, for example `DefaultHandler` (see xref:pg-server-http-handler-use-util-default-handler[this section]). -Eventually, if no `Handler` returns `true` from their own `process(\...)` method, then Jetty returns an HTTP `404` response to the client. +Eventually, if no `Handler` returns `true` from their own `handle(\...)` method, then Jetty returns an HTTP `404` response to the client. [source,java,indent=0] ---- @@ -132,7 +132,7 @@ If you need to serve static resources from multiple directories: include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java[tags=multipleResourcesHandler] ---- -If the resource is not found, `ResourceHandler` will not return `true` from the `process(\...)` method, so what happens next depends on the `Handler` tree structure. +If the resource is not found, `ResourceHandler` will not return `true` from the `handle(\...)` method, so what happens next depends on the `Handler` tree structure. See also xref:pg-server-http-handler-use-util-default-handler[how to use] `DefaultHandler`. [[pg-server-http-handler-use-util-gzip-handler]] @@ -285,7 +285,7 @@ include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/http/HTTPSer [[pg-server-http-handler-use-util-default-handler]] ====== DefaultHandler -`DefaultHandler` is a terminal `Handler` that always returns `true` from its `process(\...)` method and performs the following: +`DefaultHandler` is a terminal `Handler` that always returns `true` from its `handle(\...)` method and performs the following: * Serves the `favicon.ico` Jetty icon when it is requested * Sends a HTTP `404` response for any other request @@ -357,7 +357,7 @@ Note also how adding a `Servlet` or a `Filter` returns a _holder_ object that ca When a request arrives to `ServletContextHandler` the request URI will be matched against the ``Filter``s and ``Servlet`` mappings and only those that match will process the request, as dictated by the Servlet specification. -IMPORTANT: `ServletContextHandler` is a terminal `Handler`, that is it always returns `true` from its `process(\...)` method when invoked. +IMPORTANT: `ServletContextHandler` is a terminal `Handler`, that is it always returns `true` from its `handle(\...)` method when invoked. Server applications must be careful when creating the `Handler` tree to put ``ServletContextHandler``s as last ``Handler``s in any `Handler.Collection` or as children of a `ContextHandlerCollection`. // TODO: revise what above, as ServletContextHandler is not a terminal handler. @@ -385,12 +385,11 @@ The web application class loader is special because it behaves differently from The typical class loading model, parent-first, is _inverted_ for web application class loaders, as they use a child-first model. Furthermore, the Servlet specification requires that web applications cannot load or otherwise access the Servlet container implementation classes, also called _server classes_. -In the Jetty case, the Servlet specification class `javax.servlet.http.HttpServletRequest` is implemented by `org.eclipse.jetty.server.Request`. -Web applications cannot downcast Servlet's `HttpServletRequest` to Jetty's `Request` to access Jetty specific features -- this ensures maximum web application portability across Servlet container implementations. +Web applications receive the HTTP request object as an instance of the `jakarta.servlet.http.HttpServletRequest` interface, and cannot downcast it to the Jetty specific implementation of that interface to access Jetty specific features -- this ensures maximum web application portability across Servlet container implementations. -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). +Lastly, the Servlet specification requires that other classes, also called _system classes_, such as `jakarta.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.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. +`WebAppContext` implements this class loader logic using a single class loader, `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-handler.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http-handler.adoc index 407bf92ecfe..c5f97cb75f8 100644 --- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http-handler.adoc +++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http-handler.adoc @@ -17,12 +17,12 @@ An `org.eclipse.jetty.server.Handler` is the component that processes incoming HTTP requests and eventually produces HTTP responses. ``Handler``s can process the HTTP request themselves, or they can be ``Handler.Container``s that delegate HTTP request processing to one or more contained ``Handler``s. -This allows ``Handler``s to be organised as a tree comprised of: +This allows ``Handler``s to be organized as a tree comprised of: -* Leaf ``Handler``s that return `true` from the `process(\...)` method, generate a response and succeed the `Callback`. -* A `Handler.Wrapper` can be used to form a chain of ``Handler``s where request, response or callback objects are wrapped in the `process(\...)` method before being passed down the chain. -* A `Handler.Collection` that contains a sequence of ``Handler``s, with each `Handler` being called in sequence until one returns `true` from its `process(\..)` method. -* A specialized `Handler.Container` that may use properties of the request (for example, the URI, or a header, etc.) to select from one or more contained ``Handler``s to delegate the HTTP request processing to. +* Leaf ``Handler``s that return `true` from the `handle(\...)` method, generate a response and succeed the `Callback`. +* A `Handler.Wrapper` can be used to form a chain of ``Handler``s where request, response or callback objects are wrapped in the `handle(\...)` method before being passed down the chain. +* A `Handler.Sequence` that contains a sequence of ``Handler``s, with each `Handler` being called in sequence until one returns `true` from its `handle(\...)` method. +* A specialized `Handler.Container` that may use properties of the request (for example, the URI, or a header, etc.) to select from one or more contained ``Handler``s to delegate the HTTP request processing to, for example link:{javadoc-url}/org/eclipse/jetty/server/handler/PathMappingsHandler.html[`PathMappingsHandler`]. A `Handler` tree is created by composing ``Handler``s together: @@ -37,7 +37,7 @@ The corresponding `Handler` tree structure looks like the following: ---- Server └── GzipHandler - └── Handler.Collection + └── Handler.Sequence ├── App1Handler └── App2Handler ---- diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/server.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/server.adoc index 50c5a7debb0..b1d2a8aa6f1 100644 --- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/server.adoc +++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/server.adoc @@ -27,7 +27,7 @@ The Jetty server-side libraries provide: * HTTP/2 low-level support, for applications that want to explicitly handle low-level HTTP/2 _sessions_, _streams_ and _frames_, via the xref:pg-server-http2[HTTP/2 libraries] * HTTP/3 low-level support, for applications that want to explicitly handle low-level HTTP/3 _sessions_, _streams_ and _frames_, via the xref:pg-server-http3[HTTP/3 libraries] * WebSocket support, for applications that want to embed a WebSocket server, via the xref:pg-server-websocket[WebSocket libraries] -* FCGI support, to delegate requests to python or similar scripting languages. +* FCGI support, to delegate requests to PHP, Python, Ruby or similar scripting languages. include::compliance/server-compliance.adoc[] include::http/server-http.adoc[] 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 58a4efc1ec6..07a0cdcc664 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 @@ -479,10 +479,10 @@ public class HTTPServerDocs @Override // tag::handlerAPI[] public boolean handle(Request request, Response response, Callback callback) throws Exception - { - return true; - } // end::handlerAPI[] + { + return false; + } } } @@ -555,7 +555,7 @@ public class HTTPServerDocs HttpURI newURI = HttpURI.build(uri).path(newPath).asImmutable(); // Modify the request object by wrapping the HttpURI - request = new Request.Wrapper(request) + Request newRequest = new Request.Wrapper(request) { @Override public HttpURI getHttpURI() @@ -563,10 +563,15 @@ public class HTTPServerDocs return newURI; } }; - } - // Forward to the next Handler. - return super.handle(request, response, callback); + // Forward to the next Handler using the wrapped Request. + return super.handle(newRequest, response, callback); + } + else + { + // Forward to the next Handler as-is. + return super.handle(request, response, callback); + } } } diff --git a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Handler.java b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Handler.java index 280d2a25820..797a50ea523 100644 --- a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Handler.java +++ b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Handler.java @@ -607,8 +607,9 @@ public interface Handler extends LifeCycle, Destroyable, Request.Handler } /** - *

A {@link Handler.Container} that contains a list of other {@code Handler}s that are - * tried in sequence by {@link #handle(Request, Response, Callback)}.

+ *

A {@link Handler.Container} that contains a list of other {@link Handler}s + * whose {@link Handler#handle(Request, Response, Callback)} method is invoked + * in sequence until {@code true} is returned.

*/ class Sequence extends AbstractContainer implements Collection {