Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 75a9f4b

Browse files
Alon Blayer-Gatalonbg
authored andcommittedSep 18, 2016
udp downstream api - work in progress
1 parent a440866 commit 75a9f4b

11 files changed

+858
-35
lines changed
 

‎src/ngx_stream_lua_output.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ ngx_stream_lua_ngx_echo(lua_State *L, unsigned newline)
6060
return luaL_error(L, "no session object found");
6161
}
6262

63+
if (s->connection->type == SOCK_DGRAM) {
64+
return luaL_error(L, "not supported in udp requests");
65+
}
66+
6367
ctx = ngx_stream_get_module_ctx(s, ngx_stream_lua_module);
6468

6569
if (ctx == NULL) {
@@ -476,6 +480,10 @@ ngx_stream_lua_ngx_flush(lua_State *L)
476480

477481
s = ngx_stream_lua_get_session(L);
478482

483+
if (s->connection->type == SOCK_DGRAM) {
484+
return luaL_error(L, "not supported in udp requests");
485+
}
486+
479487
wait = 1; /* always wait */
480488

481489
ctx = ngx_stream_get_module_ctx(s, ngx_stream_lua_module);
@@ -563,6 +571,10 @@ ngx_stream_lua_ngx_eof(lua_State *L)
563571
return luaL_error(L, "no session object found");
564572
}
565573

574+
if (s->connection->type == SOCK_DGRAM) {
575+
return luaL_error(L, "not supported in udp requests");
576+
}
577+
566578
if (lua_gettop(L) != 0) {
567579
return luaL_error(L, "no argument is expected");
568580
}

‎src/ngx_stream_lua_socket_tcp.c

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ static int ngx_stream_lua_socket_receiveuntil_iterator(lua_State *L);
9696
static ngx_int_t ngx_stream_lua_socket_compile_pattern(u_char *data, size_t len,
9797
ngx_stream_lua_socket_compiled_pattern_t *cp, ngx_log_t *log);
9898
static int ngx_stream_lua_socket_cleanup_compiled_pattern(lua_State *L);
99-
static int ngx_stream_lua_req_socket(lua_State *L);
99+
static int ngx_stream_lua_tcp_req_socket(lua_State *L);
100100
static void ngx_stream_lua_req_socket_rev_handler(ngx_stream_session_t *s,
101101
ngx_stream_lua_ctx_t *ctx);
102102
static int ngx_stream_lua_socket_tcp_getreusedtimes(lua_State *L);
@@ -197,7 +197,7 @@ enum {
197197
static char ngx_stream_lua_req_socket_metatable_key;
198198
#endif
199199
static char ngx_stream_lua_raw_req_socket_metatable_key;
200-
static char ngx_stream_lua_tcp_socket_metatable_key;
200+
static char ngx_stream_lua_socket_tcp_metatable_key;
201201
static char ngx_stream_lua_upstream_udata_metatable_key;
202202
static char ngx_stream_lua_downstream_udata_metatable_key;
203203
static char ngx_stream_lua_pool_udata_metatable_key;
@@ -293,7 +293,7 @@ ngx_stream_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L)
293293
/* }}} */
294294

295295
/* {{{tcp object metatable */
296-
lua_pushlightuserdata(L, &ngx_stream_lua_tcp_socket_metatable_key);
296+
lua_pushlightuserdata(L, &ngx_stream_lua_skcoet_tcp_metatable_key);
297297
lua_createtable(L, 0 /* narr */, 12 /* nrec */);
298298

299299
lua_pushcfunction(L, ngx_stream_lua_socket_tcp_bind);
@@ -384,14 +384,6 @@ ngx_stream_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L)
384384
}
385385

386386

387-
void
388-
ngx_stream_lua_inject_req_socket_api(lua_State *L)
389-
{
390-
lua_pushcfunction(L, ngx_stream_lua_req_socket);
391-
lua_setfield(L, -2, "socket");
392-
}
393-
394-
395387
static int
396388
ngx_stream_lua_socket_tcp(lua_State *L)
397389
{
@@ -417,7 +409,7 @@ ngx_stream_lua_socket_tcp(lua_State *L)
417409
| NGX_STREAM_LUA_CONTEXT_TIMER);
418410

419411
lua_createtable(L, 4 /* narr */, 1 /* nrec */);
420-
lua_pushlightuserdata(L, &ngx_stream_lua_tcp_socket_metatable_key);
412+
lua_pushlightuserdata(L, &ngx_stream_lua_socket_tcp_metatable_key);
421413
lua_rawget(L, LUA_REGISTRYINDEX);
422414
lua_setmetatable(L, -2);
423415

@@ -4047,14 +4039,22 @@ ngx_stream_lua_socket_cleanup_compiled_pattern(lua_State *L)
40474039
}
40484040

40494041

