コンテンツにスキップ

はじめての HTTP/3

HTTP/3 サーバーは、リクエストハンドラーとサーバーの識別情報からなります。 このページのサーバーは、すべてのリクエストに hello と応答します。

コード

main.c
#define WIRED_MAIN
#include "wired.h"
/* Called once per request (and again while *more is set). Fill body_out and
* return 1 to answer 200. */
static int on_request(
void* ctx,
const wired_h3reqdrive_req* req,
u64 offset,
wired_obuf* body_out,
const char** content_type,
int* more,
u64* total_size) {
(void)ctx;
(void)req;
(void)offset;
(void)more;
(void)total_size;
wired_log_str("request /\n");
*content_type = "text/plain";
wired_obuf_printf(body_out, "hello");
return 1;
}
int wired_main(int argc, char** argv) {
/* Fixed demo identity (self-signed certificate; never for production). */
static wired_srvboot_demo_keys keys;
wired_srvboot_id id;
wired_srvboot_demo(&id, &keys, 0x50, "guide-h3");
u16 port = (u16)wired_cliargs_int(argc, argv, "--port", 4433);
wired_srvrun_handler h = {.cb = on_request};
wired_srvrun_obs obs = {0};
return wired_server_run(port, &id, h, obs) ? 0 : 1;
}

実行結果

Terminal window
$ ./h3-hello --port 4433
request /
conn closed by peer (CONNECTION_CLOSE)
Terminal window
$ probe h3get 127.0.0.1:4433 /
GET / status=200 content-type=text/plain body="hello"
  • wired_server_run(port, &id, h, obs) は UDP ポート上で QUIC、TLS 1.3、HTTP/3 を動かし、リクエストごとにハンドラーを 1 回呼びます。
  • wired_srvboot_id はサーバーの識別情報で、X25519(TLS 1.3 の鍵交換アルゴリズム)の鍵ペア、証明書署名用のシード、コネクション ID、ServerHello.random(TLS ハンドシェイクで使う乱数)を持ちます。 wired_srvboot_demo(&id, &keys, 0x50, "guide-h3") が固定のデモ用バイト列で埋めます(自己署名証明書です。本番では使わないでください)。 id は keys の中の鍵を指すので、keys は static にします。
  • ハンドラーは body_out にボディを書き、*content_type を設定して 1 を返します。 0 を返すと、ボディのない 200 が送られます。
  • wired_cliargs_int はコマンドラインから --port を読みます。