Installing handlers in NGX_HTTP_LOG_PHASE
Maxim Dounin
mdounin at mdounin.ru
Wed Dec 23 13:07:56 MSK 2009
Hello!
On Wed, Dec 23, 2009 at 10:48:06AM +0100, Srebrenko Šehić wrote:
> 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.
This is somewhat expected as phases array are initialized after
reading configuration (see ngx_http.c for details). The only
alternative is SIGBUS, not sure it's better. :)
> What is the correct approach to conditionally install a handler?
In postconfiguration handler. Nothing stops you from doing it
conditionally.
Maxim Dounin
More information about the nginx-devel
mailing list