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
これは使えるなぁ。
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
だったので修正。