//
// ========================================================================
// Copyright (c) 1995 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
// ========================================================================
//

= HTTP/2 Server Library

In the vast majority of cases, server applications should use the generic, high-level, xref:server/http.adoc[HTTP server library] that also provides HTTP/2 support via the HTTP/2 ``ConnectionFactory``s as described in details xref:server/http.adoc#connector-protocol-http2[here].

The low-level HTTP/2 server library has been designed for those applications that need low-level access to HTTP/2 features such as _sessions_, _streams_ and _frames_, and this is quite a rare use case.

See also the correspondent xref:client/http2.adoc[HTTP/2 client library].

[[intro]]
== Introduction

The Maven artifact coordinates for the HTTP/2 client library are the following:

[,xml,subs=attributes+]
----
<dependency>
  <groupId>org.eclipse.jetty.http2</groupId>
  <artifactId>jetty-http2-server</artifactId>
  <version>{jetty-version}</version>
</dependency>
----

HTTP/2 is a multiplexed protocol: it allows multiple HTTP/2 requests to be sent on the same TCP connection, or _session_.
Each request/response cycle is represented by a _stream_.
Therefore, a single _session_ manages multiple concurrent _streams_.
A _stream_ has typically a very short life compared to the _session_: a _stream_ only exists for the duration of the request/response cycle and then disappears.

[[flow-control]]
== HTTP/2 Flow Control

