Line data Source code
1 :
2 : /*
3 : * Copyright (C) Yichun Zhang (agentzh)
4 : */
5 :
6 :
7 : #ifndef DDEBUG
8 : #define DDEBUG 0
9 : #endif
10 : #include "ddebug.h"
11 :
12 :
13 : #include "ngx_http_lua_ndk.h"
14 : #include "ngx_http_lua_util.h"
15 :
16 :
17 : #if defined(NDK) && NDK
18 :
19 :
20 : static ndk_set_var_value_pt ngx_http_lookup_ndk_set_var_directive(u_char *name,
21 : size_t name_len);
22 : static int ngx_http_lua_ndk_set_var_get(lua_State *L);
23 : static int ngx_http_lua_ndk_set_var_set(lua_State *L);
24 : static int ngx_http_lua_run_set_var_directive(lua_State *L);
25 :
26 :
27 : int
28 0 : ngx_http_lua_ndk_set_var_get(lua_State *L)
29 : {
30 : ndk_set_var_value_pt func;
31 : size_t len;
32 : u_char *p;
33 :
34 0 : p = (u_char *) luaL_checklstring(L, 2, &len);
35 :
36 : dd("ndk.set_var metatable __index: %s", p);
37 :
38 0 : func = ngx_http_lookup_ndk_set_var_directive(p, len);
39 :
40 0 : if (func == NULL) {
41 0 : return luaL_error(L, "ndk.set_var: directive \"%s\" not found "
42 : "or does not use ndk_set_var_value", p);
43 : }
44 :
45 0 : lua_pushvalue(L, -1); /* table key key */
46 0 : lua_pushvalue(L, -1); /* table key key key */
47 0 : lua_pushlightuserdata(L, (void *) func); /* table key key key func */
48 0 : lua_pushcclosure(L, ngx_http_lua_run_set_var_directive, 2);
49 : /* table key key closure */
50 0 : lua_rawset(L, 1); /* table key */
51 0 : lua_rawget(L, 1); /* table closure */
52 :
53 0 : return 1;
54 : }
55 :
56 :
57 : int
58 0 : ngx_http_lua_ndk_set_var_set(lua_State *L)
59 : {
60 0 : return luaL_error(L, "Not allowed");
61 : }
62 :
63 :
64 : int
65 0 : ngx_http_lua_run_set_var_directive(lua_State *L)
66 : {
67 : ngx_int_t rc;
68 : ndk_set_var_value_pt func;
69 : ngx_str_t res;
70 : ngx_http_variable_value_t arg;
71 : u_char *p;
72 : size_t len;
73 : ngx_http_request_t *r;
74 :
75 0 : if (lua_gettop(L) != 1) {
76 0 : return luaL_error(L, "expecting one argument");
77 : }
78 :
79 : #if 1
80 0 : ngx_memzero(&arg, sizeof(ngx_http_variable_value_t));
81 :
82 0 : arg.valid = 1;
83 : #endif
84 :
85 0 : arg.data = (u_char *) luaL_checklstring(L, 1, &len);
86 0 : arg.len = len;
87 :
88 0 : r = ngx_http_lua_get_req(L);
89 0 : if (r == NULL) {
90 0 : return luaL_error(L, "no request object found");
91 : }
92 :
93 0 : p = (u_char *) luaL_checklstring(L, lua_upvalueindex(1), &len);
94 :
95 : dd("calling set_var func for %s", p);
96 :
97 0 : func = (ndk_set_var_value_pt) lua_touserdata(L, lua_upvalueindex(2));
98 :
99 0 : rc = func(r, &res, &arg);
100 :
101 0 : if (rc != NGX_OK) {
102 0 : return luaL_error(L, "calling directive %s failed with code %d",
103 : p, (int) rc);
104 : }
105 :
106 0 : lua_pushlstring(L, (char *) res.data, res.len);
107 :
108 0 : return 1;
109 : }
110 :
111 :
112 : static ndk_set_var_value_pt
113 0 : ngx_http_lookup_ndk_set_var_directive(u_char *name,
114 : size_t name_len)
115 : {
116 : ndk_set_var_t *filter;
117 : ngx_uint_t i;
118 : ngx_module_t *module;
119 : ngx_module_t **modules;
120 : ngx_command_t *cmd;
121 :
122 : #if defined(nginx_version) && nginx_version >= 1009011
123 0 : modules = ngx_cycle->modules;
124 : #else
125 : modules = ngx_modules;
126 : #endif
127 :
128 0 : for (i = 0; modules[i]; i++) {
129 0 : module = modules[i];
130 0 : if (module->type != NGX_HTTP_MODULE) {
131 0 : continue;
132 : }
133 :
134 0 : cmd = modules[i]->commands;
135 0 : if (cmd == NULL) {
136 0 : continue;
137 : }
138 :
139 0 : for ( /* void */ ; cmd->name.len; cmd++) {
140 0 : if (cmd->set != ndk_set_var_value) {
141 0 : continue;
142 : }
143 :
144 0 : filter = cmd->post;
145 0 : if (filter == NULL) {
146 0 : continue;
147 : }
148 :
149 0 : if (cmd->name.len != name_len
150 0 : || ngx_strncmp(cmd->name.data, name, name_len) != 0)
151 : {
152 0 : continue;
153 : }
154 :
155 0 : return (ndk_set_var_value_pt)(filter->func);
156 : }
157 : }
158 :
159 0 : return NULL;
160 : }
161 :
162 :
163 : void
164 18 : ngx_http_lua_inject_ndk_api(lua_State *L)
165 : {
166 18 : lua_createtable(L, 0, 1 /* nrec */); /* ndk.* */
167 :
168 18 : lua_newtable(L); /* .set_var */
169 :
170 18 : lua_createtable(L, 0, 2 /* nrec */); /* metatable for .set_var */
171 18 : lua_pushcfunction(L, ngx_http_lua_ndk_set_var_get);
172 18 : lua_setfield(L, -2, "__index");
173 18 : lua_pushcfunction(L, ngx_http_lua_ndk_set_var_set);
174 18 : lua_setfield(L, -2, "__newindex");
175 18 : lua_setmetatable(L, -2);
176 :
177 18 : lua_setfield(L, -2, "set_var");
178 :
179 18 : lua_getglobal(L, "package"); /* ndk package */
180 18 : lua_getfield(L, -1, "loaded"); /* ndk package loaded */
181 18 : lua_pushvalue(L, -3); /* ndk package loaded ndk */
182 18 : lua_setfield(L, -2, "ndk"); /* ndk package loaded */
183 18 : lua_pop(L, 2);
184 :
185 18 : lua_setglobal(L, "ndk");
186 18 : }
187 :
188 :
189 : #endif /* defined(NDK) && NDK */
190 :
191 : /* vi:set ft=c ts=4 sw=4 et fdm=marker: */
|