Instantly share code, notes, and snippets.
Created
April 24, 2013 19:48
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save agentzh/5455007 to your computer and use it in GitHub Desktop.
bugfix: modifying the Cookie request headers via ngx.req.set_header or ngx.req.clear_header did not update the Nginx internal data structure, r->headers_in.cookies, at the same time, which might cause issues when reading variables $cookie_COOKIE, for example. 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 9987e54..8391de0 100644 | |
--- a/src/ngx_http_lua_headers_in.c | |
+++ b/src/ngx_http_lua_headers_in.c | |
@@ -29,6 +29,8 @@ 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_set_cookie_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, | |
ngx_http_lua_header_val_t *hv, ngx_str_t *value); | |
static ngx_int_t ngx_http_clear_content_length_header(ngx_http_request_t *r, | |
@@ -103,6 +105,10 @@ static ngx_http_lua_set_header_t ngx_http_lua_set_handlers[] = { | |
offsetof(ngx_http_headers_in_t, content_length), | |
ngx_http_set_content_length_header }, | |
+ { ngx_string("Cookie"), | |
+ 0, | |
+ ngx_http_set_cookie_header }, | |
+ | |
#if (NGX_HTTP_REALIP) | |
{ ngx_string("X-Real-IP"), | |
offsetof(ngx_http_headers_in_t, x_real_ip), | |
@@ -401,6 +407,45 @@ ngx_http_set_content_length_header(ngx_http_request_t *r, | |
static ngx_int_t | |
+ngx_http_set_cookie_header(ngx_http_request_t *r, | |
+ ngx_http_lua_header_val_t *hv, ngx_str_t *value) | |
+{ | |
+ ngx_table_elt_t **cookie, *h; | |
+ | |
+ if (!hv->no_override && r->headers_in.cookies.nelts > 0) { | |
+ ngx_array_destroy(&r->headers_in.cookies); | |
+ | |
+ if (ngx_array_init(&r->headers_in.cookies, r->pool, 2, | |
+ sizeof(ngx_table_elt_t *)) | |
+ != NGX_OK) | |
+ { | |
+ return NGX_ERROR; | |
+ } | |
+ | |
+ dd("clear headers in cookies: %d", (int) r->headers_in.cookies.nelts); | |
+ } | |
+ | |
+ if (ngx_http_set_header_helper(r, hv, value, &h, 0) == NGX_ERROR) { | |
+ return NGX_ERROR; | |
+ } | |
+ | |
+ if (value->len == 0) { | |
+ return NGX_OK; | |
+ } | |
+ | |
+ dd("new cookie header: %p", h); | |
+ | |
+ cookie = ngx_array_push(&r->headers_in.cookies); | |
+ if (cookie == NULL) { | |
+ return NGX_ERROR; | |
+ } | |
+ | |
+ *cookie = h; | |
+ return NGX_OK; | |
+} | |
+ | |
+ | |
+static ngx_int_t | |
ngx_http_clear_content_length_header(ngx_http_request_t *r, | |
ngx_http_lua_header_val_t *hv, ngx_str_t *value) | |
{ | |
diff --git a/t/113-req-header-cookie.t b/t/113-req-header-cookie.t | |
new file mode 100644 | |
index 0000000..5265860 | |
--- /dev/null | |
+++ b/t/113-req-header-cookie.t | |
@@ -0,0 +1,251 @@ | |
+# 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 cookie (with existing cookies) | |
+--- config | |
+ location /t { | |
+ rewrite_by_lua ' | |
+ ngx.req.set_header("Cookie", nil) | |
+ '; | |
+ echo "Cookie foo: $cookie_foo"; | |
+ echo "Cookie baz: $cookie_baz"; | |
+ echo "Cookie: $http_cookie"; | |
+ } | |
+--- request | |
+GET /t | |
+--- more_headers | |
+Cookie: foo=bar | |
+Cookie: baz=blah | |
+ | |
+--- stap | |
+F(ngx_http_lua_rewrite_by_chunk) { | |
+ printf("rewrite: cookies: %d\n", $r->headers_in->cookies->nelts) | |
+} | |
+ | |
+F(ngx_http_core_content_phase) { | |
+ printf("content: cookies: %d\n", $r->headers_in->cookies->nelts) | |
+} | |
+ | |
+--- stap_out | |
+rewrite: cookies: 2 | |
+content: cookies: 0 | |
+ | |
+--- response_body | |
+Cookie foo: | |
+Cookie baz: | |
+Cookie: | |
+ | |
+--- no_error_log | |
+[error] | |
+ | |
+ | |
+ | |
+=== TEST 2: clear cookie (without existing cookies) | |
+--- config | |
+ location /t { | |
+ rewrite_by_lua ' | |
+ ngx.req.set_header("Cookie", nil) | |
+ '; | |
+ echo "Cookie foo: $cookie_foo"; | |
+ echo "Cookie baz: $cookie_baz"; | |
+ echo "Cookie: $http_cookie"; | |
+ } | |
+--- request | |
+GET /t | |
+ | |
+--- stap | |
+F(ngx_http_lua_rewrite_by_chunk) { | |
+ printf("rewrite: cookies: %d\n", $r->headers_in->cookies->nelts) | |
+} | |
+ | |
+F(ngx_http_core_content_phase) { | |
+ printf("content: cookies: %d\n", $r->headers_in->cookies->nelts) | |
+} | |
+ | |
+--- stap_out | |
+rewrite: cookies: 0 | |
+content: cookies: 0 | |
+ | |
+--- response_body | |
+Cookie foo: | |
+Cookie baz: | |
+Cookie: | |
+ | |
+--- no_error_log | |
+[error] | |
+ | |
+ | |
+ | |
+=== TEST 3: set one custom cookie (with existing cookies) | |
+--- config | |
+ location /t { | |
+ rewrite_by_lua ' | |
+ ngx.req.set_header("Cookie", "boo=123") | |
+ '; | |
+ echo "Cookie foo: $cookie_foo"; | |
+ echo "Cookie baz: $cookie_baz"; | |
+ echo "Cookie boo: $cookie_boo"; | |
+ echo "Cookie: $http_cookie"; | |
+ } | |
+--- request | |
+GET /t | |
+--- more_headers | |
+Cookie: foo=bar | |
+Cookie: baz=blah | |
+ | |
+--- stap | |
+F(ngx_http_lua_rewrite_by_chunk) { | |
+ printf("rewrite: cookies: %d\n", $r->headers_in->cookies->nelts) | |
+} | |
+ | |
+F(ngx_http_core_content_phase) { | |
+ printf("content: cookies: %d\n", $r->headers_in->cookies->nelts) | |
+} | |
+ | |
+--- stap_out | |
+rewrite: cookies: 2 | |
+content: cookies: 1 | |
+ | |
+--- response_body | |
+Cookie foo: | |
+Cookie baz: | |
+Cookie boo: 123 | |
+Cookie: boo=123 | |
+ | |
+--- no_error_log | |
+[error] | |
+ | |
+ | |
+ | |
+=== TEST 4: set one custom cookie (without existing cookies) | |
+--- config | |
+ location /t { | |
+ rewrite_by_lua ' | |
+ ngx.req.set_header("Cookie", "boo=123") | |
+ '; | |
+ echo "Cookie foo: $cookie_foo"; | |
+ echo "Cookie baz: $cookie_baz"; | |
+ echo "Cookie boo: $cookie_boo"; | |
+ echo "Cookie: $http_cookie"; | |
+ } | |
+--- request | |
+GET /t | |
+ | |
+--- stap | |
+F(ngx_http_lua_rewrite_by_chunk) { | |
+ printf("rewrite: cookies: %d\n", $r->headers_in->cookies->nelts) | |
+} | |
+ | |
+F(ngx_http_core_content_phase) { | |
+ printf("content: cookies: %d\n", $r->headers_in->cookies->nelts) | |
+} | |
+ | |
+--- stap_out | |
+rewrite: cookies: 0 | |
+content: cookies: 1 | |
+ | |
+--- response_body | |
+Cookie foo: | |
+Cookie baz: | |
+Cookie boo: 123 | |
+Cookie: boo=123 | |
+ | |
+--- no_error_log | |
+[error] | |
+ | |
+ | |
+ | |
+=== TEST 5: set multiple custom cookies (with existing cookies) | |
+--- config | |
+ location /t { | |
+ rewrite_by_lua ' | |
+ ngx.req.set_header("Cookie", {"boo=123","foo=78"}) | |
+ '; | |
+ echo "Cookie foo: $cookie_foo"; | |
+ echo "Cookie baz: $cookie_baz"; | |
+ echo "Cookie boo: $cookie_boo"; | |
+ echo "Cookie: $http_cookie"; | |
+ } | |
+--- request | |
+GET /t | |
+--- more_headers | |
+Cookie: foo=bar | |
+Cookie: baz=blah | |
+ | |
+--- stap | |
+F(ngx_http_lua_rewrite_by_chunk) { | |
+ printf("rewrite: cookies: %d\n", $r->headers_in->cookies->nelts) | |
+} | |
+ | |
+F(ngx_http_core_content_phase) { | |
+ printf("content: cookies: %d\n", $r->headers_in->cookies->nelts) | |
+} | |
+ | |
+--- stap_out | |
+rewrite: cookies: 2 | |
+content: cookies: 2 | |
+ | |
+--- response_body | |
+Cookie foo: 78 | |
+Cookie baz: | |
+Cookie boo: 123 | |
+Cookie: boo=123; foo=78 | |
+ | |
+--- no_error_log | |
+[error] | |
+ | |
+ | |
+ | |
+=== TEST 6: set one custom cookie (without existing cookies) | |
+--- config | |
+ location /t { | |
+ rewrite_by_lua ' | |
+ ngx.req.set_header("Cookie", {"boo=123", "foo=bar"}) | |
+ '; | |
+ echo "Cookie foo: $cookie_foo"; | |
+ echo "Cookie baz: $cookie_baz"; | |
+ echo "Cookie boo: $cookie_boo"; | |
+ echo "Cookie: $http_cookie"; | |
+ } | |
+--- request | |
+GET /t | |
+ | |
+--- stap | |
+F(ngx_http_lua_rewrite_by_chunk) { | |
+ printf("rewrite: cookies: %d\n", $r->headers_in->cookies->nelts) | |
+} | |
+ | |
+F(ngx_http_core_content_phase) { | |
+ printf("content: cookies: %d\n", $r->headers_in->cookies->nelts) | |
+} | |
+ | |
+--- stap_out | |
+rewrite: cookies: 0 | |
+content: cookies: 2 | |
+ | |
+--- response_body | |
+Cookie foo: bar | |
+Cookie baz: | |
+Cookie boo: 123 | |
+Cookie: boo=123; foo=bar | |
+ | |
+--- no_error_log | |
+[error] | |
+ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment