ПРОЕКТЫ 


  АРХИВ 


Apache-Talk @lexa.ru 

Inet-Admins @info.east.ru 

Filmscanners @halftone.co.uk 

Security-alerts @yandex-team.ru 

nginx-ru @sysoev.ru 


  СТАТЬИ 


  ПЕРСОНАЛЬНОЕ 


  ПРОГРАММЫ 



ПИШИТЕ
ПИСЬМА












     АРХИВ :: nginx-ru
Nginx-ru mailing list archive (nginx-ru@sysoev.ru)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

В хендлере модуля используе тся location-конфигурация уровня сер вера


  • To: nginx-ru@xxxxxxxxx
  • Subject: В хендлере модуля используе тся location-конфигурация уровня сер вера
  • From: Alrond <rusnginx@xxxxxxxxx>
  • Date: Wed, 28 Oct 2009 01:04:22 +0100
  • Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:date:message-id:subject :from:to:content-type; bh=uC6gp5XM5VSXxWYoKr9q0gffPcaqsUsrDrp/7caNQPs=; b=L3Qsfsbl5bv5fyi0/hOXmK0jMB2SkKMDB17lkhyLlOgXTzhrINqYMR8ewIkEWPAoLL uwR08Mk+V/voIaLUaVEPm9v7mbUgv7p6FF3j7sevKz4OeZCNJ0ab6E1SM7VEhqw51b6Y 4FB1tuoZ1qfDtzK0aJguhyPI/ApyKJYR34oBo=
  • Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; b=aoW8lspC2yITQbC4PnYDfLD2oURruBDY/MTHE7PLPY5qcLoaCpdDkLJTb94fCGo8IK ZjGItaUgsz4C5JUY1CCnwkM0NtCfT1CntUZRejMKxe1S+ZwjzzbaWLe0F31YZFxCvUkT PbFQ5HGa7VUHi5SEHZw+EvMh8vEC1lSQaWRbY=

Немного замысловато звучит :) Какое-то странное поведение хендлера обнаружил.

Небольшое введение: модуль - каркас с двумя переменными "blabla" и "blabla_disable". Действия модуля распростроняется на все сервера, кроме тех locations, где будет "blabla_disable on"
Поэтому используется конфигурация уровня location и
server. Такого я правда пока ни в одном модуле не встречал.

static ngx_http_module_t  ngx_http_blabla_module_ctx = {
    NULL,                             /* preconfiguration */
    ngx_http_blabla_init,             /* postconfiguration */

    NULL,                             /* create main configuration */
    NULL,                             /* init main configuration */

    ngx_http_blabla_create_srv_conf,  /* create server configuration */
    ngx_http_blabla_merge_srv_conf,   /* merge server configuration */

    ngx_http_blabla_create_loc_conf,  /* create location configration */
    ngx_http_blabla_merge_loc_conf    /* merge location configration */
};


В ините добавляется ngx_http_blabla_handler. Пока всё стандартно.
Самое интересное поведение - в хендлере:

static ngx_int_t
ngx_http_blabla_handler(ngx_http_request_t *r)
{
    ngx_http_blabla_srv_conf_t *conf;
    ngx_http_blabla_loc_conf_t *confl;

    conf = ngx_http_get_module_srv_conf(r, ngx_http_blabla_module);
    confl = ngx_http_get_module_loc_conf(r, ngx_http_blabla_module);

    if (confl->disable) {
        return NGX_DECLINED;
    }

    /*  Future logic */
    return NGX_DECLINED;
}

