Rust の Hyper で受けとったリクエストに入っている Cookie の複数の値を取り扱う

ふとしです。

あけましておめでとうございます。

Cookie を取り扱う関数はなくなった

0.11 の時点では存在していたようですが、0.12 の時点ではすでになくなっていたようです。

いまでは http クレートから re-export されたヘッダー名定数しか痕跡がありません。

cookie クレートを使う

ごく単純には cookie クレートを使えば解決します。

cookie  = { version = "0.14.3", features= ["percent-encode"] }
let (head, body) = req.into_parts();

match head.headers.get(COOKIE) {
    None => Err(FooError::EmptyCookie),
    Some(c) => {
        let cookie = Cookie::parse_encoded(c.to_str()?)?;
        Ok(cookie)
    }
}

ただしこの場合、先頭の key value ペアひとつだけしか得られません。挿入順に依存した結果となるので嬉しくありません。

Rocket の方式を使う

let mut jar = CookieJar::new();
let (head, body) = req.into_parts();

for header in head.headers.get_all(COOKIE) {
    let raw_str = match std::str::from_utf8(header.as_bytes()) {
        Ok(string) => string,
        Err(_) => continue,
    };

    for cookie_str in raw_str.split(';').map(|s| s.trim()) {
        if let Ok(cookie) = Cookie::parse_encoded(cookie_str) {
            jar.add_original(cookie.into_owned());
        }
    }
}

jar

これで望む値が手に入れられるようになりました。