//
// ========================================================================
// 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/3 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/3 support via the HTTP/3 connector and ``ConnectionFactory``s as described in details xref:server/http.adoc#connector-protocol-http3[here].

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

See also the correspondent xref:client/http3.adoc[HTTP/3 client library].

[[intro]]
== Introduction

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

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

HTTP/3 is a multiplexed protocol because it relies on the multiplexing capabilities of QUIC, the protocol based on UDP that transports HTTP/3 frames.
Thanks to multiplexing, multiple HTTP/3 requests are sent on the same QUIC 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.

// TODO: flow control?
//[[pg-server-http3-flow-control]]
//==== HTTP/3 Flow Control
//
//include::../../http3.adoc[tag=flowControl]
//
//How a server application should handle HTTP/3 flow control is discussed in details in <<request,this section>>.

[[setup]]
== Server Setup

The low-level HTTP/3 support is provided by `org.eclipse.jetty.http3.server.RawHTTP3ServerConnectionFactory` and `org.eclipse.jetty.http3.api.Session.Server.Listener`:

[,java,indent=0]
----
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/server/http3/HTTP3ServerDocs.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/3 server library deal directly with HTTP/3 __session__s, __stream__s and __frame__s in a `Session.Server.Listener` implementation.

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

Please refer to the `Session.Server.Listener` link:{javadoc-url}/org/eclipse/jetty/http3/api/Session.Server.Listener.html[javadocs] for the complete list of events.

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

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

After the QUIC connection has been established, both client and server send an HTTP/3 `SETTINGS` frame to exchange their HTTP/3 configuration.
This generates the _preface_ event, where applications can customize the HTTP/3 settings by returning a map of settings that the implementation will send to the other peer:

[,java,indent=0]
----
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/server/http3/HTTP3ServerDocs.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/3 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/http3/HTTP3ServerDocs.java[tags=request]
----

Server applications should return a `Stream.Server.Listener` implementation from `onRequest(...)` to be notified of events generated by the client, such as `DATA` frames carrying request content, or a reset event 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/http3/HTTP3ServerDocs.java[tags=requestContent]
----

// TODO: flow control?
//include::../../http3.adoc[tag=apiFlowControl]

[[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/3 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/http3/HTTP3ServerDocs.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/http3/HTTP3ServerDocs.java[tags=reset;!exclude]
----
