[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