ngx-queue.h

libuv のソースを見ていたら、ngx_queue_* という API が出てきてびっくり。どうやら nginx から ngx-queue.h っていうリンクドリストの実装を持ってきているようだ。

include/uv-private/ngx-queue.h at master from joyent/libuv - GitHub

なかなかおもしろい。これ、いろんなところで使えそうなので手元でも試してみた。

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>

#include "ngx-queue.h"

typedef struct {
    ngx_queue_t queue;
    char* data;
} chunk_t;

chunk_t* chunk_init(const char* data, size_t len) {
    chunk_t* c = malloc(sizeof(chunk_t));
    assert(c);

    ngx_queue_init(&c->queue);

    c->data = malloc(len + 1);
    assert(c->data);
    memcpy(c->data, data, len);
    c->data[len] = '\0';

    return c;
}

void chunk_delete(chunk_t* c) {
    ngx_queue_remove(&c->queue);
    free(c->data);
    free(c);
}

int main(int argc, char** argv) {
    ngx_queue_t queue;
    chunk_t* chunk;

    ngx_queue_init(&queue);

    chunk = chunk_init("foo", 3);
    ngx_queue_insert_tail(&queue, &chunk->queue);

    chunk = chunk_init("bar", 3);
    ngx_queue_insert_tail(&queue, &chunk->queue);

    chunk = chunk_init("buz", 3);
    ngx_queue_insert_tail(&queue, &chunk->queue);

    while (!ngx_queue_empty(&queue)) {
        ngx_queue_t* q = ngx_queue_head(&queue);
        chunk_t* c = ngx_queue_data(q, chunk_t, queue);

        printf("data: %s\n", c->data);

        chunk_delete(c);
    }


    chunk = chunk_init("foo", 3);
    ngx_queue_insert_tail(&queue, &chunk->queue);

    chunk = chunk_init("bar", 3);
    ngx_queue_insert_tail(&queue, &chunk->queue);

    chunk = chunk_init("buz", 3);
    ngx_queue_insert_tail(&queue, &chunk->queue);

    while (!ngx_queue_empty(&queue)) {
        ngx_queue_t* q = ngx_queue_last(&queue);
        chunk_t* c = ngx_queue_data(q, chunk_t, queue);

        printf("data: %s\n", c->data);

        chunk_delete(c);
    }

    return 0;
}

出力は

$ ./a.out
data: foo
data: bar
data: buz
data: buz
data: bar
data: foo

これは使えるなぁ。

by typester / at 2011-11-15T17:38:00 / libuv · nginx / Comment

nginx で lighttpd のようにユーザーをトラッキングする方法

lighttpd では mod_fastcgi や mod_proxy 経由でアプリケーションが、

X-Lighttpd-Hogehoge: foobar

のような X-Lighttpd- ではじまるヘッダーを返してもそれをクライアントに送り返さないという仕組みがあり、 たとえばそれを利用してアプリからユーザーIDを返してあげたりすると、それをクライアントに送ることなく lighttpd のアクセスログにだけ記録する、といったようなことが出来て便利なのですが、 同じようなことを nginx でやりたかったのでしらべてみた。

アプリから

X-MyApp-User: foobar

みたいなのを返してそれをクライアントに送ることなくアクセスログに記録したい場合、まずクライアントに送らないように、

proxy_hide_header X-MyApp-User;

とし、さらに accesslog のフォーマット設定 log_format

$upstream_http_x_myapp_user

を追加することで記録が行えました。まる。

追記@2011-11-08T16:22:26+09:00

$upstream_http_myapp_user $upstream_http_x_myapp_user

だったので修正。

by typester / at 2011-11-08T13:46:00 / nginx / Comment