Updated the documentation about HttpChannel events (they don't exist anymore replaced by `EventsHandler`).
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
parent
be11dfdbab
commit
0eb4f1b7e3
|
@ -25,4 +25,4 @@ This section lists the listeners available in the Jetty components, but the even
|
||||||
|
|
||||||
* xref:pg-arch-bean-listener[]
|
* xref:pg-arch-bean-listener[]
|
||||||
* xref:pg-arch-io-connection-listener[]
|
* xref:pg-arch-io-connection-listener[]
|
||||||
* xref:pg-server-http-channel-events[]
|
* xref:pg-server-http-request-processing-events[]
|
||||||
|
|
|
@ -266,6 +266,75 @@ For instance, `StatisticsHandler.MinimumDataRateHandler` can be used to enforce
|
||||||
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java[tags=dataRateHandler]
|
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java[tags=dataRateHandler]
|
||||||
----
|
----
|
||||||
|
|
||||||
|
[[pg-server-http-handler-use-events]]
|
||||||
|
====== EventsHandler
|
||||||
|
|
||||||
|
`EventsHandler` allows applications to be notified of xref:pg-server-http-request-processing-events[request processing] events.
|
||||||
|
|
||||||
|
`EventsHandler` must be subclassed, and the relevant `onXYZ()` methods overridden to capture the request processing events you are interested in.
|
||||||
|
The request processing events can be used in conjunction with `Request` APIs that provide the information you may be interested in.
|
||||||
|
|
||||||
|
For example, if you want to use `EventsHandler` to record processing times, you can use the request processing events with the following `Request` APIs:
|
||||||
|
|
||||||
|
* `Request.getBeginNanoTime()`, which returns the earliest possible nanoTime the request was received.
|
||||||
|
* `Request.getHeadersNanoTime()`, which returns the nanoTime at which the parsing of the HTTP headers was completed.
|
||||||
|
|
||||||
|
[CAUTION]
|
||||||
|
====
|
||||||
|
The `Request` and `Response` objects may be inspected during events, but it is recommended to avoid modifying them, for example by adding/removing headers or by reading/writing content, because any modification may interfere with the processing performed by other ``Handler``s.
|
||||||
|
====
|
||||||
|
|
||||||
|
`EventsHandler` emits the following events:
|
||||||
|
|
||||||
|
`beforeHandling`::
|
||||||
|
Emitted just before `EventsHandler` invokes the `Handler.handle(\...)` method of the next `Handler` in the `Handler` tree.
|
||||||
|
`afterHandling`::
|
||||||
|
Emitted just after the invocation to the `Handler.handle(\...)` method of the next `Handler` in the `Handler` tree returns, either normally or by throwing.
|
||||||
|
`requestRead`::
|
||||||
|
Emitted every time a chunk of content is read from the `Request`.
|
||||||
|
`responseBegin`::
|
||||||
|
Emitted when the response first write happens.
|
||||||
|
`responseWrite`::
|
||||||
|
Emitted every time the write of some response content is initiated.
|
||||||
|
`responseWriteComplete`::
|
||||||
|
Emitted every time the write of some response content is completed, either successfully or with a failure.
|
||||||
|
`responseTrailersComplete`::
|
||||||
|
Emitted when the write of the response trailers is completed.
|
||||||
|
`complete`::
|
||||||
|
Emitted when both request and the response have been completely processed.
|
||||||
|
|
||||||
|
Your `EventsHandler` subclass should then be linked in the `Handler` tree in the relevant position, typically as the outermost `Handler` after `Server`:
|
||||||
|
|
||||||
|
[source,java,indent=0]
|
||||||
|
----
|
||||||
|
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java[tags=eventsHandler]
|
||||||
|
----
|
||||||
|
|
||||||
|
The `Handler` tree structure looks like the following:
|
||||||
|
|
||||||
|
[source,screen]
|
||||||
|
----
|
||||||
|
Server
|
||||||
|
└── MyEventsHandler
|
||||||
|
└── ContextHandler /app
|
||||||
|
----
|
||||||
|
|
||||||
|
You can link the `EventsHandler` at any point in the `Handler` tree structure, and even have multiple ``EventsHandler``s to be notified of the request processing events at the different stages of the `Handler` tree, for example:
|
||||||
|
|
||||||
|
[source,screen]
|
||||||
|
----
|
||||||
|
Server
|
||||||
|
└── TotalEventsHandler
|
||||||
|
└── SlowHandler
|
||||||
|
└── AppEventsHandler
|
||||||
|
└── ContextHandler /app
|
||||||
|
----
|
||||||
|
|
||||||
|
In the example above, `TotalEventsHandler` may record the total times of request processing, from `SlowHandler` all the way to the `ContextHandler`.
|
||||||
|
On the other hand, `AppEventsHandler` may record both the time it takes for the request to flow from `TotalEventsHandler` to `AppEventsHandler`, therefore effectively measuring the processing time due to `SlowHandler`, and the time it takes to process the request by the `ContextHandler`.
|
||||||
|
|
||||||
|
Refere to the `EventsHandler` link:{javadoc-url}/org/eclipse/jetty/server/handler/EventsHandler[javadocs] for further information.
|
||||||
|
|
||||||
[[pg-server-http-handler-use-limit]]
|
[[pg-server-http-handler-use-limit]]
|
||||||
====== QoSHandler
|
====== QoSHandler
|
||||||
TODO
|
TODO
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
Web application development typically involves writing your web applications, packaging them into a web application archive, the `+*.war+` file, and then deploy the `+*.war+` file into a standalone Servlet Container that you have previously installed.
|
Web application development typically involves writing your web applications, packaging them into a web application archive, the `+*.war+` file, and then deploy the `+*.war+` file into a standalone Servlet Container that you have previously installed.
|
||||||
|
|
||||||
The Eclipse Jetty server libraries allow you to write web applications components using either the Jetty APIs (by writing xref:pg-server-http-handler[Jetty ``Handler``s]) or using the standard xref:pg-server-http-handler-use-servlet[Servlet APIs] (by writing ``Servlet``s and Servlet ``Filter``s).
|
The Jetty server libraries allow you to write web applications components using either the Jetty APIs (by writing xref:pg-server-http-handler[Jetty ``Handler``s]) or using the standard xref:pg-server-http-handler-use-servlet[Servlet APIs] (by writing ``Servlet``s and Servlet ``Filter``s).
|
||||||
These components can then be programmatically assembled together, without the need of creating a `+*.war+` file, added to a Jetty ``Server`` instance that is then started.
|
These components can then be programmatically assembled together, without the need of creating a `+*.war+` file, added to a Jetty ``Server`` instance that is then started.
|
||||||
This result in your web applications to be available to HTTP clients as if you deployed your `+*.war+` files in a standalone Jetty server.
|
This result in your web applications to be available to HTTP clients as if you deployed your `+*.war+` files in a standalone Jetty server.
|
||||||
|
|
||||||
|
@ -90,6 +90,7 @@ participant ManagedSelector
|
||||||
participant EndPoint
|
participant EndPoint
|
||||||
participant Connection
|
participant Connection
|
||||||
participant Parser
|
participant Parser
|
||||||
|
participant HttpStream
|
||||||
participant HttpChannel
|
participant HttpChannel
|
||||||
participant Server
|
participant Server
|
||||||
participant Handlers
|
participant Handlers
|
||||||
|
@ -99,8 +100,8 @@ EndPoint -> Connection : onFillable()
|
||||||
Connection -> EndPoint : fill()
|
Connection -> EndPoint : fill()
|
||||||
EndPoint --> Connection
|
EndPoint --> Connection
|
||||||
Connection -> Parser : parse()
|
Connection -> Parser : parse()
|
||||||
Parser -> HttpChannel : events
|
Parser -> HttpStream : events
|
||||||
Connection -> HttpChannel : handle()
|
Connection -> HttpChannel : onRequest()
|
||||||
HttpChannel -> Server : handle()
|
HttpChannel -> Server : handle()
|
||||||
Server -> Handlers : handle()
|
Server -> Handlers : handle()
|
||||||
----
|
----
|
||||||
|
@ -110,48 +111,16 @@ 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 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.
|
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 `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.
|
When enough of the HTTP request is arrived, the `Connection` calls `HttpChannel.onRequest()` that calls the `Handler` chain starting from the `Server` instance, that eventually calls the server application code.
|
||||||
|
|
||||||
[[pg-server-http-channel-events]]
|
[[pg-server-http-request-processing-events]]
|
||||||
===== HttpChannel Events
|
===== Request Processing Events
|
||||||
|
|
||||||
The central component processing HTTP requests is `HttpChannelState`.
|
Advanced server applications may be interested in the progress of the processing of an HTTP request/response.
|
||||||
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).
|
A typical case is to know exactly _when_ the HTTP request/response processing starts and when it is complete, for example to monitor processing times.
|
||||||
|
|
||||||
Advanced server applications may be interested in the progress of the processing of an HTTP request/response by `HttpChannelState`.
|
This is conveniently implemented by `org.eclipse.jetty.server.handler.EventsHandler`, described in more details in xref:pg-server-http-handler-use-events[this section].
|
||||||
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.
|
|
||||||
|
|
||||||
`HttpChannelState` notifies ``HttpChannel.Listener``s of the progress of the HTTP request/response handling.
|
|
||||||
Currently, the following events are available:
|
|
||||||
|
|
||||||
* `requestBegin`
|
|
||||||
* `beforeDispatch`
|
|
||||||
* `dispatchFailure`
|
|
||||||
* `afterDispatch`
|
|
||||||
* `requestContent`
|
|
||||||
* `requestContentEnd`
|
|
||||||
* `requestTrailers`
|
|
||||||
* `requestEnd`
|
|
||||||
* `responseBegin`
|
|
||||||
* `responseCommit`
|
|
||||||
* `responseContent`
|
|
||||||
* `responseFailure`
|
|
||||||
* `responseEnd`
|
|
||||||
* `complete`
|
|
||||||
|
|
||||||
Please refer to the `HttpChannel.Listener` link:{javadoc-url}/org/eclipse/jetty/server/HttpChannel.Listener.html[javadocs] for the complete list of events.
|
|
||||||
|
|
||||||
Server applications can register `HttpChannel.Listener` by adding them as xref:pg-arch-bean[beans] to the `Connector`:
|
|
||||||
|
|
||||||
[source,java,indent=0]
|
|
||||||
----
|
|
||||||
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java[tags=httpChannelListener]
|
|
||||||
----
|
|
||||||
|
|
||||||
[[pg-server-http-request-logging]]
|
[[pg-server-http-request-logging]]
|
||||||
==== Request Logging
|
==== Request Logging
|
||||||
|
|
|
@ -63,17 +63,21 @@ import org.eclipse.jetty.server.SslConnectionFactory;
|
||||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||||
import org.eclipse.jetty.server.handler.DefaultHandler;
|
import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||||
|
import org.eclipse.jetty.server.handler.EventsHandler;
|
||||||
import org.eclipse.jetty.server.handler.ResourceHandler;
|
import org.eclipse.jetty.server.handler.ResourceHandler;
|
||||||
import org.eclipse.jetty.server.handler.SecuredRedirectHandler;
|
import org.eclipse.jetty.server.handler.SecuredRedirectHandler;
|
||||||
import org.eclipse.jetty.server.handler.StatisticsHandler;
|
import org.eclipse.jetty.server.handler.StatisticsHandler;
|
||||||
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
|
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
|
||||||
import org.eclipse.jetty.unixdomain.server.UnixDomainServerConnector;
|
import org.eclipse.jetty.unixdomain.server.UnixDomainServerConnector;
|
||||||
import org.eclipse.jetty.util.Callback;
|
import org.eclipse.jetty.util.Callback;
|
||||||
|
import org.eclipse.jetty.util.NanoTime;
|
||||||
import org.eclipse.jetty.util.resource.Resource;
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||||
|
|
||||||
|
import static java.lang.System.Logger.Level.INFO;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class HTTPServerDocs
|
public class HTTPServerDocs
|
||||||
{
|
{
|
||||||
|
@ -910,6 +914,48 @@ public class HTTPServerDocs
|
||||||
// end::dataRateHandler[]
|
// end::dataRateHandler[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void eventsHandler() throws Exception
|
||||||
|
{
|
||||||
|
// tag::eventsHandler[]
|
||||||
|
class MyEventsHandler extends EventsHandler
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void onBeforeHandling(Request request)
|
||||||
|
{
|
||||||
|
// The nanoTime at which the request is first received.
|
||||||
|
long requestBeginNanoTime = request.getBeginNanoTime();
|
||||||
|
|
||||||
|
// The nanoTime just before invoking the next Handler.
|
||||||
|
request.setAttribute("beforeHandlingNanoTime", NanoTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onComplete(Request request, Throwable failure)
|
||||||
|
{
|
||||||
|
// Retrieve the before handling nanoTime.
|
||||||
|
long beforeHandlingNanoTime = (long)request.getAttribute("beforeHandlingNanoTime");
|
||||||
|
|
||||||
|
// Record the request processing time.
|
||||||
|
long processingTime = NanoTime.millisSince(beforeHandlingNanoTime);
|
||||||
|
System.getLogger("trackTime").log(INFO, "processing request %s took %d ms", request, processingTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Server server = new Server();
|
||||||
|
ServerConnector connector = new ServerConnector(server);
|
||||||
|
server.addConnector(connector);
|
||||||
|
|
||||||
|
// Link the EventsHandler as the outermost Handler after Server.
|
||||||
|
MyEventsHandler eventsHandler = new MyEventsHandler();
|
||||||
|
server.setHandler(eventsHandler);
|
||||||
|
|
||||||
|
ContextHandler appHandler = new ContextHandler("/app");
|
||||||
|
eventsHandler.setHandler(appHandler);
|
||||||
|
|
||||||
|
server.start();
|
||||||
|
// end::eventsHandler[]
|
||||||
|
}
|
||||||
|
|
||||||
public void securedHandler() throws Exception
|
public void securedHandler() throws Exception
|
||||||
{
|
{
|
||||||
// tag::securedHandler[]
|
// tag::securedHandler[]
|
||||||
|
|
Loading…
Reference in New Issue