Четверг, 4 Декабрь 2008

nginx: пишем свой модуль с переменными

Сегодня днем, мне один человек пожаловался что хорошо бы сделать публичный интерфейс к «добавлению переменных в ssi» в nginx. Как ответ на вопрос и появился этот пост.

Начнем, как обычно, с устройства.

typedef ngx_variable_value_t  ngx_http_variable_value_t;
struct ngx_http_variable_s {
    ngx_str_t                     name;   /* must be first to build the hash */
    ngx_http_set_variable_pt      set_handler;
    ngx_http_get_variable_pt      get_handler;
    uintptr_t                     data;
    ngx_uint_t                    flags;
    ngx_uint_t                    index;
};
  • name — имя переменной
  • set_handler — не используется, зарезервированно
  • get_handler — функция для получения значения
  • data — указатель на данные для получения значения (передаются в get_handler).
  • flag — комбинация флагов
  • index — позиция в r->variables, устанавливается при «компиляции» переменных.

Handler для получения и установки выглядят так:

typedef void (*ngx_http_set_variable_pt) (ngx_http_request_t *r,
    ngx_http_variable_value_t *v, uintptr_t data);
typedef ngx_int_t (*ngx_http_get_variable_pt) (ngx_http_request_t *r,
    ngx_http_variable_value_t *v, uintptr_t data);
  • r — запрос
  • v — значение переменной
  • data — указатель на данные для данной переменной

Значение переменной это:

typedef ngx_variable_value_t  ngx_http_variable_value_t;
typedef struct {
    unsigned    len:28;

    unsigned    valid:1;
    unsigned    no_cacheable:1;
    unsigned    not_found:1;
    unsigned    escape:1;

    u_char     *data;
} ngx_variable_value_t;
  • len — длина значения (почему не больше 256 гигабайт я не знаю, честно, я бы не делал выравнивания или делал его по sizeof(long))
  • valid — флаг что переменная обработана get_handler
  • no_cacheable — флаг что переменная не кешируется
  • not_found — флаг что get_handler не смог найти значение переменой
  • escape — не используется, зарезервированно
  • data — указатель на строчку длинной len без терминирующего символа в конце, где распологается значение переменной

Флаги у переменных могут быть:

#define NGX_HTTP_VAR_CHANGEABLE   1
#define NGX_HTTP_VAR_NOCACHEABLE  2
#define NGX_HTTP_VAR_INDEXED      4
#define NGX_HTTP_VAR_NOHASH       8
  • NGX_HTTP_VAR_CHANGEABLE — кешируемая переменная
  • NGX_HTTP_VAR_NOCHANGEABLE — не кешируемая переменная
  • NGX_HTTP_VAR_INDEXED — индексируемая переменная
  • NGX_HTTP_VAR_NOHASH — не добавлять в хеш

Все переменные должны быть добавлены до начала разбора конфига процесса используя функцию:

ngx_http_variable_t * ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)

Она принимаетм указатель на конфигурацию(cf), имя(name) и флаги(flags). Возвращает переменную в которую надо поставить get_handler, имя и т.д.

Эти переменные видны отовсюду в nginx. Начиная с конфигурации и заканчивая ssi. Вот пример реализации модуля, который добавляет три переменных ($example_vars_host, example_vars_version и example_vars_args). Можно создать простой файл

You GET request: <!--# echo var="example_vars_args" default="empty?" -->

и пропустить его через фильтр ssi.

Написано в: 20:40 | 1 комментарий | | теги: , , , , | постоянная ссылка |
Добавить пост в:   Delicious Reddit Slashdot Digg Technorati Google


Последние комментарии

Комментарии

Винокуров Илья 13.05.2009 15:04

А вот ссылка на пример битая :(

ответить

Форма комментирования для «nginx: пишем свой модуль с переменными»

Обязательное поле. Не больше 30 символов.

Обязательное поле