static ngx_int_t ngx_http_eval_handler(ngx_http_request_t *r) { size_t loc_len; ngx_str_t args; ngx_str_t subrequest_uri; ngx_uint_t flags; ngx_http_core_loc_conf_t *clcf; ngx_http_eval_loc_conf_t *ecf; ngx_http_eval_ctx_t *ctx; ngx_http_request_t *sr; ngx_int_t rc; ngx_http_post_subrequest_t *psr; ngx_http_eval_block_t *block; u_char *p; if(r != r->main && r->uri.len > 6 && r->uri.data[0] == '/' && r->uri.data[1] == 'e' && r->uri.data[2] == 'v' && r->uri.data[3] == 'a' && r->uri.data[4] == 'l' && r->uri.data[5] == '_') { clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); loc_len = r->valid_location ? clcf->name.len : 0; if(r->uri.len != loc_len) { r->uri.data += loc_len; r->uri.len -= loc_len; } else { r->uri.len = 1; } } ecf = ngx_http_get_module_loc_conf(r, ngx_http_eval_module); if(ecf->blocks == NULL || !ecf->blocks->nelts) { return NGX_DECLINED; } ctx = ngx_http_get_module_ctx(r, ngx_http_eval_module); if(ctx == NULL) { ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_eval_ctx_t)); if (ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ctx->base_conf = ecf; ctx->current_block = ecf->blocks->elts; ctx->last_block = ctx->current_block + ecf->blocks->nelts - 1; ngx_http_set_ctx(r, ctx, ngx_http_eval_module); } if(ctx->done) { ctx->in_progress = 0; if(ctx->current_block == ctx->last_block) { if(!ecf->escalate || ctx->status == NGX_OK || ctx->status == NGX_HTTP_OK) { return NGX_DECLINED; } return ctx->status; } ctx->current_block++; } if(ctx->in_progress) { #if defined nginx_version && nginx_version >= 8042 return NGX_DONE; #else return NGX_AGAIN; #endif } /* * Advance to block which has at least one variable */ while(ctx->current_block->variables == NULL || ctx->current_block->variables->nelts == 0) { if(ctx->current_block == ctx->last_block) { return NGX_DECLINED; } ctx->current_block++; } block = ctx->current_block; psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t)); if (psr == NULL) { return NGX_ERROR; } if(ngx_http_eval_init_variables(r, ctx, block) != NGX_OK) { return NGX_ERROR; } args.len = r->args.len; args.data = r->args.data; flags = 0; subrequest_uri.len = block->eval_location.len + r->uri.len; p = subrequest_uri.data = ngx_palloc(r->pool, subrequest_uri.len); if(p == NULL) { return NGX_ERROR; } p = ngx_copy(p, block->eval_location.data, block->eval_location.len); p = ngx_copy(p, r->uri.data, r->uri.len); if (ngx_http_parse_unsafe_uri(r, &subrequest_uri, &args, &flags) != NGX_OK) { return NGX_ERROR; } psr->handler = ngx_http_eval_post_subrequest_handler; psr->data = ctx; flags |= NGX_HTTP_SUBREQUEST_IN_MEMORY|NGX_HTTP_SUBREQUEST_WAITED; rc = ngx_http_subrequest(r, &subrequest_uri, &args, &sr, psr, flags); if (rc == NGX_ERROR || rc == NGX_DONE) { return rc; } /* * create a fake request body instead of discarding the real one * in order to avoid attempts to read it */ sr->request_body = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); if (sr->request_body == NULL) { return NGX_ERROR; } ctx->in_progress = 1; ctx->done = 0; /* * Wait for subrequest to complete */ #if defined nginx_version && nginx_version >= 8042 return NGX_DONE; #else return NGX_AGAIN; #endif }
static ngx_int_t ngx_http_eval_handler(ngx_http_request_t *r) { size_t loc_len; ngx_str_t args; ngx_str_t subrequest_uri; ngx_uint_t flags; ngx_http_core_loc_conf_t *clcf; ngx_http_eval_loc_conf_t *ecf; ngx_http_eval_ctx_t *ctx; ngx_http_request_t *sr; ngx_int_t rc; ngx_http_post_subrequest_t *psr; u_char *p; if(r != r->main && ngx_memn2cmp(r->uri.data, "/eval_", r->uri.len, 6 - 1) == 0) { clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); loc_len = r->valid_location ? clcf->name.len : 0; if(r->uri.len != loc_len) { r->uri.data += loc_len; r->uri.len -= loc_len; } else { r->uri.len = 1; } } ecf = ngx_http_get_module_loc_conf(r, ngx_http_eval_module); if(ecf->variables == NULL || !ecf->variables->nelts) { return NGX_DECLINED; } ctx = ngx_http_get_module_ctx(r, ngx_http_eval_module); if(ctx == NULL) { ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_eval_ctx_t)); if (ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ctx->base_conf = ecf; ngx_http_set_ctx(r, ctx, ngx_http_eval_module); } if(ctx->done) { if(!ecf->escalate || ctx->status == NGX_OK || ctx->status == NGX_HTTP_OK) { return NGX_DECLINED; } return ctx->status; } if(ctx->in_progress) { return NGX_AGAIN; } psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t)); if (psr == NULL) { return NGX_ERROR; } if(ngx_http_eval_init_variables(r, ctx, ecf) != NGX_OK) { return NGX_ERROR; } args.len = 0; args.data = NULL; flags = 0; subrequest_uri.len = ecf->eval_location.len + r->uri.len; p = subrequest_uri.data = ngx_palloc(r->pool, subrequest_uri.len); if(p == NULL) { return NGX_ERROR; } p = ngx_copy(p, ecf->eval_location.data, ecf->eval_location.len); p = ngx_copy(p, r->uri.data, r->uri.len); if (ngx_http_parse_unsafe_uri(r, &subrequest_uri, &args, &flags) != NGX_OK) { return NGX_ERROR; } psr->handler = ngx_http_eval_post_subrequest_handler; psr->data = ctx; flags |= NGX_HTTP_SUBREQUEST_IN_MEMORY|NGX_HTTP_SUBREQUEST_WAITED; rc = ngx_http_subrequest(r, &subrequest_uri, &args, &sr, psr, flags); if (rc == NGX_ERROR || rc == NGX_DONE) { return rc; } sr->discard_body = 1; ctx->in_progress = 1; /* * Wait for subrequest to complete */ return NGX_AGAIN; }
static ngx_int_t ngx_http_eval_handler(ngx_http_request_t *r) { /* size_t loc_len; */ ngx_str_t args; ngx_str_t subrequest_uri; ngx_uint_t flags; /* ngx_http_core_loc_conf_t *clcf; */ ngx_http_eval_loc_conf_t *ecf; ngx_http_eval_ctx_t *ctx; ngx_http_eval_ctx_t *sr_ctx; ngx_http_request_t *sr; ngx_int_t rc; ngx_http_post_subrequest_t *psr; u_char *p; /* if(r != r->main) { clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); loc_len = r->valid_location ? clcf->name.len : 0; if(r->uri.len != loc_len) { r->uri.data += loc_len; r->uri.len -= loc_len; } else { r->uri.len = 1; } } */ ecf = ngx_http_get_module_loc_conf(r, ngx_http_eval_module); if(ecf->variables == NULL || !ecf->variables->nelts) { return NGX_DECLINED; } ctx = ngx_http_get_module_ctx(r, ngx_http_eval_module); if(ctx == NULL) { ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_eval_ctx_t)); if (ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ctx->base_conf = ecf; ngx_http_set_ctx(r, ctx, ngx_http_eval_module); } if (ctx->done) { dd("subrequest done"); if(!ecf->escalate || ctx->status == NGX_OK || ctx->status == NGX_HTTP_OK) { return NGX_DECLINED; } dd("status: %d", (int) ctx->status); return ctx->status; } if (ctx->in_progress) { dd("still in progress"); return NGX_DONE; } psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t)); if (psr == NULL) { return NGX_ERROR; } if(ngx_http_eval_init_variables(r, ctx, ecf) != NGX_OK) { return NGX_ERROR; } args = r->args; flags = 0; subrequest_uri.len = ecf->eval_location.len + r->uri.len; p = subrequest_uri.data = ngx_palloc(r->pool, subrequest_uri.len); if(p == NULL) { return NGX_ERROR; } p = ngx_copy(p, ecf->eval_location.data, ecf->eval_location.len); p = ngx_copy(p, r->uri.data, r->uri.len); if (ngx_http_parse_unsafe_uri(r, &subrequest_uri, &args, &flags) != NGX_OK) { return NGX_ERROR; } psr->handler = ngx_http_eval_post_subrequest_handler; psr->data = ctx; flags |= NGX_HTTP_SUBREQUEST_WAITED; dd("subrequest in memory : %d", (int) ecf->subrequest_in_memory); if (ecf->subrequest_in_memory) { flags |= NGX_HTTP_SUBREQUEST_IN_MEMORY; } else { } dd("issue subrequest"); rc = ngx_http_subrequest(r, &subrequest_uri, &args, &sr, psr, flags); if (rc == NGX_ERROR || rc == NGX_DONE) { return rc; } sr->discard_body = 1; ctx->in_progress = 1; /* XXX we don't allow eval in subrequests, i think? */ sr_ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_eval_ctx_t)); if (sr_ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_http_set_ctx(sr, sr_ctx, ngx_http_eval_module); dd("wait for subrequest to complete"); return NGX_DONE; }