4042+
void
4043+
ngx_stream_lua_inject_tcp_req_socket_api(lua_State *L)
4044+
{
4045+
lua_pushcfunction(L, ngx_stream_lua_tcp_req_socket);
4046+
lua_setfield(L, -2, "socket");
4047+
}
4048+
4049+
40504050
static int
4051-
ngx_stream_lua_req_socket(lua_State *L)
4051+
ngx_stream_lua_tcp_req_socket(lua_State *L)
40524052
{
40534053
int n, raw;
4054+
ngx_stream_session_t *s;
40544055
ngx_peer_connection_t *pc;
40554056
ngx_stream_lua_srv_conf_t *lscf;
40564057
ngx_connection_t *c;
4057-
ngx_stream_session_t *s;
40584058
ngx_stream_lua_ctx_t *ctx;
40594059
ngx_stream_lua_co_ctx_t *coctx;
40604060
ngx_stream_lua_cleanup_t *cln;
@@ -4085,6 +4085,11 @@ ngx_stream_lua_req_socket(lua_State *L)
40854085

40864086
c = s->connection;
40874087

4088+
if (c->type != SOCK_STREAM) {
4089+
return luaL_error(L, "socket api does not match connection transport",
4090+
lua_gettop(L));
4091+
}
4092+
40884093
#if !defined(nginx_version) || nginx_version < 1003013
40894094
lua_pushnil(L);
40904095
lua_pushliteral(L, "nginx version too old");

‎src/ngx_stream_lua_socket_tcp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ typedef struct {
150150

151151

152152
void ngx_stream_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L);
153-
void ngx_stream_lua_inject_req_socket_api(lua_State *L);
153+
void ngx_stream_lua_inject_tcp_req_socket_api(lua_State *L);
154154
void ngx_stream_lua_cleanup_conn_pools(lua_State *L);
155155

156156

‎src/ngx_stream_lua_socket_udp.c

Lines changed: 238 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@ static int ngx_stream_lua_socket_udp_setpeername(lua_State *L);
3232
static int ngx_stream_lua_socket_udp_send(lua_State *L);
3333
static int ngx_stream_lua_socket_udp_receive(lua_State *L);
3434
static int ngx_stream_lua_socket_udp_settimeout(lua_State *L);
35+
static int ngx_stream_lua_udp_req_socket(lua_State *L);
3536
static void ngx_stream_lua_socket_udp_finalize(ngx_stream_session_t *s,
3637
ngx_stream_lua_socket_udp_upstream_t *u);
38+
static int ngx_stream_lua_socket_udp_downstream_destroy(lua_State *L);
3739
static int ngx_stream_lua_socket_udp_upstream_destroy(lua_State *L);
3840
static int ngx_stream_lua_socket_resolve_retval_handler(ngx_stream_session_t *s,
3941
ngx_stream_lua_socket_udp_upstream_t *u, lua_State *L);
@@ -76,8 +78,13 @@ enum {
7678
};
7779

7880

81+
#if 0
82+
static char ngx_stream_lua_req_socket_metatable_key;
83+
#endif
84+
static char ngx_stream_lua_raw_req_socket_metatable_key;
7985
static char ngx_stream_lua_socket_udp_metatable_key;
80-
static char ngx_stream_lua_udp_udata_metatable_key;
86+
static char ngx_stream_lua_upstream_udata_metatable_key;
87+
static char ngx_stream_lua_downstream_udata_metatable_key;
8188
static u_char ngx_stream_lua_socket_udp_buffer[UDP_MAX_DATAGRAM_SIZE];
8289

8390

@@ -119,18 +126,206 @@ ngx_stream_lua_inject_socket_udp_api(ngx_log_t *log, lua_State *L)
119126
lua_rawset(L, LUA_REGISTRYINDEX);
120127
/* }}} */
121128

122-
/* udp socket object metatable */
123-
lua_pushlightuserdata(L, &ngx_stream_lua_udp_udata_metatable_key);
129+
/* {{{upstream userdata metatable */
130+
lua_pushlightuserdata(L, &ngx_stream_lua_upstream_udata_metatable_key);
124131
lua_createtable(L, 0 /* narr */, 1 /* nrec */); /* metatable */
125132
lua_pushcfunction(L, ngx_stream_lua_socket_udp_upstream_destroy);
126133
lua_setfield(L, -2, "__gc");
127134
lua_rawset(L, LUA_REGISTRYINDEX);
128135
/* }}} */
129136

137+
/* {{{downstream userdata metatable */
138+
lua_pushlightuserdata(L, &ngx_stream_lua_downstream_udata_metatable_key);
139+
lua_createtable(L, 0 /* narr */, 1 /* nrec */); /* metatable */
140+
lua_pushcfunction(L, ngx_stream_lua_socket_udp_downstream_destroy);
141+
lua_setfield(L, -2, "__gc");
142+
lua_rawset(L, LUA_REGISTRYINDEX);
143+
/* }}} */
144+
145+
#if 0
146+
/* {{{udp req socket object metatable */
147+
lua_pushlightuserdata(L, &ngx_stream_lua_req_socket_metatable_key);
148+
lua_createtable(L, 0 /* narr */, 3 /* nrec */);
149+
150+
lua_pushcfunction(L, ngx_stream_lua_socket_udp_receive);
151+
lua_setfield(L, -2, "receive");
152+
153+
lua_pushcfunction(L, ngx_stream_lua_socket_udp_settimeout);
154+
lua_setfield(L, -2, "settimeout"); /* ngx socket mt */
155+
156+
lua_pushvalue(L, -1);
157+
lua_setfield(L, -2, "__index");
158+
159+
lua_rawset(L, LUA_REGISTRYINDEX);
160+
/* }}} */
161+
#endif
162+
163+
/* {{{raw udp req socket object metatable */
164+
lua_pushlightuserdata(L, &ngx_stream_lua_raw_req_socket_metatable_key);
165+
lua_createtable(L, 0 /* narr */, 4 /* nrec */);
166+
167+
lua_pushcfunction(L, ngx_stream_lua_socket_udp_receive);
168+
lua_setfield(L, -2, "receive");
169+
170+
lua_pushcfunction(L, ngx_stream_lua_socket_udp_send);
171+
lua_setfield(L, -2, "send");
172+
173+
lua_pushcfunction(L, ngx_stream_lua_socket_udp_settimeout);
174+
lua_setfield(L, -2, "settimeout"); /* ngx socket mt */
175+
176+
lua_pushvalue(L, -1);
177+
lua_setfield(L, -2, "__index");
178+
lua_rawset(L, LUA_REGISTRYINDEX);
179+
/* }}} */
180+
130181
lua_pop(L, 1);
131182
}
132183

