Mercurial > hg > nginx
comparison src/http/modules/ngx_http_ssi_filter_module.c @ 8102:49e7db44b57c
SSI: handling of subrequests from other modules (ticket #1263).
As the SSI parser always uses the context from the main request for storing
variables and blocks, that context should always exist for subrequests using
SSI, even though the main request does not necessarily have SSI enabled.
However, `ngx_http_get_module_ctx(r->main, ...)` is getting NULL in such cases,
resulting in the worker crashing SIGSEGV when accessing its attributes.
This patch links the first initialized context to the main request, and
upgrades it only when main context is initialized.
author | Ciel Zhao <i@ciel.dev> |
---|---|
date | Mon, 21 Nov 2022 17:01:34 +0300 |
parents | d75153522557 |
children |
comparison
equal
deleted
inserted
replaced
8101:42bc158a47ec | 8102:49e7db44b57c |
---|---|
327 | 327 |
328 | 328 |
329 static ngx_int_t | 329 static ngx_int_t |
330 ngx_http_ssi_header_filter(ngx_http_request_t *r) | 330 ngx_http_ssi_header_filter(ngx_http_request_t *r) |
331 { | 331 { |
332 ngx_http_ssi_ctx_t *ctx; | 332 ngx_http_ssi_ctx_t *ctx, *mctx; |
333 ngx_http_ssi_loc_conf_t *slcf; | 333 ngx_http_ssi_loc_conf_t *slcf; |
334 | 334 |
335 slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module); | 335 slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module); |
336 | 336 |
337 if (!slcf->enable | 337 if (!slcf->enable |
339 || ngx_http_test_content_type(r, &slcf->types) == NULL) | 339 || ngx_http_test_content_type(r, &slcf->types) == NULL) |
340 { | 340 { |
341 return ngx_http_next_header_filter(r); | 341 return ngx_http_next_header_filter(r); |
342 } | 342 } |
343 | 343 |
344 mctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module); | |
345 | |
344 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_ssi_ctx_t)); | 346 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_ssi_ctx_t)); |
345 if (ctx == NULL) { | 347 if (ctx == NULL) { |
346 return NGX_ERROR; | 348 return NGX_ERROR; |
347 } | 349 } |
348 | 350 |
365 "[an error occurred while processing the directive]"); | 367 "[an error occurred while processing the directive]"); |
366 | 368 |
367 r->filter_need_in_memory = 1; | 369 r->filter_need_in_memory = 1; |
368 | 370 |
369 if (r == r->main) { | 371 if (r == r->main) { |
372 | |
373 if (mctx) { | |
374 | |
375 /* | |
376 * if there was a shared context previously used as main, | |
377 * copy variables and blocks | |
378 */ | |
379 | |
380 ctx->variables = mctx->variables; | |
381 ctx->blocks = mctx->blocks; | |
382 | |
383 #if (NGX_PCRE) | |
384 ctx->ncaptures = mctx->ncaptures; | |
385 ctx->captures = mctx->captures; | |
386 ctx->captures_data = mctx->captures_data; | |
387 #endif | |
388 | |
389 mctx->shared = 0; | |
390 } | |
391 | |
370 ngx_http_clear_content_length(r); | 392 ngx_http_clear_content_length(r); |
371 ngx_http_clear_accept_ranges(r); | 393 ngx_http_clear_accept_ranges(r); |
372 | 394 |
373 r->preserve_body = 1; | 395 r->preserve_body = 1; |
374 | 396 |
377 ngx_http_clear_etag(r); | 399 ngx_http_clear_etag(r); |
378 | 400 |
379 } else { | 401 } else { |
380 ngx_http_weak_etag(r); | 402 ngx_http_weak_etag(r); |
381 } | 403 } |
404 | |
405 } else if (mctx == NULL) { | |
406 ngx_http_set_ctx(r->main, ctx, ngx_http_ssi_filter_module); | |
407 ctx->shared = 1; | |
382 } | 408 } |
383 | 409 |
384 return ngx_http_next_header_filter(r); | 410 return ngx_http_next_header_filter(r); |
385 } | 411 } |
386 | 412 |
403 ngx_str_t *params[NGX_HTTP_SSI_MAX_PARAMS + 1]; | 429 ngx_str_t *params[NGX_HTTP_SSI_MAX_PARAMS + 1]; |
404 | 430 |
405 ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module); | 431 ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module); |
406 | 432 |
407 if (ctx == NULL | 433 if (ctx == NULL |
434 || (ctx->shared && r == r->main) | |
408 || (in == NULL | 435 || (in == NULL |
409 && ctx->buf == NULL | 436 && ctx->buf == NULL |
410 && ctx->in == NULL | 437 && ctx->in == NULL |
411 && ctx->busy == NULL)) | 438 && ctx->busy == NULL)) |
412 { | 439 { |