Skip to content

Commit d2e9259

Browse files
spacewanderthibaultcha
authored andcommitted
bugfix: ensured Content-Type header gets generated when other headers get set.
Fixed a regression introduced in 017e004 and previously described in openresty#92. Signed-off-by: Thibault Charbonnier <[email protected]>
1 parent 017e004 commit d2e9259

8 files changed

+98
-27
lines changed

src/ngx_http_lua_common.h

+2
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,8 @@ typedef struct ngx_http_lua_ctx_s {
566566

567567
unsigned headers_set:1; /* whether the user has set custom
568568
response headers */
569+
unsigned mime_set:1; /* whether the user has set Content-Type
570+
response header */
569571

570572
unsigned entered_rewrite_phase:1;
571573
unsigned entered_access_phase:1;

src/ngx_http_lua_headers.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ ngx_http_lua_ngx_resp_get_headers(lua_State *L)
563563
}
564564

565565
if (!r->headers_out.content_type.len) {
566-
rc = ngx_http_lua_set_content_type(r);
566+
rc = ngx_http_lua_set_content_type(r, ctx);
567567
if (rc != NGX_OK) {
568568
return luaL_error(L,
569569
"failed to set default content type: %d",
@@ -826,7 +826,7 @@ ngx_http_lua_ngx_header_set(lua_State *L)
826826
ngx_memcpy(value.data, p, len);
827827
value.len = len;
828828

829-
rc = ngx_http_lua_set_output_header(r, key, value,
829+
rc = ngx_http_lua_set_output_header(r, ctx, key, value,
830830
i == 1 /* override */);
831831

832832
if (rc == NGX_ERROR) {
@@ -853,7 +853,7 @@ ngx_http_lua_ngx_header_set(lua_State *L)
853853
dd("key: %.*s, value: %.*s",
854854
(int) key.len, key.data, (int) value.len, value.data);
855855

856-
rc = ngx_http_lua_set_output_header(r, key, value, 1 /* override */);
856+
rc = ngx_http_lua_set_output_header(r, ctx, key, value, 1 /* override */);
857857

858858
if (rc == NGX_ERROR) {
859859
return luaL_error(L, "failed to set header %s (error: %d)",
@@ -1250,7 +1250,7 @@ ngx_http_lua_ffi_set_resp_header(ngx_http_request_t *r, const u_char *key_data,
12501250
ngx_memcpy(value.data, p, len);
12511251
value.len = len;
12521252

1253-
rc = ngx_http_lua_set_output_header(r, key, value,
1253+
rc = ngx_http_lua_set_output_header(r, ctx, key, value,
12541254
override && i == 0);
12551255

12561256
if (rc == NGX_ERROR) {
@@ -1276,7 +1276,7 @@ ngx_http_lua_ffi_set_resp_header(ngx_http_request_t *r, const u_char *key_data,
12761276
dd("key: %.*s, value: %.*s",
12771277
(int) key.len, key.data, (int) value.len, value.data);
12781278

1279-
rc = ngx_http_lua_set_output_header(r, key, value, override);
1279+
rc = ngx_http_lua_set_output_header(r, ctx, key, value, override);
12801280

12811281
if (rc == NGX_ERROR) {
12821282
*errmsg = "failed to set header";
@@ -1407,7 +1407,7 @@ ngx_http_lua_ffi_get_resp_header(ngx_http_request_t *r,
14071407
case 12:
14081408
if (ngx_strncasecmp(key_buf, (u_char *) "Content-Type", 12) == 0) {
14091409
if (!r->headers_out.content_type.len) {
1410-
if (ngx_http_lua_set_content_type(r) != NGX_OK) {
1410+
if (ngx_http_lua_set_content_type(r, ctx) != NGX_OK) {
14111411
*errmsg = "failed to set default content type";
14121412
return NGX_ERROR;
14131413
}

src/ngx_http_lua_headers_out.c

+8-4
Original file line numberDiff line numberDiff line change
@@ -476,8 +476,8 @@ ngx_http_clear_builtin_header(ngx_http_request_t *r,
476476

477477

478478
ngx_int_t
479-
ngx_http_lua_set_output_header(ngx_http_request_t *r, ngx_str_t key,
480-
ngx_str_t value, unsigned override)
479+
ngx_http_lua_set_output_header(ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx,
480+
ngx_str_t key, ngx_str_t value, unsigned override)
481481
{
482482
ngx_http_lua_header_val_t hv;
483483
ngx_http_lua_set_header_t *handlers = ngx_http_lua_set_handlers;
@@ -508,6 +508,10 @@ ngx_http_lua_set_output_header(ngx_http_request_t *r, ngx_str_t key,
508508
hv.offset = handlers[i].offset;
509509
hv.handler = handlers[i].handler;
510510

511+
if (hv.handler == ngx_http_set_content_type_header) {
512+
ctx->mime_set = 1;
513+
}
514+
511515
break;
512516
}
513517

@@ -552,8 +556,8 @@ ngx_http_lua_get_output_header(lua_State *L, ngx_http_request_t *r,
552556

553557
case 12:
554558
if (ngx_strncasecmp(key->data, (u_char *) "Content-Type", 12) == 0) {
555-
if (!r->headers_out.content_type.len) {
556-
rc = ngx_http_lua_set_content_type(r);
559+
if (r->headers_out.content_type.len == 0) {
560+
rc = ngx_http_lua_set_content_type(r, ctx);
557561
if (rc != NGX_OK) {
558562
return luaL_error(L,
559563
"failed to set default content type: %d",

src/ngx_http_lua_headers_out.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
#include "ngx_http_lua_common.h"
1313

1414

15-
ngx_int_t ngx_http_lua_set_output_header(ngx_http_request_t *r, ngx_str_t key,
16-
ngx_str_t value, unsigned override);
15+
ngx_int_t ngx_http_lua_set_output_header(ngx_http_request_t *r,
16+
ngx_http_lua_ctx_t *ctx, ngx_str_t key, ngx_str_t value, unsigned override);
1717
int ngx_http_lua_get_output_header(lua_State *L, ngx_http_request_t *r,
1818
ngx_http_lua_ctx_t *ctx, ngx_str_t *key);
1919

src/ngx_http_lua_subrequest.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1032,7 +1032,7 @@ ngx_http_lua_post_subrequest(ngx_http_request_t *r, void *data, ngx_int_t rc)
10321032

10331033
/* copy subrequest response headers */
10341034
if (ctx->headers_set) {
1035-
rc = ngx_http_lua_set_content_type(r);
1035+
rc = ngx_http_lua_set_content_type(r, ctx);
10361036
if (rc != NGX_OK) {
10371037
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
10381038
"failed to set default content type: %i", rc);

src/ngx_http_lua_util.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,9 @@ ngx_http_lua_send_header_if_needed(ngx_http_request_t *r,
433433
r->headers_out.status = NGX_HTTP_OK;
434434
}
435435

436-
if (!ctx->headers_set && ngx_http_lua_set_content_type(r) != NGX_OK) {
436+
if (!ctx->mime_set
437+
&& ngx_http_lua_set_content_type(r, ctx) != NGX_OK)
438+
{
437439
return NGX_ERROR;
438440
}
439441

src/ngx_http_lua_util.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -411,10 +411,12 @@ ngx_http_lua_hash_str(u_char *src, size_t n)
411411

412412

413413
static ngx_inline ngx_int_t
414-
ngx_http_lua_set_content_type(ngx_http_request_t *r)
414+
ngx_http_lua_set_content_type(ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx)
415415
{
416416
ngx_http_lua_loc_conf_t *llcf;
417417

418+
ctx->mime_set = 1;
419+
418420
llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);
419421
if (llcf->use_default_type
420422
&& r->headers_out.status != NGX_HTTP_NOT_MODIFIED)

t/016-resp-header.t

+73-12
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use Test::Nginx::Socket::Lua;
88

99
repeat_each(2);
1010

11-
plan tests => repeat_each() * (blocks() * 3 + 51);
11+
plan tests => repeat_each() * (blocks() * 3 + 55);
1212

1313
#no_diff();
1414
no_long_string();
@@ -1705,16 +1705,38 @@ lua exceeding response header limit
17051705
17061706
17071707
1708-
=== TEST 76: don't generate Content-Type header when setting other response headers
1708+
=== TEST 76: don't generate Content-Type when setting other response header
17091709
--- config
1710+
location = /backend {
1711+
content_by_lua_block {
1712+
ngx.say("foo")
1713+
}
1714+
header_filter_by_lua_block {
1715+
ngx.header.content_type = nil
1716+
}
1717+
}
1718+
17101719
location = /t {
17111720
default_type text/html;
17121721
rewrite_by_lua_block {
17131722
ngx.header.blah = "foo"
17141723
}
17151724
proxy_pass http://127.0.0.1:$TEST_NGINX_SERVER_PORT/backend;
17161725
}
1726+
--- request
1727+
GET /t
1728+
--- response_body
1729+
foo
1730+
--- response_headers
1731+
blah: foo
1732+
!Content-Type
1733+
--- no_error_log
1734+
[error]
17171735
1736+
1737+
1738+
=== TEST 77: don't generate Content-Type when getting other response header
1739+
--- config
17181740
location = /backend {
17191741
content_by_lua_block {
17201742
ngx.say("foo")
@@ -1723,41 +1745,80 @@ lua exceeding response header limit
17231745
ngx.header.content_type = nil
17241746
}
17251747
}
1748+
1749+
location = /t {
1750+
default_type text/html;
1751+
rewrite_by_lua_block {
1752+
local h = ngx.header.content_length
1753+
}
1754+
proxy_pass http://127.0.0.1:$TEST_NGINX_SERVER_PORT/backend;
1755+
}
17261756
--- request
17271757
GET /t
17281758
--- response_body
17291759
foo
17301760
--- response_headers
1731-
blah: foo
1732-
Content-Type:
1761+
!Content-Type
17331762
--- no_error_log
17341763
[error]
17351764
17361765
17371766
1738-
=== TEST 77: don't generate Content-Type header when getting other response headers
1767+
=== TEST 78: generate default Content-Type when setting other response header
17391768
--- config
17401769
location = /t {
17411770
default_type text/html;
1742-
rewrite_by_lua_block {
1743-
local h = ngx.header.content_length
1771+
content_by_lua_block {
1772+
ngx.header.blah = "foo"
1773+
ngx.say("foo")
17441774
}
1745-
proxy_pass http://127.0.0.1:$TEST_NGINX_SERVER_PORT/backend;
17461775
}
1776+
--- request
1777+
GET /t
1778+
--- response_body
1779+
foo
1780+
--- response_headers
1781+
blah: foo
1782+
Content-Type: text/html
1783+
--- no_error_log
1784+
[error]
17471785
1748-
location = /backend {
1786+
1787+
1788+
=== TEST 79: don't generate default Content-Type when Content-Type is cleared
1789+
--- config
1790+
location = /t {
1791+
default_type text/html;
17491792
content_by_lua_block {
1793+
ngx.header["Content-Type"] = nil
17501794
ngx.say("foo")
17511795
}
1752-
header_filter_by_lua_block {
1753-
ngx.header.content_type = nil
1796+
}
1797+
--- request
1798+
GET /t
1799+
--- response_body
1800+
foo
1801+
--- response_headers
1802+
!Content-Type
1803+
--- no_error_log
1804+
[error]
1805+
1806+
1807+
1808+
=== TEST 80: don't generate default Content-Type when Content-Type is set
1809+
--- config
1810+
location = /t {
1811+
default_type text/html;
1812+
content_by_lua_block {
1813+
ngx.header["Content-Type"] = "application/json"
1814+
ngx.say("foo")
17541815
}
17551816
}
17561817
--- request
17571818
GET /t
17581819
--- response_body
17591820
foo
17601821
--- response_headers
1761-
Content-Type:
1822+
Content-Type: application/json
17621823
--- no_error_log
17631824
[error]

0 commit comments

Comments
 (0)