Задумано так, что берется конфигурация переменных уровня сервера и уровня локейшена для запроса.
Проверяется что в этом локейшене "blabla_disable on" и ничего не делается. Во всех остальных случаях идет дальше на обработку.
Но в реальности "blabla_disable" проверяется того же уровня, где расположена переменная "blabla".
Как пример, запрос идет на /tamtam И модуль должен пропустить этот запрос. (в реальности это редкий случай, поэтому по умолчанию везде "
blabla_disable off")

server {
    blabla "test";
    //blabla_disable off;

    location /tamtam {
        blabla_disable on;
    }
}

Почему "ngx_http_get_module_loc_conf" берет данные не для запрашиваемого локейшена, а от того места, где идет инициализация хендлера и переменной "blabla"?
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>

typedef struct {
    ngx_str_t       blabla;
} ngx_http_blabla_srv_conf_t;

typedef struct {
    ngx_flag_t       disable;
} ngx_http_blabla_loc_conf_t;

static ngx_int_t ngx_http_blabla_init(ngx_conf_t *cf);

static void *ngx_http_blabla_create_srv_conf(ngx_conf_t *cf);
static char *ngx_http_blabla_merge_srv_conf(ngx_conf_t *cf,
    void *parent, void *child);

static void *ngx_http_blabla_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_blabla_merge_loc_conf(ngx_conf_t *cf,
    void *parent, void *child);

static ngx_int_t ngx_http_blabla_handler(ngx_http_request_t *r);

static ngx_command_t  ngx_http_blabla_commands[] = {

    { ngx_string("blabla_disable"),
      NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
      ngx_conf_set_flag_slot,
      NGX_HTTP_LOC_CONF_OFFSET,
      offsetof(ngx_http_blabla_loc_conf_t, disable),
      NULL },

    { ngx_string("blabla"),
      NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
      ngx_conf_set_str_slot,
      NGX_HTTP_SRV_CONF_OFFSET,
      offsetof(ngx_http_blabla_srv_conf_t, blabla),
      NULL },

      ngx_null_command
};


static ngx_http_module_t  ngx_http_blabla_module_ctx = {
    NULL,                             /* preconfiguration */
    ngx_http_blabla_init,             /* postconfiguration */

    NULL,                             /* create main configuration */
    NULL,                             /* init main configuration */

    ngx_http_blabla_create_srv_conf,  /* create server configuration */
    ngx_http_blabla_merge_srv_conf,   /* merge server configuration */

    ngx_http_blabla_create_loc_conf,  /* create location configration */
    ngx_http_blabla_merge_loc_conf    /* merge location configration */
};


ngx_module_t  ngx_http_blabla_module = {
    NGX_MODULE_V1,
    &ngx_http_blabla_module_ctx,      /* module context */
    ngx_http_blabla_commands,         /* module directives */
    NGX_HTTP_MODULE,                  /* module type */
    NULL,                             /* init master */
    NULL,                             /* init module */
    NULL,                             /* init process */
    NULL,                             /* init thread */
    NULL,                             /* exit thread */
    NULL,                             /* exit process */
    NULL,                             /* exit master */
    NGX_MODULE_V1_PADDING
};


static ngx_int_t
ngx_http_blabla_handler(ngx_http_request_t *r)
{
    ngx_http_blabla_srv_conf_t *conf;
    ngx_http_blabla_loc_conf_t *confl;

    conf = ngx_http_get_module_srv_conf(r, ngx_http_blabla_module);
    confl = ngx_http_get_module_loc_conf(r, ngx_http_blabla_module);

    if (confl->disable) {
        return NGX_DECLINED;
    }

    /*  Future logic */

    return NGX_DECLINED;
}

static ngx_int_t ngx_http_blabla_init(ngx_conf_t *cf)
{
    ngx_http_handler_pt        *h;
    ngx_http_core_main_conf_t  *cmcf;

    cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);

    h = ngx_array_push(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers);
    if (h == NULL) {
        return NGX_ERROR;
    }

    *h = ngx_http_blabla_handler;

    return NGX_OK;
}


static void *ngx_http_blabla_create_srv_conf(ngx_conf_t *cf)
{
    ngx_http_blabla_srv_conf_t *conf;

    conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_blabla_srv_conf_t));
    if (conf == NULL) {
        return NGX_CONF_ERROR;
    }

    return conf;
}


static char *ngx_http_blabla_merge_srv_conf(ngx_conf_t *cf,
    void *parent, void *child)
{
    ngx_http_blabla_srv_conf_t *prev = parent;
    ngx_http_blabla_srv_conf_t *conf = child;

    ngx_conf_merge_value(conf->blabla, prev->blabla, "test");

    return NGX_CONF_OK;
}

static void *ngx_http_blabla_create_loc_conf(ngx_conf_t *cf)
{
    ngx_http_blabla_loc_conf_t *conf;

    conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_blabla_loc_conf_t));
    if (conf == NULL) {
        return NGX_CONF_ERROR;
    }

    conf->disable = NGX_CONF_UNSET;

    return conf;
}

static char *ngx_http_blabla_merge_loc_conf(ngx_conf_t *cf,
    void *parent, void *child)
{
    ngx_http_blabla_loc_conf_t *prev = parent;
    ngx_http_blabla_loc_conf_t *conf = child;

    ngx_conf_merge_value(conf->disable, prev->disable, 0);

    return NGX_CONF_OK;
}


 




Copyright © Lexa Software, 1996-2009.