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

Brice Figureau brice+nginx at daysofwonder.com
Mon Oct 1 11:43:02 MSD 2007


Hi,

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).
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.

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?

Thanks,
-- 
Brice Figureau <brice+nginx at daysofwonder.com>






More information about the nginx mailing list