Browse files

feature: added new Nginx API for Lua: ngx.req.set_method(method_id) a…

…nd ngx.req.get_method. thanks Matthieu Tourne for suggesting these.
  • Loading branch information...
1 parent 4960e01 commit e9d5d601a3ff687d09bec9305217b6b3639fb34e @agentzh agentzh committed Jul 5, 2012
View
1 .gitignore
@@ -140,3 +140,4 @@ src/bodyfilterby.[ch]
src/tcp.[ch]
src/initby.[ch]
src/socket.[ch]
+src/method.[ch]
View
2 config
@@ -181,6 +181,7 @@ NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
$ngx_addon_dir/src/ngx_http_lua_sleep.c \
$ngx_addon_dir/src/ngx_http_lua_bodyfilterby.c \
$ngx_addon_dir/src/ngx_http_lua_initby.c \
+ $ngx_addon_dir/src/ngx_http_lua_req_method.c \
"
NGX_ADDON_DEPS="$NGX_ADDON_DEPS \
@@ -225,6 +226,7 @@ NGX_ADDON_DEPS="$NGX_ADDON_DEPS \
$ngx_addon_dir/src/ngx_http_lua_sleep.h \
$ngx_addon_dir/src/ngx_http_lua_bodyfilterby.h \
$ngx_addon_dir/src/ngx_http_lua_initby.h \
+ $ngx_addon_dir/src/ngx_http_lua_req_method.h \
"
CFLAGS="$CFLAGS -DNDK_SET_VAR"
View
108 src/ngx_http_lua_req_method.c
@@ -0,0 +1,108 @@
+#ifndef DDEBUG
+#define DDEBUG 0
+#endif
+
+#include "ddebug.h"
+#include "ngx_http_lua_req_method.h"
+#include "ngx_http_lua_subrequest.h"
+#include "ngx_http_lua_util.h"
+
+
+static int ngx_http_lua_ngx_req_get_method(lua_State *L);
+static int ngx_http_lua_ngx_req_set_method(lua_State *L);
+
+
+void
+ngx_http_lua_inject_req_method_api(lua_State *L)
+{
+ lua_pushcfunction(L, ngx_http_lua_ngx_req_get_method);
+ lua_setfield(L, -2, "get_method");
+
+ lua_pushcfunction(L, ngx_http_lua_ngx_req_set_method);
+ lua_setfield(L, -2, "set_method");
+}
+
+
+static int
+ngx_http_lua_ngx_req_get_method(lua_State *L)
+{
+ int n;
+ ngx_http_request_t *r;
+
+ n = lua_gettop(L);
+ if (n != 0) {
+ return luaL_error(L, "only one argument expected but got %d", n);
+ }
+
+ lua_pushlightuserdata(L, &ngx_http_lua_request_key);
+ lua_rawget(L, LUA_GLOBALSINDEX);
+ r = lua_touserdata(L, -1);
+ lua_pop(L, 1);
+
+ if (r == NULL) {
+ return luaL_error(L, "request object not found");
+ }
+
+ lua_pushlstring(L, (char *) r->method_name.data, r->method_name.len);
+ return 1;
+}
+
+
+static int
+ngx_http_lua_ngx_req_set_method(lua_State *L)
+{
+ int n;
+ int method;
+ ngx_http_request_t *r;
+
+ n = lua_gettop(L);
+ if (n != 1) {
+ return luaL_error(L, "only one argument expected but got %d", n);
+ }
+
+ method = luaL_checkint(L, 1);
+
+ lua_pushlightuserdata(L, &ngx_http_lua_request_key);
+ lua_rawget(L, LUA_GLOBALSINDEX);
+ r = lua_touserdata(L, -1);
+ lua_pop(L, 1);
+
+ if (r == NULL) {
+ return luaL_error(L, "request object not found");
+ }
+
+ r->method = method;
+
+ switch (method) {
+ case NGX_HTTP_GET:
+ r->method_name = ngx_http_lua_get_method;
+ break;
+
+ case NGX_HTTP_POST:
+ r->method_name = ngx_http_lua_post_method;
+ break;
+
+ case NGX_HTTP_PUT:
+ r->method_name = ngx_http_lua_put_method;
+ break;
+
+ case NGX_HTTP_HEAD:
+ r->method_name = ngx_http_lua_head_method;
+ break;
+
+ case NGX_HTTP_DELETE:
+ r->method_name = ngx_http_lua_delete_method;
+ break;
+
+ case NGX_HTTP_OPTIONS:
+ r->method_name = ngx_http_lua_options_method;
+ break;
+
+ default:
+ return luaL_error(L, "unsupported HTTP method: %d", method);
+
+ }
+
+ return 0;
+}
+
View
12 src/ngx_http_lua_req_method.h
@@ -0,0 +1,12 @@
+#ifndef NGX_HTTP_LUA_METHOD_H
+#define NGX_HTTP_LUA_METHOD_H
+
+
+#include "ngx_http_lua_common.h"
+
+
+void ngx_http_lua_inject_req_method_api(lua_State *L);
+
+
+#endif /* NGX_HTTP_LUA_METHOD_H */
+
View
12 src/ngx_http_lua_subrequest.c
@@ -15,13 +15,13 @@
#define ngx_http_lua_method_name(m) { sizeof(m) - 1, (u_char *) m " " }
-static ngx_str_t ngx_http_lua_get_method = ngx_http_lua_method_name("GET");
-static ngx_str_t ngx_http_lua_put_method = ngx_http_lua_method_name("PUT");
-static ngx_str_t ngx_http_lua_post_method = ngx_http_lua_method_name("POST");
-static ngx_str_t ngx_http_lua_head_method = ngx_http_lua_method_name("HEAD");
-static ngx_str_t ngx_http_lua_delete_method =
+ngx_str_t ngx_http_lua_get_method = ngx_http_lua_method_name("GET");
+ngx_str_t ngx_http_lua_put_method = ngx_http_lua_method_name("PUT");
+ngx_str_t ngx_http_lua_post_method = ngx_http_lua_method_name("POST");
+ngx_str_t ngx_http_lua_head_method = ngx_http_lua_method_name("HEAD");
+ngx_str_t ngx_http_lua_delete_method =
ngx_http_lua_method_name("DELETE");
-static ngx_str_t ngx_http_lua_options_method =
+ngx_str_t ngx_http_lua_options_method =
ngx_http_lua_method_name("OPTIONS");
View
8 src/ngx_http_lua_subrequest.h
@@ -12,5 +12,13 @@ ngx_int_t ngx_http_lua_post_subrequest(ngx_http_request_t *r, void *data,
ngx_int_t rc);
+extern ngx_str_t ngx_http_lua_get_method;
+extern ngx_str_t ngx_http_lua_put_method;
+extern ngx_str_t ngx_http_lua_post_method;
+extern ngx_str_t ngx_http_lua_head_method;
+extern ngx_str_t ngx_http_lua_delete_method;
+extern ngx_str_t ngx_http_lua_options_method;
+
+
#endif /* NGX_HTTP_LUA_SUBREQUEST_H */
View
5 src/ngx_http_lua_util.c
@@ -26,6 +26,7 @@
#include "ngx_http_lua_string.h"
#include "ngx_http_lua_misc.h"
#include "ngx_http_lua_consts.h"
+#include "ngx_http_lua_req_method.h"
#include "ngx_http_lua_shdict.h"
#include "ngx_http_lua_socket_tcp.h"
#include "ngx_http_lua_sleep.h"
@@ -1697,7 +1698,7 @@ ngx_http_lua_inject_req_api(ngx_log_t *log, lua_State *L)
{
/* ngx.req table */
- lua_createtable(L, 0 /* narr */, 16 /* nrec */); /* .req */
+ lua_createtable(L, 0 /* narr */, 18 /* nrec */); /* .req */
ngx_http_lua_inject_req_header_api(L);
@@ -1709,6 +1710,8 @@ ngx_http_lua_inject_req_api(ngx_log_t *log, lua_State *L)
ngx_http_lua_inject_req_socket_api(L);
+ ngx_http_lua_inject_req_method_api(L);
+
lua_setfield(L, -2, "req");
}
View
6 t/062-count.t
@@ -124,7 +124,7 @@ n = 1
--- request
GET /test
--- response_body
-n = 16
+n = 18
--- no_error_log
[error]
@@ -146,7 +146,7 @@ n = 16
--- request
GET /test
--- response_body
-n = 16
+n = 18
--- no_error_log
[error]
@@ -173,7 +173,7 @@ n = 16
--- request
GET /test
--- response_body
-n = 16
+n = 18
--- no_error_log
[error]
View
227 t/088-req-method.t
@@ -0,0 +1,227 @@
+# vim:set ft= ts=4 sw=4 et fdm=marker:
+use lib 'lib';
+use Test::Nginx::Socket;
+
+#worker_connections(1014);
+#master_on();
+#workers(2);
+#log_level('warn');
+
+repeat_each(2);
+#repeat_each(1);
+
+plan tests => repeat_each() * (blocks() * 3);
+
+#no_diff();
+#no_long_string();
+run_tests();
+
+__DATA__
+
+=== TEST 1: get method name in main request
+--- config
+ location /t {
+ content_by_lua '
+ ngx.say("method: [", ngx.req.get_method(), "]")
+ ';
+ }
+--- request
+ GET /t
+--- response_body
+method: [GET]
+--- no_error_log
+[error]
+
+
+
+=== TEST 2: get method name in subrequest
+--- config
+ location /t {
+ echo_subrequest POST /sub;
+ }
+
+ location /sub {
+ content_by_lua '
+ ngx.say("method: [", ngx.req.get_method(), "]")
+ ';
+ }
+--- request
+ GET /t
+--- response_body
+method: [POST]
+--- no_error_log
+[error]
+
+
+
+=== TEST 3: set GET to POST
+--- config
+ location /t {
+ rewrite_by_lua '
+ ngx.req.set_method(ngx.HTTP_POST)
+ ';
+
+ proxy_pass http://127.0.0.1:$server_port/echo;
+ }
+
+ location /echo {
+ echo $request_method;
+ }
+--- request
+GET /t
+--- response_body
+POST
+--- no_error_log
+[error]
+
+
+
+=== TEST 4: set POST to GET
+--- config
+ location /t {
+ rewrite_by_lua '
+ ngx.req.set_method(ngx.HTTP_GET)
+ ';
+
+ proxy_pass http://127.0.0.1:$server_port/echo;
+ }
+
+ location /echo {
+ echo $request_method;
+ }
+--- request
+POST /t
+hello world
+--- response_body
+GET
+--- no_error_log
+[error]
+
+
+
+=== TEST 5: set POST to DELETE
+--- config
+ location /t {
+ rewrite_by_lua '
+ ngx.req.set_method(ngx.HTTP_DELETE)
+ ';
+
+ proxy_pass http://127.0.0.1:$server_port/echo;
+ }
+
+ location /echo {
+ echo $request_method;
+ }
+--- request
+POST /t
+hello world
+--- response_body
+DELETE
+--- no_error_log
+[error]
+
+
+
+=== TEST 6: set POST to PUT
+--- config
+ location /t {
+ rewrite_by_lua '
+ ngx.req.set_method(ngx.HTTP_PUT)
+ ';
+
+ proxy_pass http://127.0.0.1:$server_port/echo;
+ }
+
+ location /echo {
+ echo $request_method;
+ }
+--- request
+POST /t
+hello world
+--- response_body
+PUT
+--- no_error_log
+[error]
+
+
+
+=== TEST 7: set POST to PUT (using $requeset_method)
+--- config
+ location /t {
+ rewrite_by_lua '
+ ngx.req.set_method(ngx.HTTP_PUT)
+ ';
+
+ echo $request_method;
+ }
+--- request
+POST /t
+hello world
+--- response_body
+PUT
+--- no_error_log
+[error]
+
+
+
+=== TEST 8: set GET to HEAD
+--- config
+ location /t {
+ rewrite_by_lua '
+ ngx.req.set_method(ngx.HTTP_HEAD)
+ ';
+
+ proxy_pass http://127.0.0.1:$server_port/echo;
+ #proxy_pass http://127.0.0.1:8888/;
+ }
+
+ location /echo {
+ echo $request_method;
+ }
+--- request
+GET /t
+--- response_body
+--- no_error_log
+[error]
+
+
+
+=== TEST 9: set method name in subrequest
+--- config
+ location /t {
+ echo_subrequest POST /sub;
+ echo "main: $echo_request_method";
+ }
+
+ location /sub {
+ content_by_lua '
+ ngx.req.set_method(ngx.HTTP_PUT)
+ ngx.say("sub: ", ngx.var.echo_request_method)
+ ';
+ }
+--- request
+ GET /t
+--- response_body
+sub: PUT
+main: GET
+--- no_error_log
+[error]
+
+
+
+=== TEST 10: set HEAD to GET
+--- config
+ location /t {
+ rewrite_by_lua '
+ ngx.req.set_method(ngx.HTTP_GET)
+ ';
+
+ echo "method: $echo_request_method";
+ }
+--- request
+ HEAD /t
+--- response_body
+method: GET
+--- no_error_log
+[error]
+

0 comments on commit e9d5d60

Please sign in to comment.