From 3f3953599a2de05f82f09cb0efe442d3d58f3e16 Mon Sep 17 00:00:00 2001 From: Aviram Date: Wed, 24 Apr 2013 10:36:55 +0300 Subject: [PATCH 1/8] Added an optional parameter for ngx.req.set_header and ngx.req.clear_header that determines whether or not to replace underscores with hyphens. Previously, underscores were replaced unconditionally. Currently each of the functions has another boolean argument. If it's false, underscores would not be touched. If it's true, they would. The default value of the argument is true. --- src/ngx_http_lua_headers.c | 40 ++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/ngx_http_lua_headers.c b/src/ngx_http_lua_headers.c index 0f30a78ff8..a91a3c9314 100644 --- a/src/ngx_http_lua_headers.c +++ b/src/ngx_http_lua_headers.c @@ -581,12 +581,26 @@ ngx_http_lua_ngx_header_set(lua_State *L) static int ngx_http_lua_ngx_req_header_clear(lua_State *L) { - if (lua_gettop(L) != 1) { - return luaL_error(L, "expecting one arguments, but seen %d", + ngx_uint_t n; + n = lua_gettop(L); + if ((n != 1) && (n != 2)) { + return luaL_error(L, "expecting one or two arguments, but seen %d", lua_gettop(L)); } - lua_pushnil(L); + if (n == 2) { + u_char *p; + size_t len; + int replace_underscores = 1; + p = (u_char *) luaL_checklstring(L, 1, &len); + replace_underscores = lua_toboolean(L, 2); + lua_pop(L, 2); + lua_pushlstring(L, (char *) p, len); + lua_pushnil(L); + lua_pushboolean(L, replace_underscores); + } else { + lua_pushnil(L); + } return ngx_http_lua_ngx_req_header_set_helper(L); } @@ -595,7 +609,7 @@ ngx_http_lua_ngx_req_header_clear(lua_State *L) static int ngx_http_lua_ngx_req_header_set(lua_State *L) { - if (lua_gettop(L) != 2) { + if ((lua_gettop(L) != 2) && (lua_gettop(L) != 3)) { return luaL_error(L, "expecting two arguments, but seen %d", lua_gettop(L)); } @@ -615,6 +629,7 @@ ngx_http_lua_ngx_req_header_set_helper(lua_State *L) size_t len; ngx_int_t rc; ngx_uint_t n; + int replace_underscores = 1; lua_pushlightuserdata(L, &ngx_http_lua_request_key); lua_rawget(L, LUA_GLOBALSINDEX); @@ -627,17 +642,26 @@ ngx_http_lua_ngx_req_header_set_helper(lua_State *L) ngx_http_lua_check_fake_request(L, r); + n = lua_gettop(L); + if (n >= 3) { + replace_underscores = lua_toboolean(L, 3); + } else { + replace_underscores = 1; + } + p = (u_char *) luaL_checklstring(L, 1, &len); dd("key: %.*s, len %d", (int) len, p, (int) len); + if (replace_underscores) { /* replace "_" with "-" */ - for (i = 0; i < len; i++) { - if (p[i] == '_') { - p[i] = '-'; + for (i = 0; i < len; i++) { + if (p[i] == '_') { + p[i] = '-'; + } } } - + key.data = ngx_palloc(r->pool, len + 1); if (key.data == NULL) { return luaL_error(L, "out of memory"); From 1c5e5b9f0d030f66aec123b4cd22c7e23feaf34e Mon Sep 17 00:00:00 2001 From: aviramc Date: Wed, 8 May 2013 13:23:50 +0300 Subject: [PATCH 2/8] Changed the replace_underscores parameter to a table of parameters (options), in which the only possible option currently is replace_underscores. --- src/ngx_http_lua_headers.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ngx_http_lua_headers.c b/src/ngx_http_lua_headers.c index a91a3c9314..95df6111c8 100644 --- a/src/ngx_http_lua_headers.c +++ b/src/ngx_http_lua_headers.c @@ -643,8 +643,11 @@ ngx_http_lua_ngx_req_header_set_helper(lua_State *L) ngx_http_lua_check_fake_request(L, r); n = lua_gettop(L); - if (n >= 3) { - replace_underscores = lua_toboolean(L, 3); + if (n == 3) { + luaL_checktype(L, 3, LUA_TTABLE); + lua_getfield(L, 3, "replace_underscores"); + replace_underscores = lua_toboolean(L, -1); + lua_pop(L, 1); } else { replace_underscores = 1; } From f2e849a7efc23f86971596110a819d1057aeee37 Mon Sep 17 00:00:00 2001 From: aviramc Date: Wed, 8 May 2013 13:44:32 +0300 Subject: [PATCH 3/8] Added an options table to clean_header as well. --- src/ngx_http_lua_headers.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/ngx_http_lua_headers.c b/src/ngx_http_lua_headers.c index 95df6111c8..36f6a01c5a 100644 --- a/src/ngx_http_lua_headers.c +++ b/src/ngx_http_lua_headers.c @@ -589,15 +589,9 @@ ngx_http_lua_ngx_req_header_clear(lua_State *L) } if (n == 2) { - u_char *p; - size_t len; - int replace_underscores = 1; - p = (u_char *) luaL_checklstring(L, 1, &len); - replace_underscores = lua_toboolean(L, 2); - lua_pop(L, 2); - lua_pushlstring(L, (char *) p, len); lua_pushnil(L); - lua_pushboolean(L, replace_underscores); + /* Top element is now 3, replace it with element 3 */ + lua_insert(L, 2); } else { lua_pushnil(L); } From d4d2988488c5a6758d2e87a47c592d833513329d Mon Sep 17 00:00:00 2001 From: aviram Date: Sun, 29 Sep 2013 10:54:33 +0200 Subject: [PATCH 4/8] Removed unneeded variable. --- src/ngx_http_lua_headers.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ngx_http_lua_headers.c b/src/ngx_http_lua_headers.c index 6960a3c238..3a0226517d 100644 --- a/src/ngx_http_lua_headers.c +++ b/src/ngx_http_lua_headers.c @@ -604,7 +604,6 @@ ngx_http_lua_ngx_req_header_set_helper(lua_State *L) size_t len; ngx_int_t rc; ngx_uint_t n; - int replace_underscores = 1; r = ngx_http_lua_get_req(L); if (r == NULL) { From 2799aad1906b99a54f9bb18b10cad7966bef06d6 Mon Sep 17 00:00:00 2001 From: aviram Date: Mon, 30 Sep 2013 10:49:17 +0200 Subject: [PATCH 5/8] Lua subrequests - added support for passing the method optional parameter as a string. If the method string isn't a known Nginx method, it is still passed (and Nginx considers it as unknown). --- src/ngx_http_lua_subrequest.c | 100 ++++++++++++++++++++++++++++++---- 1 file changed, 89 insertions(+), 11 deletions(-) diff --git a/src/ngx_http_lua_subrequest.c b/src/ngx_http_lua_subrequest.c index bb10fff4b0..c21ad1795e 100644 --- a/src/ngx_http_lua_subrequest.c +++ b/src/ngx_http_lua_subrequest.c @@ -50,6 +50,23 @@ ngx_str_t ngx_http_lua_patch_method = ngx_str_t ngx_http_lua_trace_method = ngx_http_lua_method_name("TRACE"); +ngx_str_t * ngx_http_lua_ordered_methods[] = { + &ngx_http_lua_get_method, + &ngx_http_lua_head_method, + &ngx_http_lua_post_method, + &ngx_http_lua_put_method, + &ngx_http_lua_delete_method, + &ngx_http_lua_mkcol_method, + &ngx_http_lua_copy_method, + &ngx_http_lua_move_method, + &ngx_http_lua_options_method, + &ngx_http_lua_propfind_method, + &ngx_http_lua_proppatch_method, + &ngx_http_lua_lock_method, + &ngx_http_lua_unlock_method, + &ngx_http_lua_patch_method, + &ngx_http_lua_trace_method, +}; static ngx_str_t ngx_http_lua_content_length_header_key = ngx_string("Content-Length"); @@ -58,7 +75,7 @@ static ngx_str_t ngx_http_lua_content_length_header_key = static ngx_int_t ngx_http_lua_set_content_length_header(ngx_http_request_t *r, off_t len); static ngx_int_t ngx_http_lua_adjust_subrequest(ngx_http_request_t *sr, - ngx_uint_t method, int forward_body, + ngx_uint_t method, ngx_str_t *method_name, int forward_body, ngx_http_request_body_t *body, unsigned vars_action, ngx_array_t *extra_vars); static int ngx_http_lua_ngx_location_capture(lua_State *L); @@ -136,6 +153,11 @@ ngx_http_lua_ngx_location_capture_multi(lua_State *L) unsigned vars_action; ngx_uint_t nsubreqs; ngx_uint_t index; + ngx_uint_t method_index; + ngx_uint_t methods_number; + ngx_str_t *ngx_method_name = NULL; + u_char *lua_method_name; + size_t method_name_length; size_t sr_statuses_len; size_t sr_headers_len; size_t sr_bodies_len; @@ -386,15 +408,62 @@ ngx_http_lua_ngx_location_capture_multi(lua_State *L) type = lua_type(L, -1); - if (type == LUA_TNIL) { - method = NGX_HTTP_GET; + switch (type) { + case LUA_TNIL: + method = NGX_HTTP_GET; + break; + case LUA_TNUMBER: + method = (ngx_uint_t) lua_tonumber(L, -1); + break; + case LUA_TSTRING: + lua_method_name = (u_char *) lua_tolstring(L, -1, + &method_name_length); + if (method_name_length == 0) { + return luaL_error(L, "Bad http request method"); + } + + methods_number = sizeof(ngx_http_lua_ordered_methods) / + sizeof(ngx_http_lua_ordered_methods[0]); + for (method_index = 0; method_index < methods_number; + method_index++) { + if (ngx_strncasecmp( + ngx_http_lua_ordered_methods[method_index]->data, + lua_method_name, + method_name_length) + == 0) { + break; + } + } - } else { - if (type != LUA_TNUMBER) { + if (method_index == methods_number) { + /* unknown method */ + method = NGX_HTTP_UNKNOWN; + ngx_method_name = ngx_palloc(r->pool, + sizeof(ngx_str_t)); + if (ngx_method_name == NULL) { + return luaL_error(L, "out of memory"); + } + ngx_method_name->data = ngx_palloc(r->pool, + method_name_length); + if (ngx_method_name->data == NULL) { + return luaL_error(L, "out of memory"); + } + ngx_memcpy(ngx_method_name->data, + lua_method_name, + method_name_length); + ngx_memcpy(ngx_method_name->data + method_name_length, + " ", + 1); + ngx_method_name->len = method_name_length; + } else { + /* the method is a bit field, the first value is + of NGX_HTTP_GET */ + method = NGX_HTTP_GET << method_index; + ngx_method_name = NULL; + } + break; + default: return luaL_error(L, "Bad http request method"); - } - - method = (ngx_uint_t) lua_tonumber(L, -1); } lua_pop(L, 1); @@ -577,7 +646,8 @@ ngx_http_lua_ngx_location_capture_multi(lua_State *L) ngx_http_set_ctx(sr, sr_ctx, ngx_http_lua_module); - rc = ngx_http_lua_adjust_subrequest(sr, method, always_forward_body, + rc = ngx_http_lua_adjust_subrequest(sr, method, ngx_method_name, + always_forward_body, body, vars_action, extra_vars); if (rc != NGX_OK) { @@ -613,8 +683,9 @@ ngx_http_lua_ngx_location_capture_multi(lua_State *L) static ngx_int_t ngx_http_lua_adjust_subrequest(ngx_http_request_t *sr, ngx_uint_t method, - int always_forward_body, ngx_http_request_body_t *body, - unsigned vars_action, ngx_array_t *extra_vars) + ngx_str_t *method_name, int always_forward_body, + ngx_http_request_body_t *body, unsigned vars_action, + ngx_array_t *extra_vars) { ngx_http_request_t *r; ngx_int_t rc; @@ -665,6 +736,13 @@ ngx_http_lua_adjust_subrequest(ngx_http_request_t *sr, ngx_uint_t method, sr->method = method; switch (method) { + case NGX_HTTP_UNKNOWN: + if (method_name == NULL) { + return NGX_ERROR; + } + sr->method_name = *method_name; + break; + case NGX_HTTP_GET: sr->method_name = ngx_http_lua_get_method; break; From e9e1dec69b88803a0080cbdbcb28151e31674fd9 Mon Sep 17 00:00:00 2001 From: aviram Date: Thu, 3 Oct 2013 17:40:18 +0200 Subject: [PATCH 6/8] Reverted unnecessary changes. --- src/ngx_http_lua_headers.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/src/ngx_http_lua_headers.c b/src/ngx_http_lua_headers.c index af56a2d8b0..3fd4672216 100644 --- a/src/ngx_http_lua_headers.c +++ b/src/ngx_http_lua_headers.c @@ -574,19 +574,13 @@ ngx_http_lua_ngx_req_header_clear(lua_State *L) { ngx_uint_t n; n = lua_gettop(L); - if ((n != 1) && (n != 2)) { - return luaL_error(L, "expecting one or two arguments, but seen %d", + if (lua_gettop(L) != 1) { + return luaL_error(L, "expecting one arguments, but seen %d", lua_gettop(L)); } - if (n == 2) { - lua_pushnil(L); - /* Top element is now 3, replace it with element 3 */ - lua_insert(L, 2); - } else { - lua_pushnil(L); - } - + lua_pushnil(L); + return ngx_http_lua_ngx_req_header_set_helper(L); } @@ -594,7 +588,7 @@ ngx_http_lua_ngx_req_header_clear(lua_State *L) static int ngx_http_lua_ngx_req_header_set(lua_State *L) { - if ((lua_gettop(L) != 2) && (lua_gettop(L) != 3)) { + if (lua_gettop(L) != 2) { return luaL_error(L, "expecting two arguments, but seen %d", lua_gettop(L)); } @@ -632,10 +626,9 @@ ngx_http_lua_ngx_req_header_set_helper(lua_State *L) #if 0 /* replace "_" with "-" */ - for (i = 0; i < len; i++) { - if (p[i] == '_') { - p[i] = '-'; - } + for (i = 0; i < len; i++) { + if (p[i] == '_') { + p[i] = '-'; } } #endif From 24cb6857e2a1452733be9185a59f600e962dc029 Mon Sep 17 00:00:00 2001 From: aviram Date: Thu, 3 Oct 2013 17:41:25 +0200 Subject: [PATCH 7/8] Reverted unnecessary changes. --- src/ngx_http_lua_headers.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ngx_http_lua_headers.c b/src/ngx_http_lua_headers.c index 3fd4672216..c9d89aa941 100644 --- a/src/ngx_http_lua_headers.c +++ b/src/ngx_http_lua_headers.c @@ -572,15 +572,13 @@ ngx_http_lua_ngx_header_set(lua_State *L) static int ngx_http_lua_ngx_req_header_clear(lua_State *L) { - ngx_uint_t n; - n = lua_gettop(L); if (lua_gettop(L) != 1) { return luaL_error(L, "expecting one arguments, but seen %d", lua_gettop(L)); } lua_pushnil(L); - + return ngx_http_lua_ngx_req_header_set_helper(L); } From aa7ff3396f82598983be20c7ce632b5d2c5b530b Mon Sep 17 00:00:00 2001 From: aviram Date: Thu, 3 Oct 2013 17:50:25 +0200 Subject: [PATCH 8/8] Reverted unnecessary changes. --- src/ngx_http_lua_headers.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/ngx_http_lua_headers.c b/src/ngx_http_lua_headers.c index 3a0226517d..3afbd7ba76 100644 --- a/src/ngx_http_lua_headers.c +++ b/src/ngx_http_lua_headers.c @@ -562,20 +562,12 @@ ngx_http_lua_ngx_header_set(lua_State *L) static int ngx_http_lua_ngx_req_header_clear(lua_State *L) { - ngx_uint_t n; - n = lua_gettop(L); - if ((n != 1) && (n != 2)) { - return luaL_error(L, "expecting one or two arguments, but seen %d", + if (lua_gettop(L) != 1) { + return luaL_error(L, "expecting one arguments, but seen %d", lua_gettop(L)); } - if (n == 2) { - lua_pushnil(L); - /* Top element is now 3, replace it with element 3 */ - lua_insert(L, 2); - } else { - lua_pushnil(L); - } + lua_pushnil(L); return ngx_http_lua_ngx_req_header_set_helper(L); } @@ -584,7 +576,7 @@ ngx_http_lua_ngx_req_header_clear(lua_State *L) static int ngx_http_lua_ngx_req_header_set(lua_State *L) { - if ((lua_gettop(L) != 2) && (lua_gettop(L) != 3)) { + if (lua_gettop(L) != 2) { return luaL_error(L, "expecting two arguments, but seen %d", lua_gettop(L)); } @@ -622,10 +614,9 @@ ngx_http_lua_ngx_req_header_set_helper(lua_State *L) #if 0 /* replace "_" with "-" */ - for (i = 0; i < len; i++) { - if (p[i] == '_') { - p[i] = '-'; - } + for (i = 0; i < len; i++) { + if (p[i] == '_') { + p[i] = '-'; } } #endif