Created
April 24, 2013 01:35
-
-
Save agentzh/5448934 to your computer and use it in GitHub Desktop.
bugfix: modifying the Connection request header via ngx.req.set_header or ngx.req.clear_header did not update the special internal flags in the Nginx core, "r->headers_in.connection_type" and "r->headers_in.keep_alive_n". Thanks Matthieu Tourne for the patch.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/ngx_http_lua_headers_in.c b/src/ngx_http_lua_headers_in.c | |
index f4413b6..bd4af76 100644 | |
--- a/src/ngx_http_lua_headers_in.c | |
+++ b/src/ngx_http_lua_headers_in.c | |
@@ -25,6 +25,8 @@ static ngx_int_t ngx_http_set_builtin_header(ngx_http_request_t *r, | |
ngx_http_lua_header_val_t *hv, ngx_str_t *value); | |
static ngx_int_t ngx_http_set_user_agent_header(ngx_http_request_t *r, | |
ngx_http_lua_header_val_t *hv, ngx_str_t *value); | |
+static ngx_int_t ngx_http_set_connection_header(ngx_http_request_t *r, | |
+ ngx_http_lua_header_val_t *hv, ngx_str_t *value); | |
static ngx_int_t ngx_http_set_content_length_header(ngx_http_request_t *r, | |
ngx_http_lua_header_val_t *hv, ngx_str_t *value); | |
static ngx_int_t ngx_http_clear_builtin_header(ngx_http_request_t *r, | |
@@ -51,7 +53,7 @@ static ngx_http_lua_set_header_t ngx_http_lua_set_handlers[] = { | |
{ ngx_string("Connection"), | |
offsetof(ngx_http_headers_in_t, connection), | |
- ngx_http_set_builtin_header }, | |
+ ngx_http_set_connection_header }, | |
{ ngx_string("If-Modified-Since"), | |
offsetof(ngx_http_headers_in_t, if_modified_since), | |
@@ -268,6 +270,28 @@ ngx_http_set_host_header(ngx_http_request_t *r, ngx_http_lua_header_val_t *hv, | |
} | |
+static ngx_int_t | |
+ngx_http_set_connection_header(ngx_http_request_t *r, | |
+ ngx_http_lua_header_val_t *hv, ngx_str_t *value) | |
+{ | |
+ r->headers_in.connection_type = 0; | |
+ | |
+ if (value->len == 0) { | |
+ return ngx_http_set_builtin_header(r, hv, value); | |
+ } | |
+ | |
+ if (ngx_strcasestrn(value->data, "close", 5 - 1)) { | |
+ r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE; | |
+ r->headers_in.keep_alive_n = -1; | |
+ | |
+ } else if (ngx_strcasestrn(value->data, "keep-alive", 10 - 1)) { | |
+ r->headers_in.connection_type = NGX_HTTP_CONNECTION_KEEP_ALIVE; | |
+ } | |
+ | |
+ return ngx_http_set_builtin_header(r, hv, value); | |
+} | |
+ | |
+ | |
/* borrowed the code from ngx_http_request.c:ngx_http_process_user_agent */ | |
static ngx_int_t | |
ngx_http_set_user_agent_header(ngx_http_request_t *r, | |
diff --git a/t/112-req-header-conn.t b/t/112-req-header-conn.t | |
new file mode 100644 | |
index 0000000..37f1a2e | |
--- /dev/null | |
+++ b/t/112-req-header-conn.t | |
@@ -0,0 +1,150 @@ | |
+# vim:set ft= ts=4 sw=4 et fdm=marker: | |
+ | |
+use lib 'lib'; | |
+use Test::Nginx::Socket; | |
+ | |
+#worker_connections(1014); | |
+#master_process_enabled(1); | |
+#log_level('warn'); | |
+ | |
+repeat_each(2); | |
+ | |
+plan tests => repeat_each() * (4 * blocks()); | |
+ | |
+#no_diff(); | |
+no_long_string(); | |
+ | |
+run_tests(); | |
+ | |
+__DATA__ | |
+ | |
+=== TEST 1: clear the Connection req header | |
+--- config | |
+ location /req-header { | |
+ rewrite_by_lua ' | |
+ ngx.req.set_header("Connection", nil); | |
+ '; | |
+ | |
+ echo "connection: $http_connection"; | |
+ } | |
+--- request | |
+GET /req-header | |
+ | |
+--- stap | |
+F(ngx_http_lua_rewrite_by_chunk) { | |
+ printf("rewrite: conn type: %d\n", $r->headers_in->connection_type) | |
+} | |
+ | |
+ | |
+F(ngx_http_core_content_phase) { | |
+ printf("content: conn type: %d\n", $r->headers_in->connection_type) | |
+} | |
+ | |
+--- stap_out | |
+rewrite: conn type: 1 | |
+content: conn type: 0 | |
+ | |
+--- response_body | |
+connection: | |
+--- no_error_log | |
+[error] | |
+ | |
+ | |
+ | |
+=== TEST 2: set custom Connection req header (close) | |
+--- config | |
+ location /req-header { | |
+ rewrite_by_lua ' | |
+ ngx.req.set_header("Connection", "CLOSE"); | |
+ '; | |
+ | |
+ echo "connection: $http_connection"; | |
+ } | |
+--- request | |
+GET /req-header | |
+ | |
+--- stap | |
+F(ngx_http_lua_rewrite_by_chunk) { | |
+ printf("rewrite: conn type: %d\n", $r->headers_in->connection_type) | |
+} | |
+ | |
+ | |
+F(ngx_http_core_content_phase) { | |
+ printf("content: conn type: %d\n", $r->headers_in->connection_type) | |
+} | |
+ | |
+--- stap_out | |
+rewrite: conn type: 1 | |
+content: conn type: 1 | |
+ | |
+--- response_body | |
+connection: CLOSE | |
+--- no_error_log | |
+[error] | |
+ | |
+ | |
+ | |
+=== TEST 3: set custom Connection req header (keep-alive) | |
+--- config | |
+ location /req-header { | |
+ rewrite_by_lua ' | |
+ ngx.req.set_header("Connection", "keep-alive"); | |
+ '; | |
+ | |
+ echo "connection: $http_connection"; | |
+ } | |
+--- request | |
+GET /req-header | |
+ | |
+--- stap | |
+F(ngx_http_lua_rewrite_by_chunk) { | |
+ printf("rewrite: conn type: %d\n", $r->headers_in->connection_type) | |
+} | |
+ | |
+ | |
+F(ngx_http_core_content_phase) { | |
+ printf("content: conn type: %d\n", $r->headers_in->connection_type) | |
+} | |
+ | |
+--- stap_out | |
+rewrite: conn type: 1 | |
+content: conn type: 2 | |
+ | |
+--- response_body | |
+connection: keep-alive | |
+--- no_error_log | |
+[error] | |
+ | |
+ | |
+ | |
+=== TEST 4: set custom Connection req header (bad) | |
+--- config | |
+ location /req-header { | |
+ rewrite_by_lua ' | |
+ ngx.req.set_header("Connection", "bad"); | |
+ '; | |
+ | |
+ echo "connection: $http_connection"; | |
+ } | |
+--- request | |
+GET /req-header | |
+ | |
+--- stap | |
+F(ngx_http_lua_rewrite_by_chunk) { | |
+ printf("rewrite: conn type: %d\n", $r->headers_in->connection_type) | |
+} | |
+ | |
+ | |
+F(ngx_http_core_content_phase) { | |
+ printf("content: conn type: %d\n", $r->headers_in->connection_type) | |
+} | |
+ | |
+--- stap_out | |
+rewrite: conn type: 1 | |
+content: conn type: 0 | |
+ | |
+--- response_body | |
+connection: bad | |
+--- no_error_log | |
+[error] | |
+ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment