---
title: Reactor NettyでHTTP/3対応サーバーを作る
tags: ["Reactor", "HTTP/3", "Java"]
categories: ["Programming", "Java", "reactor", "netty", "http"]
date: 2024-05-16T04:16:07Z
updated: 2024-05-16T04:20:45Z
---
[Reactor Netty 1.2.0-M2](https://github.com/reactor/reactor-netty/releases/tag/v1.2.0-M2) でHTTP/3が対応されたので"Hello World!"を試してみます。
`pom.xml`に以下の依存ライブラリを追加します。
```xml
io.projectreactor.netty
reactor-netty-http
io.netty.incubator
netty-incubator-codec-http3
0.0.28.Final
io.projectreactor
reactor-bom
2024.0.0-M2
pom
import
```
[ドキュメント](https://projectreactor.io/docs/netty/milestone/reference/http-server.html#HTTP3)に従って次のようなコードを記述します。
```java
package com.example;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import reactor.core.publisher.Mono;
import reactor.netty.DisposableServer;
import reactor.netty.http.Http3SslContextSpec;
import reactor.netty.http.HttpProtocol;
import reactor.netty.http.server.HttpServer;
import java.time.Duration;
public class Application {
public static void main(String[] args) throws Exception {
SelfSignedCertificate cert = new SelfSignedCertificate();
Http3SslContextSpec serverCtx = Http3SslContextSpec.forServer(cert.privateKey(), null, cert.certificate());
DisposableServer server = HttpServer.create()
.port(8443)
.protocol(HttpProtocol.HTTP3)
.secure(spec -> spec.sslContext(serverCtx))
.idleTimeout(Duration.ofSeconds(5))
.http3Settings(spec -> spec.maxData(10000000)
.maxStreamDataBidirectionalLocal(1000000)
.maxStreamDataBidirectionalRemote(1000000)
.maxStreamsBidirectional(100))
.handle((request, response) -> response.header("server", "reactor-netty")
.sendString(Mono.just("Hello HTTP/3!")))
.bindNow();
server.onDispose().block();
}
}
```
HTTP/3はTLSの設定が必要です。自己署名証明書を自動生成するため、依存ライブラリとして[`org.bouncycastle:bcpkix-jdk18on`](https://central.sonatype.com/artifact/org.bouncycastle/bcpkix-jdk18on)を追加しています。
次のコマンドでアプリケーションを起動します。
```
$ ./mvnw -q compile exec:java -Dexec.mainClass=com.example.Application
2024-05-16 12:56:09.034 DEBUG --- [lication.main()] reactor.netty.tcp.TcpResources : [http] resources will use the default LoopResources: DefaultLoopResources {prefix=reactor-http, daemon=true, selectCount=12, workerCount=12}
2024-05-16 12:56:09.035 DEBUG --- [lication.main()] reactor.netty.tcp.TcpResources : [http] resources will use the default ConnectionProvider: reactor.netty.resources.DefaultPooledConnectionProvider@7cca24c4
2024-05-16 12:56:09.036 DEBUG --- [lication.main()] r.netty.resources.DefaultLoopIOUring : Default io_uring support : false
2024-05-16 12:56:09.039 DEBUG --- [lication.main()] r.netty.resources.DefaultLoopEpoll : Default Epoll support : false
2024-05-16 12:56:09.040 DEBUG --- [lication.main()] r.netty.resources.DefaultLoopKQueue : Default KQueue support : false
2024-05-16 12:56:09.096 DEBUG --- [ctor-http-nio-1] r.netty.transport.ServerTransport : [e56a5924, L:/[0:0:0:0:0:0:0:0]:8443] Bound new server
```
HTTP/3に対応した`curl`でアクセスします。
> [!NOTE]
> HTTP/3に対応した`curl` をHomebrewでインストールする方法は[こちらの記事](/entries/792)を参照してください。
```
$ curl -kv --http3 https://localhost:8443
* Host localhost:8443 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:8443...
* Server certificate:
* subject: CN=localhost
* start date: May 17 03:56:08 2023 GMT
* expire date: Dec 31 23:59:59 9999 GMT
* issuer: CN=localhost
* SSL certificate verify result: self signed certificate (18), continuing anyway.
* Connected to localhost (::1) port 8443
* using HTTP/3
* [HTTP/3] [0] OPENED stream for https://localhost:8443/
* [HTTP/3] [0] [:method: GET]
* [HTTP/3] [0] [:scheme: https]
* [HTTP/3] [0] [:authority: localhost:8443]
* [HTTP/3] [0] [:path: /]
* [HTTP/3] [0] [user-agent: curl/8.8.0-DEV]
* [HTTP/3] [0] [accept: */*]
> GET / HTTP/3
> Host: localhost:8443
> User-Agent: curl/8.8.0-DEV
> Accept: */*
>
* Request completely sent off
< HTTP/3 200
< server: reactor-netty
< content-length: 13
<
* Connection #0 to host localhost left intact
Hello HTTP/3!
```
`HTTP/3 200`でレスポンスが返りました。
HTTP/3しか対応していないためか、ブラウザでアクセスしてもアクセスはできませんでした。