この記事はkdnaktの1人 Advent Calendar 2020の2日目の記事です。
2020年は会社でKotlin dojoを主催して週1回30分Kotlinと戯れていました。12月はその集大成ということで、KotlinでHTTPサーバーを作ってみたいと思います。どこまでできるか、お楽しみ……。
[パッケージデザイン]
KotlinでHTTPサーバーを作るとは言ったものの、どういうモノができあがるとユーザーに使いたいと思ってもらえるでしょうか。世の中で使われているHTTPサーバーのランキングを見ると、ここ1年くらいはNginxが優勢だとするブログ記事もありますが、やはりHTTPサーバーというとApache HTTP Server(以下、Apacheと省略)でしょう(偏見)*1。
したがって、長らくHTTPサーバーのトップであったApache HTTP Serverと互換性のあるHTTPサーバーを作れば、使ってみたいと思わせることができるのではないでしょうか。
具体的には、Apacheの設定ファイルである、httpd.confファイルをそのまま流用できるようなHTTPサーバーを作っていきたいと思います。
……というのはあくまで理想論。
Apacheと互換性のあるHTTPサーバーを作ると宣言したものの、Apacheの機能は豊富すぎて、私の能力では1か月やそこらですべてを実装しきることは不可能です。
また、何も道筋のないところからHTTPサーバーってこういうものだよね、と考えて作っていってもよいのですが、アドベントカレンダーの期間内に一定の形に仕上げたいという時間的な制約もあります。
[プロダクトバックログ]
以下の資料を参考にプロダクトバックログを考えます。
新しいプログラミング言語の学び方 HTTPサーバーを作って学ぶ Java, Scala, Clojure - Speaker Deck
また、ApacheのサイトやReal World HTTP 第2版を参考に、一般的なHTTPサーバーにできることも追加します。
- 起動すると、localhostの固定のポートでHTTPリクエストを待ち受ける
- GETリクエストに対応する
- POSTリクエストに対応する
- その他のHTTPリクエストに対応する
- publicディレクトリより上の階層へのリクエストは403を返す
- リクエストをブロックしない(マルチスレッド)
- httpd.confに対応する
- アクセスログを書き出す
- Cookieに対応する
- Basic認証に対応する
- Keep-Aliveする
- HTTP Cacheする
- SSL/TLSに対応する
- WebSocketに対応する
- HTTP/2に対応する
- HTTP/3に対応する
HTTPに対する理解が浅いので、追加したバックログの粒度がバラバラであるという問題があります。たとえば、「Basic認証に対応する」のような比較的小さいものから、「HTTP/3に対応する」といったとても今回のアドベントカレンダーの範囲で扱えないようなものまでリストアップされています。
最低限、新しいプログラミング言語の学び方で取り上げられている内容を実装したいと思います。また、これだけでは「Apache HTTP Serverと互換性のあるHTTPサーバー」を名乗るには程遠いので、いくつかの設定項目(ディレクティブ)に限定しつつhttpd.confにも対応していきたいと思います。
余力があれば、POSTリクエストに対応したり、アクセスログを出力したり、CookieやBasic認証にも対応します。
[まとめ]
アドベントカレンダーで実装するHTTPサーバーのスコープを以下のように定めました。
- 新しいプログラミング言語の学び方を参考に実装を進める
- Apache HTTP Serverのhttpd.confに部分的に対応する
- 余力があれば、GET以外のHTTPリクエストや、アクセスログに対応する
3日目からは、いよいよコードを書いていきたいと思います。