133184

185+
void
186+
ngx_stream_lua_inject_udp_req_socket_api(lua_State *L)
187+
{
188+
lua_pushcfunction(L, ngx_stream_lua_udp_req_socket);
189+
lua_setfield(L, -2, "udp_socket");
190+
}
191+
192+
193+
static int
194+
ngx_stream_lua_udp_req_socket(lua_State *L)
195+
{
196+
int n, raw;
197+
ngx_stream_session_t *s;
198+
ngx_stream_lua_udp_connection_t *pc;
199+
ngx_stream_lua_srv_conf_t *lscf;
200+
ngx_connection_t *c;
201+
ngx_stream_lua_ctx_t *ctx;
202+
ngx_stream_lua_co_ctx_t *coctx;
203+
ngx_stream_lua_cleanup_t *cln;
204+
205+
ngx_stream_lua_socket_udp_upstream_t *u;
206+
207+
n = lua_gettop(L);
208+
if (n == 0) {
209+
raw = 0;
210+
211+
} else if (n == 1) {
212+
raw = lua_toboolean(L, 1);
213+
lua_pop(L, 1);
214+
215+
} else {
216+
return luaL_error(L, "expecting zero arguments, but got %d",
217+
lua_gettop(L));
218+
}
219+
220+
s = ngx_stream_lua_get_session(L);
221+
222+
ctx = ngx_stream_get_module_ctx(s, ngx_stream_lua_module);
223+
if (ctx == NULL) {
224+
return luaL_error(L, "no ctx found");
225+
}
226+
227+
ngx_stream_lua_check_context(L, ctx, NGX_STREAM_LUA_CONTEXT_CONTENT);
228+
229+
c = s->connection;
230+
231+
if (c->type != SOCK_DGRAM) {
232+
return luaL_error(L, "socket api does not match connection transport",
233+
lua_gettop(L));
234+
}
235+
236+
#if !defined(nginx_version) || nginx_version < 1003013
237+
lua_pushnil(L);
238+
lua_pushliteral(L, "nginx version too old");
239+
return 2;
240+
#else
241+
if (ctx->downstream_busy_bufs) {
242+
lua_pushnil(L);
243+
lua_pushliteral(L, "pending data to write");
244+
return 2;
245+
}
246+
247+
dd("ctx acquired raw req socket: %d", ctx->acquired_raw_req_socket);
248+
249+
if (ctx->acquired_raw_req_socket) {
250+
lua_pushnil(L);
251+
lua_pushliteral(L, "duplicate call");
252+
return 2;
253+
}
254+
255+
ctx->acquired_raw_req_socket = 1;
256+
#endif
257+
258+
lua_createtable(L, 3 /* narr */, 1 /* nrec */); /* the object */
259+
260+
lua_pushlightuserdata(L, &ngx_stream_lua_raw_req_socket_metatable_key);
261+
262+
lua_rawget(L, LUA_REGISTRYINDEX);
263+
lua_setmetatable(L, -2);
264+
265+
u = lua_newuserdata(L, sizeof(ngx_stream_lua_socket_udp_upstream_t));
266+
if (u == NULL) {
267+
return luaL_error(L, "no memory");
268+
}
269+
270+
#if 1
271+
lua_pushlightuserdata(L, &ngx_stream_lua_downstream_udata_metatable_key);
272+
lua_rawget(L, LUA_REGISTRYINDEX);
273+
lua_setmetatable(L, -2);
274+
#endif
275+
276+
lua_rawseti(L, 1, SOCKET_CTX_INDEX);
277+
278+
ngx_memzero(u, sizeof(ngx_stream_lua_socket_udp_upstream_t));
279+
280+
u->raw_downstream = 1;
281+
282+
coctx = ctx->cur_co_ctx;
283+
284+
u->session = s;
285+
286+
lscf = ngx_stream_get_module_srv_conf(s, ngx_stream_lua_module);
287+
288+
u->conf = lscf;
289+
290+
u->read_timeout = u->conf->read_timeout;
291+
292+
cln = ngx_stream_lua_cleanup_add(s, 0);
293+
if (cln == NULL) {
294+
u->ft_type |= NGX_STREAM_LUA_SOCKET_FT_ERROR;
295+
lua_pushnil(L);
296+
lua_pushliteral(L, "no memory");
297+
return 2;
298+
}
299+
300+
cln->handler = ngx_stream_lua_socket_udp_cleanup;
301+
cln->data = u;
302+
303+
u->cleanup = &cln->handler;
304+
305+
pc = &u->udp_connection;
306+
pc->log = *c->log;
307+
pc->connection = c;
308+
309+
dd("setting data to %p", u);
310+
311+
coctx->data = u;
312+
ctx->downstream = u;
313+
314+
if (c->read->timer_set) {
315+
ngx_del_timer(c->read);
316+
}
317+
318+
if (raw) {
319+
if (c->write->timer_set) {
320+
ngx_del_timer(c->write);
321+
}
322+
}
323+
324+
lua_settop(L, 1);
325+
return 1;
326+
}
327+
328+
134329
static int
135330
ngx_stream_lua_socket_udp(lua_State *L)
136331
{
@@ -321,7 +516,7 @@ ngx_stream_lua_socket_udp_setpeername(lua_State *L)
321516
}
322517

