Skip to content

Commit 722bd6a

Browse files
spacewanderthibaultcha
authored andcommitted
bugfix: ensured Content-Type header gets generated when other headers get set.
Signed-off-by: Thibault Charbonnier <[email protected]>
1 parent 017e004 commit 722bd6a

8 files changed

+111
-19
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

+86-4
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();
@@ -1729,13 +1729,13 @@ GET /t
17291729
foo
17301730
--- response_headers
17311731
blah: foo
1732-
Content-Type:
1732+
!Content-Type
17331733
--- no_error_log
17341734
[error]
17351735
17361736
17371737
1738-
=== TEST 77: don't generate Content-Type header when getting other response headers
1738+
=== TEST 77: don't generate Content-Type header when getting other response header
17391739
--- config
17401740
location = /t {
17411741
default_type text/html;
@@ -1758,6 +1758,88 @@ GET /t
17581758
--- response_body
17591759
foo
17601760
--- response_headers
1761-
Content-Type:
1761+
!Content-Type
1762+
--- no_error_log
1763+
[error]
1764+
1765+
1766+
1767+
=== TEST 78: generate default Content-Type when getting all response headers
1768+
--- config
1769+
location = /t {
1770+
default_type text/html;
1771+
content_by_lua_block {
1772+
local headers, err = ngx.resp.get_headers()
1773+
if err then
1774+
ngx.log(ngx.ERR, "err: ", err)
1775+
return ngx.exit(500)
1776+
end
1777+
}
1778+
}
1779+
--- request
1780+
GET /t
1781+
--- response_headers
1782+
Content-Type: text/html
1783+
--- no_error_log
1784+
[error]
1785+
1786+
1787+
1788+
=== TEST 79: generate default Content-Type header when setting other response header
1789+
--- config
1790+
location = /t {
1791+
default_type text/html;
1792+
content_by_lua_block {
1793+
ngx.header.blah = "foo"
1794+
ngx.say("foo")
1795+
}
1796+
}
1797+
--- request
1798+
GET /t
1799+
--- response_body
1800+
foo
1801+
--- response_headers
1802+
blah: foo
1803+
Content-Type: text/html
1804+
--- no_error_log
1805+
[error]
1806+
1807+
1808+
1809+
=== TEST 80: don't generate default Content-Type header when Content-Type is cleared
1810+
--- config
1811+
location = /t {
1812+
default_type text/html;
1813+
content_by_lua_block {
1814+
ngx.header["Content-Type"] = nil
1815+
ngx.say("foo")
1816+
}
1817+
}
1818+
--- request
1819+
GET /t
1820+
--- response_body
1821+
foo
1822+
--- response_headers
1823+
!Content-Type
1824+
--- no_error_log
1825+
[error]
1826+
1827+
1828+
1829+
=== TEST 81: don't generate default Content-Type header when Content-Type is set
1830+
--- config
1831+
location = /t {
1832+
default_type text/html;
1833+
content_by_lua_block {
1834+
ngx.header["Content-Type"] = "application/json"
1835+
ngx.say("foo")
1836+
}
1837+
}
1838+
--- request
1839+
GET /t
1840+
--- response_body
1841+
foo
1842+
--- response_headers
1843+
Content-Type: application/json
17621844
--- no_error_log
17631845
[error]

0 commit comments

Comments
 (0)