The HTTP/2 protocol is _flow controlled_ (see https://tools.ietf.org/html/rfc7540#section-5.2[the specification]).
This means that a sender and a receiver maintain a _flow control window_ that tracks the number of data bytes sent and received, respectively.
When a sender sends data bytes, it reduces its flow control window.
When a receiver receives data bytes, it also reduces its flow control window, and then passes the received data bytes to the application.
The application consumes the data bytes and tells back the receiver that it has consumed the data bytes.
The receiver then enlarges the flow control window, and the implementation arranges to send a message to the sender with the number of bytes consumed, so that the sender can enlarge its flow control window.

A sender can send data bytes up to its whole flow control window, then it must stop sending.
The sender may resume sending data bytes when it receives a message from the receiver that the data bytes sent previously have been consumed.
This message enlarges the sender flow control window, which allows the sender to send more data bytes.

HTTP/2 defines _two_ flow control windows: one for each _session_, and one for each _stream_.
Let's see with an example how they interact, assuming that in this example the session flow control window is 120 bytes and the stream flow control window is 100 bytes.

The sender opens a session, and then opens `stream_1` on that session, and sends `80` data bytes.
At this point the session flow control window is `40` bytes (`120 - 80`), and ``stream_1``'s flow control window is `20` bytes (`100 - 80`).
The sender now opens `stream_2` on the same session and sends `40` data bytes.
At this point, the session flow control window is `0` bytes (`40 - 40`), while ``stream_2``'s flow control window is `60` (`100 - 40`).
Since now the session flow control window is `0`, the sender cannot send more data bytes, neither on `stream_1` nor on `stream_2`, nor on other streams, despite all the streams having their stream flow control windows greater than `0`.

The receiver consumes ``stream_2``'s `40` data bytes and sends a message to the sender with this information.
At this point, the session flow control window is `40` (``0 + 40``), ``stream_1``'s flow control window is still `20` and ``stream_2``'s flow control window is `100` (``60 + 40``).
If the sender opens `stream_3` and would like to send `50` data bytes, it would only be able to send `40` because that is the maximum allowed by the session flow control window at this point.

It is therefore very important that applications notify the fact that they have consumed data bytes as soon as possible, so that the implementation (the receiver) can send a message to the sender (in the form of a `WINDOW_UPDATE` frame) with the information to enlarge the flow control window, therefore reducing the possibility that sender stalls due to the flow control windows being reduced to `0`.

How a server application should handle HTTP/2 flow control is discussed in details in <<request,this section>>.

[[setup]]
== Server Setup

The low-level HTTP/2 support is provided by `org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory` and `org.eclipse.jetty.http2.api.server.ServerSessionListener`:

[,java,indent=0]
----
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/server/http2/HTTP2ServerDocs.java[tags=setup]
----

Where server applications using the xref:server/http.adoc[high-level server library] deal with HTTP requests and responses in ``Handler``s, server applications using the low-level HTTP/2 server library deal directly with HTTP/2 __session__s, __stream__s and __frame__s in a `ServerSessionListener` implementation.

The `ServerSessionListener` interface defines a number of methods that are invoked by the implementation upon the occurrence of HTTP/2 events, and that server applications can override to react to those events.

Please refer to the `ServerSessionListener` link:{javadoc-url}/org/eclipse/jetty/http2/api/server/ServerSessionListener.html[javadocs] for the complete list of events.

The first event is the _accept_ event and happens when a client opens a new TCP connection to the server and the server accepts the connection.
This is the first occasion where server applications have access to the HTTP/2 `Session` object:

[,java,indent=0]
----
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/server/http2/HTTP2ServerDocs.java[tags=accept]
----

After connecting to the server, a compliant HTTP/2 client must send the https://tools.ietf.org/html/rfc7540#section-3.5[HTTP/2 client preface], and when the server receives it, it generates the _preface_ event on the server.
This is where server applications can customize the connection settings by returning a map of settings that the implementation will send to the client:

[,java,indent=0]
----
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/server/http2/HTTP2ServerDocs.java[tags=preface]
----

[[request]]
== Receiving a Request

Receiving an HTTP request from the client, and sending a response, creates a _stream_ that encapsulates the exchange of HTTP/2 frames that compose the request and the response.

An HTTP request is made of a `HEADERS` frame, that carries the request method, the request URI and the request headers, and optional `DATA` frames that carry the request content.

Receiving the `HEADERS` frame opens the `Stream`:

[,java,indent=0]
----
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/server/http2/HTTP2ServerDocs.java[tags=request]
----

Server applications should return a `Stream.Listener` implementation from `onNewStream(\...)` to be notified of events generated by the client, such as `DATA` frames carrying request content, or a `RST_STREAM` frame indicating that the client wants to _reset_ the request, or an idle timeout event indicating that the client was supposed to send more frames but it did not.

The example below shows how to receive request content:

[,java,indent=0]
----
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/server/http2/HTTP2ServerDocs.java[tags=requestContent]
----

[NOTE]
====
When `onDataAvailable(Stream stream)` is invoked, the demand is implicitly cancelled.

Just returning from the `onDataAvailable(Stream stream)` method does _not_ implicitly demand for more `DATA` frames.

Applications must call `Stream.demand()` to explicitly require that `onDataAvailable(Stream stream)` is invoked again when more `DATA` frames are available.
====

Applications that consume the content buffer within `onDataAvailable(Stream stream)` (for example, writing it to a file, or copying the bytes to another storage) should call `Data.release()` as soon as they have consumed the content buffer.
This allows the implementation to reuse the buffer, reducing the memory requirements needed to handle the content buffers.

Alternatively, an application may store away the `Data` object to consume the buffer bytes later, or pass the `Data` object to another asynchronous API (this is typical in proxy applications).

[IMPORTANT]
====
The call to `Stream.readData()` tells the implementation to enlarge the stream and session flow control windows so that the sender will be able to send more `DATA` frames without stalling.
====

Applications can unwrap the `Data` object into some other object that may be used later, provided that the _release_ semantic is maintained:

[,java,indent=0]
----
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/HTTP2Docs.java[tags=dataUnwrap]
----

[IMPORTANT]
====
Applications that implement `onDataAvailable(Stream stream)` must remember to call `Stream.demand()` eventually.

If they do not call `Stream.demand()`, the implementation will not invoke `onDataAvailable(Stream stream)` to deliver more `DATA` frames and the application will stall threadlessly until an idle timeout fires to close the stream or the session.
====

[[response]]
== Sending a Response

After receiving an HTTP request, a server application must send an HTTP response.

An HTTP response is typically composed of a `HEADERS` frame containing the HTTP status code and the response headers, and optionally one or more `DATA` frames containing the response content bytes.

The HTTP/2 protocol also supports response trailers (that is, headers that are sent after the response content) that also are sent using a `HEADERS` frame.

A server application can send a response in this way:

[,java,indent=0]
----
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/server/http2/HTTP2ServerDocs.java[tags=response;!exclude]
----

[[reset]]
== Resetting a Request

A server application may decide that it does not want to accept the request.
For example, it may throttle the client because it sent too many requests in a time window, or the request is invalid (and does not deserve a proper HTTP response), etc.

A request can be reset in this way:

[,java,indent=0]
----
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/server/http2/HTTP2ServerDocs.java[tags=reset;!exclude]
----

[[push]]
== HTTP/2 Push of Resources

A server application may _push_ secondary resources related to a primary resource.

A client may inform the server that it does not accept pushed resources(see https://tools.ietf.org/html/rfc7540#section-8.2[this section] of the specification) via a `SETTINGS` frame.
Server applications must track `SETTINGS` frames and verify whether the client supports HTTP/2 push, and only push if the client supports it:

[,java,indent=0]
----
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/server/http2/HTTP2ServerDocs.java[tags=push]
----
