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 {