2013年5月29日水曜日

ngx_array_tを使う

nginx moduleの開発をしていたときのメモ#1


nginx実装の配列ngx_array_tの使用例

使い方は、
  1. 配列の領域を確保する
    // ngx_str_t を10個保持する配列作成
    static void *
    ngx_sample_test(ngx_conf_t *cf) {
      ...
      ngx_array_t arr;
      if (ngx_array_init(&arr, cf->pool, 10, sizeof(ngx_str_t)) != NGX_OK) {
        return NULL;
      }
      ...
    

  2. 取り出して値を入れる
      // aにコピーして使う
      ngx_str_t *a;
      a = ngx_array_push(&arr);
      if (a == NULL) {
        return NULL;
      }
      ngx_memzero(a, sizeof(ngx_str_t));
      ngx_memcpy(a, コピー元, sizeof(ngx_str_t));
      ...
    

  3. 配列を回す
      // arr.eltsは配列のポインタ、arr.neltsは配列数を保持している
      // ngx_str_tを出力するときは %V を使う
      ngx_str_t *value;
      ngx_uint_t i;
      value = arr.elts;
      for (i=0; i<arr.nelts; i++) {
        ngx_conf_log_error(NGX_LOG_DEBUG, cf, 0, "arr[%d]=%V", i, &value[i]);
      }
      ...
    

と意外と普通であった(もっと小難しいかと思っていた)。



2013年5月28日火曜日

stdoutに流れたログをチェックする

stdoutに流れたログをチェックするのはターミナルのスクロールバーで遡れば良いだけの話ですが、、
ここで一つ小技を。
tmux使っている前提で、"<prefix>+[" でコピーモードになる様なのだけど、emacsと同じ操作で上下左右自由に動ける。 
これは便利である。 

2013年5月7日火曜日

ngx_http_upstream_rr_peer_t 調査

nginxの構造体ngx_http_upstream_rr_peer_tはupstreamの情報を格納するのに使われている。
このメンバの ngx_str_t name; はupstreamのserver名を格納している。

ngx_str_tは
typedef struct {
    size_t      len;
    u_char     *data;
} ngx_str_t;
文字列と長さを格納している。

nginxをreloadするとこのname.dataにゴミが乗ることがある(version 1.2.8で確認)。
どこで混在するのか調べきれてないが、ngx_str_tのdataをそのまま信用するのは危ない感じである。
lenをチェックしてみたところlenは不正な値が入ることは無さそうで信頼できそうである。

これを踏まえて、ngx_str_tのdataを比較する場合は、単純にngx_strcmpだと上述のため危険であるので、
ngx_str_tのlenが同じ且つngx_strncmpで比較するのが正確そうである。

こんな感じのものを用意することにした。
int ngx_strtcmp(ngx_str_t *s1, ngx_str_t *s2) {
  if (s1->len == s2->len) {
    return ngx_strncmp(s1->data, s2->data, s1->len);
  }
  return ngx_strcmp(s1->data, s2->data);
}