Installing handlers in NGX_HTTP_LOG_PHASE

Srebrenko Šehić ssehic at gmail.com
Wed Dec 23 12:48:06 MSK 2009


Hi list,

I'm looking into expanding nginx' Perl hooks to support installing
handlers for all NGX_HTTP phases. Ultimate goal is to have nginx' Perl
hooks do all those fancy things Apache's mod_perl can. Like rewriting
URI, filtering/changing proxied response bodies, etc. As starters, I
want to implement a handler which will run some Perl code in
NGX_HTTP_LOG_PHASE. I do, however, have some questions that I hope
someone can shed some light onto:

If I register a postconfiguration hook, I'm able to install a handler
at LOG_PHASE phase:

static ngx_http_module_t  ngx_http_perl_module_ctx = {
    ....
    ngx_http_perl_log_init,                /* postconfiguration */
    ....
};

static ngx_int_t
ngx_http_perl_log_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_LOG_PHASE].handlers);
    if (h == NULL) {
        return NGX_ERROR;
    }

    *h = ngx_http_perl_log_handler;

    return NGX_OK;
}

Above works just fine.

However, what I want to achieve is to install the handler
conditionally. So when you in your nginx.conf say:

location /
    perl_log_handler MyModule::log_handler

I tried the following approach and failed:

static ngx_command_t  ngx_http_perl_commands[] = {
    ....
    { ngx_string("perl_log_handler"),
      NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1,
      ngx_http_perl_handler_init,
      NGX_HTTP_LOC_CONF_OFFSET,
      0,
      NULL },
    ....
};

static char *
ngx_http_perl_handler_init(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    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_LOG_PHASE].handlers);
    if (h == NULL) {
        return NGX_CONF_ERROR;
    }

    *h = ngx_http_perl_log_handler;

    return NGX_CONF_OK;
}

nginx dies with SIGSEGV upon startup.

What is the correct approach to conditionally install a handler?

Thanks,
Srebrenko



More information about the nginx-devel mailing list