323518
#if 1
324-
lua_pushlightuserdata(L, &ngx_stream_lua_udp_udata_metatable_key);
519+
lua_pushlightuserdata(L, &ngx_stream_lua_upstream_udata_metatable_key);
325520
lua_rawget(L, LUA_REGISTRYINDEX);
326521
lua_setmetatable(L, -2);
327522
#endif
@@ -944,7 +1139,7 @@ ngx_stream_lua_socket_udp_send(lua_State *L)
9441139

9451140
dd("sending query %.*s", (int) query.len, query.data);
9461141

947-
n = ngx_send(u->udp_connection.connection, query.data, query.len);
1142+
n = ngx_udp_send(u->udp_connection.connection, query.data, query.len);
9481143

9491144
dd("ngx_send returns %d (query len %d)", (int) n, (int) query.len);
9501145

@@ -973,6 +1168,7 @@ ngx_stream_lua_socket_udp_receive(lua_State *L)
9731168
{
9741169
ngx_stream_session_t *s;
9751170
ngx_stream_lua_socket_udp_upstream_t *u;
1171+
ngx_connection_t *c;
9761172
ngx_int_t rc;
9771173
ngx_stream_lua_ctx_t *ctx;
9781174
ngx_stream_lua_co_ctx_t *coctx;
@@ -981,8 +1177,8 @@ ngx_stream_lua_socket_udp_receive(lua_State *L)
9811177
ngx_stream_lua_srv_conf_t *lscf;
9821178

9831179
nargs = lua_gettop(L);
984-
if (nargs != 1 && nargs != 2) {
985-
return luaL_error(L, "expecting 1 or 2 arguments "
1180+
if (nargs != 1) {
1181+
return luaL_error(L, "expecting 1 arguments "
9861182
"(including the object), but got %d", nargs);
9871183
}
9881184

@@ -1042,7 +1238,19 @@ ngx_stream_lua_socket_udp_receive(lua_State *L)
10421238
"stream lua udp socket receive buffer size: %uz",
10431239
u->recv_buf_size);
10441240

1045-
rc = ngx_stream_lua_socket_udp_read(s, u);
1241+
c = u->udp_connection.connection;
1242+
1243+
if (u->raw_downstream && !u->connected) {
1244+
u->received = c->buffer->last - c->buffer->pos;
1245+
c->buffer->pos = ngx_copy(ngx_stream_lua_socket_udp_buffer,
1246+
c->buffer->pos, u->received);
1247+
ngx_stream_lua_socket_udp_handle_success(s, u);
1248+
u->connected = 1;
1249+
rc = NGX_OK;
1250+
1251+
} else {
1252+
rc = ngx_stream_lua_socket_udp_read(s, u);
1253+
}
10461254

10471255
if (rc == NGX_ERROR) {
10481256
dd("read failed: %d", (int) u->ft_type);
@@ -1154,7 +1362,7 @@ ngx_stream_lua_socket_udp_finalize(ngx_stream_session_t *s,
11541362
u->resolved->ctx = NULL;
11551363
}
11561364

1157-
if (u->udp_connection.connection) {
1365+
if (u->udp_connection.connection && !u->raw_downstream) {
11581366
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
11591367
"stream lua close socket connection");
11601368

@@ -1188,6 +1396,27 @@ ngx_stream_lua_socket_udp_upstream_destroy(lua_State *L)
11881396
}
11891397

11901398

1399+
static int
1400+
ngx_stream_lua_socket_udp_downstream_destroy(lua_State *L)
1401+
{
1402+
ngx_stream_lua_socket_udp_upstream_t *u;
1403+
1404+
dd("downstream destory");
1405+
1406+
u = lua_touserdata(L, 1);
1407+
if (u == NULL) {
1408+
dd("u is NULL");
1409+
return 0;
1410+
}
1411+
1412+
if (u->cleanup) {
1413+
ngx_stream_lua_socket_udp_cleanup(u); /* it will clear u->cleanup */
1414+
}
1415+
1416+
return 0;
1417+
}
1418+
1419+
11911420
static void
11921421
ngx_stream_lua_socket_dummy_handler(ngx_stream_session_t *s,
11931422
ngx_stream_lua_socket_udp_upstream_t *u)

‎src/ngx_stream_lua_socket_udp.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,20 @@ struct ngx_stream_lua_socket_udp_upstream_s {
5050

5151
ngx_stream_lua_resolved_t *resolved;
5252

53-
ngx_uint_t ft_type;
54-
ngx_err_t socket_errno;
55-
size_t received; /* for receive */
56-
size_t recv_buf_size;
57-
58-
ngx_stream_lua_co_ctx_t *co_ctx;
59-
unsigned waiting; /* :1 */
53+
ngx_uint_t ft_type;
54+
ngx_err_t socket_errno;
55+
size_t received; /* for receive */
56+
size_t recv_buf_size;
57+
58+
ngx_stream_lua_co_ctx_t *co_ctx;
59+
unsigned raw_downstream:1;
60+
unsigned waiting:1;
61+
unsigned connected:1;
6062
};
6163

6264

6365
void ngx_stream_lua_inject_socket_udp_api(ngx_log_t *log, lua_State *L);
66+
void ngx_stream_lua_inject_udp_req_socket_api(lua_State *L);
6467

6568

6669
#endif /* _NGX_STREAM_LUA_SOCKET_UDP_H_INCLUDED_ */

‎src/ngx_stream_lua_util.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3227,9 +3227,9 @@ ngx_stream_lua_inject_req_api(ngx_log_t *log, lua_State *L)
32273227
{
32283228
/* ngx.req table */
32293229

3230-
lua_createtable(L, 0 /* narr */, 1 /* nrec */); /* .req */
3231-
3232-
ngx_stream_lua_inject_req_socket_api(L);
3230+
lua_createtable(L, 0 /* narr */, 2 /* nrec */); /* .req */
3231+
ngx_stream_lua_inject_tcp_req_socket_api(L);
3232+
ngx_stream_lua_inject_udp_req_socket_api(L);
32333233

32343234
lua_setfield(L, -2, "req");
32353235
}

‎t/062-count.t

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ ngx: 57
4646
ngx.say("n = ", n)
4747
}
4848
--- stream_response
49-
n = 1
49+
n = 2
5050
--- no_error_log
5151
[error]
5252

‎t/137-udp-count.t

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# vim:set ft= ts=4 sw=4 et fdm=marker:
2+
use Test::Nginx::Socket::Lua::Dgram;
3+
4+
#worker_connections(1014);
5+
#master_on();
6+
#workers(4);
7+
#log_level('warn');
8+
no_root_location();
9+
10+
#repeat_each(2);
11+
12+
plan tests => repeat_each() * (blocks() * 3);
13+
14+
our $HtmlDir = html_dir;
15+
16+
#$ENV{LUA_CPATH} = "/usr/local/openresty/lualib/?.so;" . $ENV{LUA_CPATH};
17+
18+
no_long_string();
19+
run_tests();
20+
21+
__DATA__
22+
23+
24+
=== TEST 1: entries under ngx._udp_meta
25+
--- dgram_server_config
26+
content_by_lua_block {
27+
local n = 0
28+
for k, v in pairs(getmetatable(ngx.socket.udp())) do
29+
print("key:", k)
30+
n = n + 1
31+
end
32+
33+
local sock, err = ngx.req.udp_socket()
34+
if not sock then
35+
ngx.log(ngx.ERR, "failed to get the request socket: ", err)
36+
return ngx.exit(ngx.ERROR)
37+
end
38+
39+
assert(sock:send("n = " .. n))
40+
}
41+
42+
--- dgram_response chomp
43+
n = 6
44+
--- no_error_log
45+
[error]
46+
47+
48+
49+
=== TEST 2: entries under the metatable of req sockets
50+
--- dgram_server_config
51+
content_by_lua_block {
52+
local n = 0
53+
local sock, err = ngx.req.udp_socket()
54+
if not sock then
55+
ngx.log(ngx.ERR, "failed to get the request socket: ", err)
56+
return ngx.exit(ngx.ERROR)
57+
end
58+
59+
for k, v in pairs(getmetatable(sock)) do
60+
print("key: ", k)
61+
n = n + 1
62+
end
63+
64+
assert(sock:send("n = " .. n))
65+
}
66+
67+
--- dgram_response chomp
68+
n = 4
69+
--- no_error_log
70+
[error]

‎t/138-req-udp-socket.t

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# vim:set ft= ts=4 sw=4 et fdm=marker:
2+
3+
use Test::Nginx::Socket::Lua::Dgram;
4+
5+
repeat_each(2);
6+
7+
plan tests => repeat_each() * (blocks() * 3);
8+
9+
our $HtmlDir = html_dir;
10+
11+
#$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
12+
13+
no_long_string();
14+
#no_diff();
15+
#log_level 'warn';
16+
no_shuffle();
17+
18+
run_tests();
19+
20+
__DATA__
21+
22+
=== TEST 1: sanity
23+
--- dgram_server_config
24+
content_by_lua_block {
25+
local sock, err = ngx.req.udp_socket()
26+
if not sock then
27+
ngx.log(ngx.ERR, "failed to get the request socket: ", err)
28+
return ngx.exit(ngx.ERROR)
29+
end
30+
31+
local data, err = sock:receive()
32+
if not data then
33+
ngx.log(ngx.ERR, "failed to receive: ", err)
34+
return ngx.exit(ngx.ERROR)
35+
end
36+
37+
local ok, err = sock:send("received: " .. data)
38+
if not ok then
39+
ngx.log(ngx.ERR, "failed to send: ", err)
40+
return ngx.exit(ngx.ERROR)
41+
end
42+
}
43+
44+
--- dgram_request
45+
hello world! my
46+
--- dgram_response
47+
received: hello world! my
48+
--- no_error_log
49+
[error]
50+
51+
52+
=== TEST 2: ngx.say not supported
53+
--- dgram_server_config
54+
content_by_lua_block {
55+
local sock, err = ngx.req.udp_socket()
56+
sock:send("")
57+
ngx.say("something")
58+
}
59+
60+
--- dgram_response
61+
--- error_log
62+
not supported in udp requests
63+
64+
65+
66+
=== TEST 3: ngx.print not supported
67+
--- dgram_server_config
68+
content_by_lua_block {
69+
local sock, err = ngx.req.udp_socket()
70+
sock:send("")
71+
ngx.print("something")
72+
}
73+
74+
--- dgram_response
75+
--- error_log
76+
not supported in udp requests
77+
78+
79+
80+
=== TEST 4: ngx.eof after ngx.req.udp_socket(true)
81+
--- dgram_server_config
82+
content_by_lua_block {
83+
local sock, err = ngx.req.udp_socket(true)
84+
if not sock then
85+
ngx.log(ngx.ERR, "failed to get raw request socket: ", err)
86+
return ngx.exit(ngx.ERROR)
87+
end
88+
assert(sock:send(""))
89+
ngx.eof()
90+
}
91+
92+
--- config
93+
server_tokens off;
94+
95+
--- dgram_response
96+
--- error_log
97+
not supported in udp requests
98+
99+
100+
101+
=== TEST 5: ngx.flush after ngx.udp_req.socket(true)
102+
--- dgram_server_config
103+
content_by_lua_block {
104+
local sock, err = ngx.req.udp_socket(true)
105+
if not sock then
106+
ngx.log(ngx.ERR, "failed to get raw request socket: ", err)
107+
return ngx.exit(ngx.ERROR)
108+
end
109+
assert(sock:send(""))
110+
ngx.flush()
111+
}
112+
113+
--- dgram_response
114+
--- error_log
115+
not supported in udp requests
116+
117+
118+
119+
=== TEST 6: receive (bad arg number)
120+
--- dgram_server_config
121+
content_by_lua_block {
122+
local sock, err = ngx.req.udp_socket()
123+
sock:send("")
124+
sock:receive(5)
125+
}
126+
127+
--- dgram_response
128+
--- error_log
129+
expecting 1 arguments (including the object), but got 2
130+
131+
132+
133+
=== TEST 7: failing reread after reading timeout happens
134+
--- SKIP
135+
--- dgram_server_config
136+
content_by_lua_block {
137+
local sock, err = ngx.req.udp_socket()
138+
if not sock then
139+
ngx.log(ngx.ERR, "failed to get the request socket: ", err)
140+
return ngx.exit(ngx.ERROR)
141+
end
142+
143+
local data, err = sock:receive() -- trigger_dgram_req
144+
145+
sock:settimeout(100)
146+
data, err = sock:receive()
147+
if err then
148+
sock:send("err: ", err)
149+
end
150+
}
151+
152+
--- dgram_response chomp
153+
err: timeout
154+
--- error_log
155+
stream lua udp socket read timed out
156+
157+
158+
159+
=== TEST 8: req socket GC'd
160+
--- dgram_server_config
161+
content_by_lua_block {
162+
do
163+
local sock, err = ngx.req.udp_socket()
164+
if not sock then
165+
ngx.log(ngx.ERR, "failed to get the request socket: ", err)
166+
return ngx.exit(ngx.ERROR)
167+
end
168+
169+
assert(sock:send("done"))
170+
end
171+
collectgarbage()
172+
ngx.log(ngx.WARN, "GC cycle done")
173+
}
174+
175+
--- dgram_response chomp
176+
done
177+
--- no_error_log
178+
[error]
179+
--- grep_error_log_out
180+
stream lua finalize socket
181+
GC cycle done

‎t/139-bad-udp-sock-self.t

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# vim:set ft= ts=4 sw=4 et fdm=marker:
2+
3+
use Test::Nginx::Socket::Lua::Dgram;
4+
repeat_each(2);
5+
6+
plan tests => repeat_each() * (blocks() * 3);
7+
8+
our $HtmlDir = html_dir;
9+
10+
#$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
11+
12+
no_long_string();
13+
#no_diff();
14+
#log_level 'warn';
15+
16+
run_tests();
17+
18+
__DATA__
19+
20+
=== TEST 1: receive
21+
--- dgram_server_config
22+
content_by_lua_block {
23+
local sock, err = ngx.req.udp_socket()
24+
sock:send("")
25+
sock.receive("l")
26+
}
27+
28+
--- dgram_response
29+
--- error_log
30+
bad argument #1 to 'receive' (table expected, got string)
31+
32+
33+
34+
=== TEST 2: send (bad arg number)
35+
--- dgram_server_config
36+
content_by_lua_block {
37+
local sock, err = ngx.req.udp_socket()
38+
sock:send("")
39+
sock.send("hello")
40+
}
41+
42+
--- dgram_response
43+
--- error_log
44+
expecting 2 arguments (including the object), but got 1
45+
46+
47+
48+
=== TEST 3: send (bad self)
49+
--- dgram_server_config
50+
content_by_lua_block {
51+
local sock, err = ngx.req.udp_socket()
52+
sock:send("")
53+
sock.send("hello", 32)
54+
}
55+
56+
--- dgram_response
57+
--- error_log
58+
bad argument #1 to 'send' (table expected, got string)

‎t/140-raw-req-udp-socket.t

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
# vim:set ft= ts=4 sw=4 et fdm=marker:
2+
3+
use Test::Nginx::Socket::Lua::Dgram;
4+
5+
repeat_each(2);
6+
7+
plan tests => repeat_each() * (blocks() * 3);
8+
9+
#plan tests => repeat_each() * 43;
10+
11+
our $HtmlDir = html_dir;
12+
13+
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
14+
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
15+
16+
#log_level 'warn';
17+
log_level 'debug';
18+
19+
no_long_string();
20+
#no_diff();
21+
run_tests();
22+
23+
__DATA__
24+
25+
=== TEST 1: sanity
26+
--- dgram_server_config
27+
content_by_lua_block {
28+
local sock, err = ngx.req.udp_socket(true)
29+
if not sock then
30+
ngx.log(ngx.ERR, "failed to get the request socket: ", err)
31+
return ngx.exit(ngx.ERROR)
32+
end
33+
34+
local data, err = sock:receive()
35+
if not data then
36+
ngx.log(ngx.ERR, "failed to receive: ", err)
37+
return ngx.exit(ngx.ERROR)
38+
end
39+
40+
local ok, err = sock:send("received: " .. data)
41+
if not ok then
42+
ngx.log(ngx.ERR, "failed to send: ", err)
43+
return ngx.exit(ngx.ERROR)
44+
end
45+
}
46+
47+
--- dgram_request
48+
hello
49+
--- dgram_response
50+
received: hello
51+
--- no_error_log
52+
[error]
53+
54+
55+
56+
=== TEST 2: multiple raw req sockets
57+
--- dgram_server_config
58+
content_by_lua_block {
59+
local sock, err = ngx.req.udp_socket(true)
60+
if not sock then
61+
ngx.log(ngx.ERR, "failed to get raw request socket: ", err)
62+
return ngx.exit(ngx.ERROR)
63+
end
64+
assert(sock:send(""))
65+
66+
local sock2, err = ngx.req.udp_socket(true)
67+
if not sock2 then
68+
ngx.log(ngx.ERR, "failed to get raw request socket: ", err)
69+
return ngx.exit(ngx.ERROR)
70+
end
71+
}
72+
73+
--- stap2
74+
F(ngx_dgram_header_filter) {
75+
println("header filter")
76+
}
77+
F(ngx_dgram_lua_req_socket) {
78+
println("lua req socket")
79+
}
80+
--- dgram_response
81+
--- error_log
82+
failed to get raw request socket: duplicate call
83+
84+
85+
86+
=== TEST 3: sock:send after ngx.req.udp_socket(true)
87+
--- dgram_server_config
88+
content_by_lua_block {
89+
local sock, err = ngx.req.udp_socket(true)
90+
if not sock then
91+
ngx.log(ngx.ERR, "failed to get raw request socket: ", err)
92+
return ngx.exit(ngx.ERROR)
93+
end
94+
95+
local ok, err = sock:send("ok")
96+
if not ok then
97+
ngx.log(ngx.ERR, "failed to send: ", err)
98+
return ngx.exit(ngx.ERROR)
99+
end
100+
}
101+
102+
--- dgram_response chomp
103+
ok
104+
--- no_error_log
105+
[error]
106+
107+
108+
109+
=== TEST 4: receive timeout
110+
--- SKIP
111+
--- dgram_server_config
112+
content_by_lua_block {
113+
local sock, err = ngx.req.udp_socket(true)
114+
if not sock then
115+
ngx.log(ngx.ERR, "failed to get raw request socket: ", err)
116+
return ngx.exit(ngx.ERROR)
117+
end
118+
119+
local data, err = sock:receive() -- trigger_dgram_req
120+
121+
sock:settimeout(100)
122+
data, err = sock:receive()
123+
if err then
124+
sock:send("err: ", err)
125+
end
126+
}
127+
128+
--- dgram_response chomp
129+
err: timeout
130+
--- error_log
131+
stream lua udp socket read timed out
132+
133+
134+
135+
=== TEST 5: on_abort called during ngx.sleep()
136+
--- dgram_server_config
137+
lua_check_client_abort on;
138+
139+
content_by_lua_block {
140+
local ok, err = ngx.on_abort(function (premature) ngx.log(ngx.WARN, "mysock handler aborted") end)
141+
if not ok then
142+
ngx.log(ngx.ERR, "failed to set on_abort handler: ", err)
143+
return
144+
end
145+
146+
local sock, err = ngx.req.udp_socket(true)
147+
if not sock then
148+
ngx.log(ngx.ERR, "failed to get raw request socket: ", err)
149+
return ngx.exit(ngx.ERROR)
150+
end
151+
152+
local data, err = sock:receive()
153+
if not data then
154+
ngx.log(ngx.ERR, "server: failed to receive: ", err)
155+
return ngx.exit(ngx.ERROR)
156+
end
157+
158+
print("msg received: ", data)
159+
160+
local bytes, err = sock:send("1: received: " .. data .. "\n")
161+
if not bytes then
162+
ngx.log(ngx.ERR, "server: failed to send: ", err)
163+
return ngx.exit(ngx.ERROR)
164+
end
165+
166+
ngx.sleep(1)
167+
}
168+
169+
--- dgram_request
170+
hello
171+
--- dgram_response
172+
receive stream response error: timeout
173+
--- abort
174+
--- timeout: 0.2
175+
--- warn_log
176+
mysock handler aborted
177+
--- no_error_log
178+
[error]
179+
--- wait: 1.1
180+
181+
182+
183+
=== TEST 6: on_abort called during sock:receive()
184+
--- dgram_server_config
185+
lua_check_client_abort on;
186+
187+
content_by_lua_block {
188+
local ok, err = ngx.on_abort(function (premature) ngx.log(ngx.WARN, "mysock handler aborted") end)
189+
if not ok then
190+
ngx.log(ngx.ERR, "failed to set on_abort handler: ", err)
191+
return
192+
end
193+
194+
195+
local sock, err = ngx.req.udp_socket(true)
196+
if not sock then
197+
ngx.log(ngx.ERR, "failed to get raw request socket: ", err)
198+
return ngx.exit(ngx.ERROR)
199+
end
200+
201+
local data, err = sock:receive()
202+
if not data then
203+
ngx.log(ngx.ERR, "server: failed to receive: ", err)
204+
return ngx.exit(ngx.ERROR)
205+
end
206+
207+
print("msg received: ", data)
208+
209+
local bytes, err = sock:send("1: received: " .. data .. "\n")
210+
if not bytes then
211+
ngx.log(ngx.ERR, "server: failed to send: ", err)
212+
return ngx.exit(ngx.ERROR)
213+
end
214+
215+
local data, err = sock:receive()
216+
if not data then
217+
ngx.log(ngx.WARN, "failed to receive a line: ", err)
218+
return
219+
end
220+
}
221+
222+
--- dgram_response
223+
receive stream response error: timeout
224+
--- timeout: 0.2
225+
--- abort
226+
--- warn_log
227+
mysock handler aborted
228+
--- no_error_log
229+
[error]
230+
--- wait: 0.1
231+
232+
233+
234+
=== TEST 7: request body not read yet
235+
--- dgram_server_config
236+
content_by_lua_block {
237+
local sock, err = ngx.req.udp_socket(true)
238+
if not sock then
239+
ngx.log(ngx.ERR, "failed to get raw request socket: ", err)
240+
return ngx.exit(ngx.ERROR)
241+
end
242+
243+
local data, err = sock:receive()
244+
if not data then
245+
ngx.log(ngx.ERR, "server: failed to receive: ", err)
246+
return ngx.exit(ngx.ERROR)
247+
end
248+
249+
local ok, err = sock:send("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n" .. data)
250+
if not ok then
251+
ngx.log(ngx.ERR, "failed to send: ", err)
252+
return ngx.exit(ngx.ERROR)
253+
end
254+
}
255+
256+
--- dgram_request chomp
257+
hello
258+
--- dgram_response eval
259+
"HTTP/1.1 200 OK\r
260+
Content-Length: 5\r
261+
\r
262+
hello"
263+
264+
--- no_error_log
265+
[error]

0 commit comments

Comments
 (0)
Please sign in to comment.