メモ代わり。てきとーに。 いや、ですからてきとーですって。 2年前ぐらいにPythonあたりでメールくれた方、ごめんなさい。メール紛失してしまい無視した形になってしまいました。。。

2008年5月19日月曜日

[libserf] libserfを調べてみた

css変換部からHTTPリクエストを発行したいので、Javaで言う、
httpclientのようなライブラリを探してみた。
有名どころとしては、libneonとlibserfらしい。
libneonはGPL。libserfはApache Licence 2.0。なので、できればlibserfを使いたい。

ということでlibserfを調べてみた。

処理の大きな流れは以下のとおり。

  1. serf用のpoolを用意する。
  2. apr_sockaddr_info_get()を使ってapr_socketaddr_tを取得する。
  3. serf_context_create()を使ってserf_context_tを生成。
  4. serf_connection_create()でserf_connection_tを生成。
  5. serf_connection_request_create()でserf_request_tを生成。
  6. serf_context_run()でループする。
  7. 終了を何かしらの方法で検知したら、ループを終了する。
  8. serf_connection_close()でコネクションを終了。
  9. serf用poolの解放。

このほかに、
  1. コネクション確立時にコールされるコールバック
  2. コネクション解放時にコールされるコールバック
  3. 実際に投げるリクエストを生成するためのコールバック
  4. レスポンスをacceptしたときにコールされるコールバック
  5. レスポンスの内容を処理するコールバック
を用意する必要がある。

コネクション確立時のコールバック関数

typedef serf_bucket_t * (*serf_connection_setup_t)(apr_socket_t *skt,
void *setup_baton,
apr_pool_t *pool);
 

と定義されているので、このインタフェースを満たす巻数を用意する。
やることは、コネクション確立時にapr_socket_tをserf用socketにwrapすること。
setup_batonはserf_connection_create()時にsetup_batonに渡されたものがわたってくる。

コネクション解放時にコールされるコールバック

typedef void (*serf_connection_closed_t)(serf_connection_t *conn,
void *closed_baton,
apr_status_t why,
apr_pool_t *pool);
 

と定義されている。
目的はコネクション切断を通知するもの。
切断時のステータスがwhyに入ってくる。
コネクション切断時にエラーが起きているなら、ここで何か処理をすることができる。

実際に投げるリクエストを生成するためのコールバック

typedef apr_status_t (*serf_request_setup_t)(serf_request_t *request,
void *setup_baton,
serf_bucket_t **req_bkt,
serf_response_acceptor_t *acceptor,
void **acceptor_baton,
serf_response_handler_t *handler,
void **handler_baton,
apr_pool_t *pool);
 

と定義されている。
1リクエストを生成し、設定することが目的。生成したリクエストはreq_bktに設定してやる。
また、レスポンスをacceptしたときのコールバック、レスポンスを処理するコールバックも
本関数で設定する。レスポンスをacceptしたときのコールバックは、acceptorに、
レスポンスを処理するコールバックは、handlerにそれぞれセットする。
本処理に渡したいものがあれば、serf_connection_request_create()の第三引数として渡して
あげれば、本関数のsetup_batonパラメータにセットされてわたってくる。

レスポンスをacceptしたときにコールされるコールバック

typedef serf_bucket_t * (*serf_response_acceptor_t)(serf_request_t *request,
serf_bucket_t *stream,
void *acceptor_baton,
apr_pool_t *pool);
 

目的は、パラメータのrequestに対応するレスポンス用serf_bucket_t領域の生成や確保。
acceptor_batonはserf_request_setup_tの方でセットしたものが渡される。
streamをwrapしてやったりする(serf_bucket_barrier_create()でできる)。


レスポンスの内容を処理するコールバック

typedef apr_status_t (*serf_response_handler_t)(serf_request_t *request,
serf_bucket_t *response,
void *handler_baton,
apr_pool_t *pool);
 

と定義されている。
レスポンスデータが届いたときに行うべき処理をここで書く。
handler_batonはserf_request_setup_tの中で設定した値がわたってくる。



ということで大体わかった。
次に実際にコードを書いてみるつもり。

.

0 コメント: