[dev] ngx_http_get_module_loc_conf not returning the right configuration (long) ?

Igor Sysoev is at rambler-co.ru
Mon Oct 1 12:38:31 MSD 2007


On Mon, Oct 01, 2007 at 09:43:02AM +0200, Brice Figureau wrote:

> While debugging my upload progress hack module, I'm stumbling accross
> the issue that:
>   lzcf = ngx_http_get_module_loc_conf(r,
> ngx_http_uploadprogress_module);
> called in an NGX_HTTP_POST_READ_PHASE handler doesn't return the right
> "location configuration" (or at least not the one I'd like).

When nginx runs in NGX_HTTP_POST_READ_PHASE, it has server level configuration. 
Then NGX_HTTP_SERVER_REWRITE_PHASE goes, and some location configuration is
found after NGX_HTTP_FIND_CONFIG_PHASE.

So NGX_HTTP_POST_READ_PHASE is not right place to this.

> In fact most of the module initialisation is based on the limit_zone
> module code, because I needed a shared rbtree. 
> The ngx_http_get_module_loc_conf returns a configuration for which the
> pointer to the shm_zone is null.

shm_zone should be non-NULL even on this stage because it is inherited
from http.

> Here are a few code extract:
> static ngx_command_t  ngx_http_uploadprogress_commands[] = {
> 
>   { ngx_string("upload_progress"),
>     NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE2,
>     ngx_http_upload_progress,
>     0,
>     0,
>     NULL },
> 
>   { ngx_string("track_uploads"),
>     NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
>     ngx_http_track_uploads,
>     NGX_HTTP_LOC_CONF_OFFSET,
>     0,
>     NULL },
> 
>   { ngx_string("report_uploads"),
>     NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
>     ngx_http_report_uploads,
>     NGX_HTTP_LOC_CONF_OFFSET,
>     0,
>     NULL },
>     ngx_null_command
> };
> 
> static ngx_http_module_t  ngx_http_uploadprogress_module_ctx = {
>     NULL,                          /* preconfiguration */
>     ngx_http_uploadprogress_init,  /* postconfiguration */
>     NULL,  /* create main configuration */
>     NULL,    /* init main configuration */
>     NULL,                          /* create server configuration */
>     NULL,                          /* merge server configuration */
>     ngx_http_uploadprogress_create_loc_conf,          /* create location configuration */
>     ngx_http_uploadprogress_merge_loc_conf            /* merge location configuration */
> };
> 
> static ngx_int_t
> ngx_http_uploadprogress_handler(ngx_http_request_t *r)
> {
> ...
>   lzcf = ngx_http_get_module_loc_conf(r, ngx_http_uploadprogress_module);
> 
>   if (lzcf->shm_zone == NULL) {
>       /* HERE is the problem -> shm_zone is always NULL */
>       return NGX_DECLINED;
>   }
> ...
> }
> 
> static ngx_int_t
> ngx_http_uploadprogress_init(ngx_conf_t *cf)
> {
> ...
>     /* setup a NGX_HTTP_POST_READ_PHASE handler */
>     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_uploadprogress_handler;
> ...
> }
> 
> static void *
> ngx_http_uploadprogress_create_loc_conf(ngx_conf_t *cf)
> {
>     ngx_http_uploadprogress_conf_t  *conf;
> 
>     conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_uploadprogress_conf_t));
>     if (conf == NULL) {
>         return NGX_CONF_ERROR;
>     }
>     return conf;
> }
> 
> 
> static char *
> ngx_http_uploadprogress_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
> {
>   ngx_http_uploadprogress_conf_t *prev = parent;
>   ngx_http_uploadprogress_conf_t *conf = child;
> 
>   /* inherit zone declared in parent block */
>   if (conf->shm_zone == NULL) {
>       *conf = *prev;
>   }
> 
>   return NGX_CONF_OK;
> }
> 
> static char *
> ngx_http_upload_progress(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
> {
> ...
>     /* creation of the shm_zone */
>     shm_zone = ngx_shared_memory_add(cf, &value[1], n,
>                                      &ngx_http_uploadprogress_module);
> ...
> }
> 
> static char *
> ngx_http_track_uploads(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
> {
>     ngx_http_uploadprogress_conf_t  *lzcf = conf;
> ...
>     lzcf->shm_zone = ngx_shared_memory_add(cf, &value[1], 0,
> 
> &ngx_http_uploadprogress_module);
> ...
> }
> 
> static char *
> ngx_http_report_uploads(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
> {
>     ngx_http_uploadprogress_conf_t  *lzcf = conf;
> ...
>     lzcf->shm_zone = ngx_shared_memory_add(cf, &value[1], 0,
> 
> &ngx_http_uploadprogress_module);
> ...
> }
> 
> In both ngx_http_report_uploads, ngx_http_track_uploads, the shm_zone is
> properly defined (and matches the one really created in
> ngx_http_upload_progress).
> 
> The configuration file looks like:
> 
> ...
> http {
> 	...
> 	upload_progress proxied 1m;
> 	...
> 	server {
> 		listen 80;
> 		server_name localhost;
> 		...
> 		location / {
> 			proxy_pass http://127.0.0.1:8080;
> 			track_uploads proxied;
> 		}
> 		...
> 		location /progress {
> 			report_uploads proxied;
> 		}
> 	}
> }
> 
> When debugging a request that ends up in the
> ngx_http_uploadprogress_handler post read phase handler, I see several
> (more than two) location conf merger appearing, and I have exactly two
> childs with a defined shm_zone. The merge operation seems OK to me, not
> overwriting child configuration.
> 
> Any idea what could be wrong ?
> Could it be because of the proxy_pass before my own configuration
> directive?
>
> Ah, and also I couldn't get any ngx_log_debugX(NGX_LOG_DEBUG_HTTP...) to
> actually print log in the several configuration handlers, is that
> normal?

Yes. Enable

#if 0
    log->log_level = NGX_LOG_DEBUG_ALL;
#endif

in src/core/ngx_cycle.c


-- 
Igor Sysoev
http://sysoev.ru/en/





More information about the nginx mailing list