IK.AM


Programming > Java > reactor > netty > http

Reactor NettyでHTTP/3対応サーバーを作る

Created on Thu May 16 2024 • Last Updated on Thu May 16 2024N/A Views

🏷️ Reactor | HTTP/3 | Java

Reactor Netty 1.2.0-M2 でHTTP/3が対応されたので"Hello World!"を試してみます。

pom.xmlに以下の依存ライブラリを追加します。

    <dependencies>
        <dependency>
            <groupId>io.projectreactor.netty</groupId>
            <artifactId>reactor-netty-http</artifactId>
        </dependency>
        <dependency>
            <groupId>io.netty.incubator</groupId>
            <artifactId>netty-incubator-codec-http3</artifactId>
            <version>0.0.28.Final</version>
        </dependency>
        <!-- ... -->
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.projectreactor</groupId>
                <artifactId>reactor-bom</artifactId>
                <version>2024.0.0-M2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

ドキュメントに従って次のようなコードを記述します。

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を追加しています。

次のコマンドでアプリケーションを起動します。

$ ./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でインストールする方法はこちらの記事を参照してください。

$ 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しか対応していないためか、ブラウザでアクセスしてもアクセスはできませんでした。

Found a mistake? Update the entry.