22
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

RustでHTTP/2+TLS対応なWebAPIの入口を作ってみる

Last updated at Posted at 2018-06-07

追記

セッション管理機構が貧弱すぎる(登録してないユーザがシステムを閲覧できちゃうかも)ので、
対応策を考えてみる記事も別途書いた。
Rust WebフレームワークのACTIXで使う安全なセッション管理機構を考えてみる

はじめに

最近ラズパイ使ったIoTとかAndroid使ったIoTが流行りじゃないですか。
で、Rustも流行ってるじゃないですか(俺の中では)

というわけで何となくホストサーバと会話できるようなAPIを作りたくなった。

ただ、HTTP/1.1はなんか個人的にバイナリじゃないのが嫌なので
バイナリな感じのHTTP/2でやりたかった。

HTTP/2ことはじめ

なーかなかRustでHTTP/2を喋れる良いAPIがなかった

  • iron:割と有名なやつだけどHTTP/2しゃべれない、TLSに対応させようとするとルーティングがなぜか80番ポートに誘導される。原因はわかってるからパッチ送ったけど、反映されず(おそらく英語に難ありなので理解されてない気がするが、この際どうでもいい) なんか2018年7月8日に反映されてた。→ironは公式で非推奨となっていた。(NOTE: Iron is not actively maintained at the moment, please consider using a different framework) →再び開発が再開されました。(Revert "README: Add note about maintenance status of iron (#576)" · iron/iron@9ad396d)
  • gRPC:セッション管理機能が未実装
  • rust-http2:この状態からどうしろと・・・(ドキュメントが壊滅)

セッション管理ができて、暗号化・サーバの真正性検証ができるライブラリないかなー
とか探してたら、偶然見つけた。

上記すべての要件を満たすFW:ACTIX

  • ミドルウェアでセッション管理対応
  • TLS対応
  • HTTP/2対応
  • 何よりもドキュメントが豊富

これはいいぞ。

というわけでサクッとコードをWeb Application Server by Rust with actix-web(@atsukさん)とか公式からコピペしつつ、とりあえず動くものを作ってみた。

#![allow(unused_variables)]
extern crate actix;
extern crate actix_web;
extern crate openssl;

use actix_web::*;
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};

// リクエストハンドラ(リクエストが飛んできたときに処理するやつ)
fn index(info: Path<(u32, String)>) -> String {
    format!("Hello {}! id:{}", info.1, info.0)
}

fn main() {
    let sys = actix::System::new("http2_api-test");

    let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
    builder.set_private_key_file("key.pem", SslFiletype::PEM).unwrap();
    builder.set_certificate_chain_file("cert.pem").unwrap();
    
    server::new(|| {
        App::new()
            // 直接来たらIDと名前を表示する。処理関数は↑の"index"
            .route("/{id}/{name}/index.html", http::Method::GET, index)
            // rootに来たらリダイレクトする。
            .resource("/", |r| r.method(http::Method::GET).f(|req| {
                HttpResponse::Found()
                    .header("LOCATION", "/0/anonymouse/index.html")
                    .finish()
                })
            )
    }).bind_ssl("127.0.0.1:8443", builder).unwrap().start();

    println!("Started http server: 127.0.0.1:8443");
    let _ = sys.run();
}

おもむろに
https://localhost:8443/
にアクセスすると
https://localhost:8443/0/anonymouse/index.html
にリダイレクトされる。

ヤッター

image.png

キター

image.png

というわけで、レスポンスの構造体をProtocolBuffersとかmessagepackにしてやれば、バイナリな感じのAPIができて俺マジで幸せ。

ってなる。(気がする)

多分使うのはIDLからコード生成できるProtocolBuffers使う気がする。

んでは以上。

22
14
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
22
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?