LoginSignup
14
8

More than 5 years have passed since last update.

C/C++アプリケーション組込みHTTPサーバの調査

Last updated at Posted at 2019-02-20

諸般の事情でアプリにHTTPサーバを組込む必要が生じたので、世間の実装を調査した。

これは網羅的なリストでない 。例えば、他にもGNU libmicrohttpd( https://www.gnu.org/software/libmicrohttpd/ )とかRESTinio( https://github.com/Stiffstream/restinio )、Seasocks( https://github.com/mattgodbolt/seasocks )、facil.io( https://github.com/boazsegev/facil.io ) 等がある。

プロトコルパーサだけ

完全なHTTPサーバ実装では(移植性のない)ネットワーク廻りを内包する必要があるため、プロトコルパーサだけというクラスのライブラリがある。

http_parser

nodejsは、HTTPプロトコルパーサだけをネイティブのCで持ち、リクエストのハンドリングをJavaScriptで実装するデザインになっている。インタプリタとの接続は結構大変な仕事なので、上手い分割だと思う。

パーサのコードは力技としか言いようがない。ステートマシンを手で実装しており、1文字づつディスパッチする実装になっている。

llhttp

... で、人間にはメンテナンスのしようがないhttp_parserを機械生成に替えたものがllhttpで、Cソースや LLVM bitcode を出力する。気持は解るけどre2cのような既存のコンパイラに比べて速いんだろうか。

ライブラリ

ライブラリはそれなりに選択肢がある。ちゃんと探せばこの倍以上は見つかるのではないか。

Mongoose

この分野でもっとも有名なのはMongooseだろう。ライセンスがGPL2になったためいくつかforkもある。シングルソース実装で、WebSocketやMQTTを実装するとともに、クライアント側の実装も自前のDNSリゾルバを持つなど充実している。同じ開発元のJavaScriptサブセット( https://github.com/cesanta/mjs )等と合わせて、Mongoose OSの一部を構成している。

TCPスタックとしてPicoTCPやLWIPを選択できる等基本的にマイコン指向の実装になっている。用途によってはoverkillになるが、便利なライブラリと言える。

beast

Mongooseの対極と言うと。。Boost.Asio上に実現されたHTTPライブラリであるところのBeastだろうか。こちらも、クライアントとサーバの両方を実装していて、WebSocketもサポートしている。

広範に強力な抽象化を提供しているものの、routerに相当する機能性は提供していない。 FAQ によると、

The authors feel that this is a responsibility of higher level code. Beast does not try to offer a web server.

cpp-httplib

cpp-httplibはrouterも含んだHTTPサーバ/クライアントライブラリで、 リクエストのパースは <regex> で実装している 。C++標準ライブラリの強力さを示す例と言えるかもしれない。

EmbeddableWebServer

EmbeddableWebServerはシングルヘッダオンリーのC/C++ Polygot実装で、Rack風に GET / POST ハンドラを書くことでアプリケーションを提供できる。

リクエストのパースは普通のステートマシンで、メソッド毎のディスパッチはユーザ側で(必要に応じて)行う。

yocto HTTP server

yoctoはシングルソース実装で、WebSocketやフォームのハンドリングも含む比較的広範な機能を実装している。ディスパッチは普通に strcmp

実際に組込まれているWebサーバ

独立したライブラリとしては提供されず、アプリケーションに実際に組込まれているものもある。切り出して使うのはあんまり現実的でないが、機能の取捨選択は参考になるかもしれない。

OpenSSLコマンド

openssls_server コマンドにはWebサーバが搭載されている。 ...あんまり必要性を感じたことがないが、実際 s_client の方はたまに使うのでまぁテスト用コマンドが充実するのは悪いことではないのかもしれない。

HTTPとしては GET だけが実装されていて、組込みの /stats などを除くと基本的に静的なファイルのserveに特化している。少し特徴的なのは、ファイルにHTTPヘッダを書くモードがあり応答を制御できる点。mockサーバならではの機能性な気がする。

Microprofile

Microprofileはほぼシングルソースで書かれた組込み向けビジュアルプロファイラで、画面上の描画の他にHTTPサーバ経由でブラウザ上にリアルタイムプロファイルを表示する機能がある。

表示用のHTMLを配信する機能の他に、リアルタイム通信のためのWebSocketを実装している。URLは殆どパースしておらず、個々のコマンドに至っては 1文字しか処理していない (フレームの指定のために数値入力もある)。侵入性の低さが求められ、serveすべきリソースが限られているプロファイラならではの実装だと思う。

Remotery

RemoteryもMicroprofileと同じくシングルソース実装のビジュアルプロファイラで、こちらは WebSocketしかサポートしていない 。表示用のWebページはローカルに置くデザインになっている。

... ユーザとしてはページもserveできた方がうれしいかな。。でもフロントエンドのサーバとバックエンドのサーバが分離されるようなケースではこのようなデザインも取れるかもしれない。

感想

Mongoose や cpp-httplib のような便利ライブラリは別として、BeastのようなライブラリまでHTTPクライアントが有るのは何故だろうか。まぁ実際MIMEのパース等は共通する機能性ではあるけど。。

意外とWebSocketの人気が高い。個人的には常にfallbackを考えないといけない印象があってあまり積極的に採用していないけど、営業上は重要な機能に見える。

追記

GitHubを見るたびにたまに右のDiscover欄にHTTPサーバが出るようになってしまったので出る度に書き足すところ。

14
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
8