この記事は、Rustアドベントカレンダー21日目の記事です。
はじめに
この記事は、
- Rust 1.5
- hyper 0.6.15
- cookie 0.1
- url
の環境においての説明を行っています。
hyper
hyper は github上で星を1300集めているHTTP通信を行うためのライブラリです。今回はこのライブラリの話をしようと思います。
hyperでリダイレクト時にCookieが含まれない
hyperを使い、外部に対して通信を行う処理を書いていたのですが、リダイレクトを行う必要がある時にうまくcookieを覚えてくれないことに気づきました。hyper自体にcookieを扱う機能は用意されているのですが、一回のリクエストに対してどんなCookieを与えるか ということであり Set-Cookie
には対応していないようです。
また勉強不足なのかもしれませんが、現時点において、GithubでSetCookieで検索しても、あまりHITしません。
Set-Cookie を処理する
hyperでCookieを保持するには、サーバーから送られてきたレスポンスヘッダに含まれるSet-Cookie
を処理する必要があります。今回はこれを、hyper自体を書き換えず、hyperのラッパーCrateを作成して対応することにしました。
なので正確にはhyperに対応させるのではなく、hyperの管理しているheaderをラッパーCrateが管理し、その際にSet-Cookieを処理するということになります。
let res = self.client
.post(url)
.body(&request_body.to_owned())
.headers(self.headers.clone())
.send();
上記はhyperの例です。resにはOption<[Response](http://hyper.rs/hyper/hyper/client/response/struct.Response.html)>が返っています。
Responseは、フィールドに、headers を持っています。このheadersに含まれる、Set-Cookie
を抽出し、ラッパーCrateのheadersに上書きすることを繰り返すことで、cookieを覚えさせる事ができます。
リダイレクトさせる
標準のhyperはデフォルトでリダイレクトに対応していますが、Cookieを覚えてくれないのでhyperのリダイレクト機能をオフにします。
self.client.set_redirect_policy(RedirectPolicy::FollowNone);
リダイレクトポリシーをFollowNone
にすることで、自動的にリダイレクトしなくなります。
後は、Responseのフィールドのstatusを見て、再帰処理によってリダイレクトを行うと良いです。
if res.unwrap().status == StatusCode::MovedPermanently || v.status == StatusCode::Found {
}
サンプルコード
ここまでの処理を サンプルコード にして公開しました。セキュリティリスクをほとんど考えてないので、使用は自己責任でお願いします。また、ライセンスはパブリックドメインです。ご自由にお使いください。