Skip to content

Commit 0547c25

Browse files
feature: add sock:getfd().
1 parent bdba93c commit 0547c25

File tree

7 files changed

+249
-5
lines changed

7 files changed

+249
-5
lines changed

README.markdown

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3751,6 +3751,7 @@ Nginx API for Lua
37513751
* [ngx.socket.tcp](#ngxsockettcp)
37523752
* [tcpsock:bind](#tcpsockbind)
37533753
* [tcpsock:connect](#tcpsockconnect)
3754+
* [tcpsock:getfd](#getfd)
37543755
* [tcpsock:setclientcert](#tcpsocksetclientcert)
37553756
* [tcpsock:sslhandshake](#tcpsocksslhandshake)
37563757
* [tcpsock:send](#tcpsocksend)
@@ -8010,6 +8011,21 @@ This method was first introduced in the `v0.5.0rc1` release.
80108011

80118012
[Back to TOC](#nginx-api-for-lua)
80128013

8014+
8015+
tcpsock:getfd
8016+
--------------------
8017+
8018+
**syntax:** *fd, err = tcpsock:getfd()*
8019+
8020+
**context:** *rewrite_by_lua*, access_by_lua*, content_by_lua*, ngx.timer.*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_client_hello_by_lua**
8021+
8022+
Get the file describer of the current tcp socket.
8023+
8024+
This method was first introduced in the `v0.10.29` release.
8025+
8026+
[Back to TOC](#nginx-api-for-lua)
8027+
8028+
80138029
tcpsock:setclientcert
80148030
---------------------
80158031

src/ngx_http_lua_socket_tcp.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,10 @@ static char ngx_http_lua_pattern_udata_metatable_key;
227227

228228

229229
#define ngx_http_lua_tcp_socket_metatable_literal_key "__tcp_cosocket_mt"
230+
#define ngx_http_lua_tcp_req_socket_metatable_literal_key \
231+
"__tcp_req_cosocket_mt"
232+
#define ngx_http_lua_tcp_raw_req_socket_metatable_literal_key \
233+
"__tcp_raw_req_cosocket_mt"
230234

231235

232236
void
@@ -283,6 +287,12 @@ ngx_http_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L)
283287
lua_pushvalue(L, -1);
284288
lua_setfield(L, -2, "__index");
285289

290+
lua_rawset(L, LUA_REGISTRYINDEX);
291+
292+
lua_pushliteral(L, ngx_http_lua_tcp_req_socket_metatable_literal_key);
293+
lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask(
294+
req_socket_metatable_key));
295+
lua_rawget(L, LUA_REGISTRYINDEX);
286296
lua_rawset(L, LUA_REGISTRYINDEX);
287297
/* }}} */
288298

@@ -312,6 +322,12 @@ ngx_http_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L)
312322
lua_pushvalue(L, -1);
313323
lua_setfield(L, -2, "__index");
314324

325+
lua_rawset(L, LUA_REGISTRYINDEX);
326+
327+
lua_pushliteral(L, ngx_http_lua_tcp_raw_req_socket_metatable_literal_key);
328+
lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask(
329+
raw_req_socket_metatable_key));
330+
lua_rawget(L, LUA_REGISTRYINDEX);
315331
lua_rawset(L, LUA_REGISTRYINDEX);
316332
/* }}} */
317333

@@ -6684,6 +6700,28 @@ ngx_http_lua_ffi_socket_tcp_setoption(ngx_http_lua_socket_tcp_upstream_t *u,
66846700
}
66856701

66866702

6703+
int
6704+
ngx_http_lua_ffi_socket_tcp_getfd(ngx_http_request_t *r,
6705+
ngx_http_lua_socket_tcp_upstream_t *u, const char **errmsg)
6706+
{
6707+
int fd;
6708+
6709+
*errmsg = NULL;
6710+
6711+
if (u == NULL || u->peer.connection == NULL) {
6712+
*errmsg = "closed";
6713+
return -1;
6714+
}
6715+
6716+
fd = u->peer.connection->fd;
6717+
if (fd == -1) {
6718+
*errmsg = "faked connection";
6719+
}
6720+
6721+
return fd;
6722+
}
6723+
6724+
66876725
/* just hack the fd for testing bad case, it will also return the original fd */
66886726
int
66896727
ngx_http_lua_ffi_socket_tcp_hack_fd(ngx_http_lua_socket_tcp_upstream_t *u,

src/ngx_http_lua_socket_udp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1207,7 +1207,7 @@ ngx_http_lua_socket_udp_read(ngx_http_request_t *r,
12071207
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
12081208
"lua udp socket read data: waiting: %d", (int) u->waiting);
12091209

1210-
n = ngx_udp_recv(u->udp_connection.connection,
1210+
n = ngx_udp_recv(c,
12111211
ngx_http_lua_socket_udp_buffer, u->recv_buf_size);
12121212

12131213
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,

t/058-tcp-socket.t

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4563,3 +4563,79 @@ connected: 1
45634563
setkeepalive: 1
45644564
--- no_error_log
45654565
[error]
4566+
4567+
4568+
4569+
=== TEST 75: getfd()
4570+
--- no_http2
4571+
--- http_config
4572+
lua_package_path "../lua-resty-core/lib/?.lua;;";
4573+
--- config
4574+
server_tokens off;
4575+
location /t {
4576+
#set $port 5000;
4577+
set $port $TEST_NGINX_SERVER_PORT;
4578+
4579+
content_by_lua_block {
4580+
local sock = ngx.socket.tcp()
4581+
local port = ngx.var.port
4582+
local ok, err = sock:connect("127.0.0.1", port)
4583+
if not ok then
4584+
ngx.say("failed to connect: ", err)
4585+
return
4586+
end
4587+
4588+
local s, err = sock:getfd()
4589+
ngx.say("fd: ", s)
4590+
ngx.say("connected: ", ok)
4591+
4592+
local req = "GET /foo HTTP/1.0\r\nHost: localhost\r\nConnection: close\r\n\r\n"
4593+
-- req = "OK"
4594+
4595+
local bytes, err = sock:send(req)
4596+
if not bytes then
4597+
ngx.say("failed to send request: ", err)
4598+
return
4599+
end
4600+
4601+
ngx.say("request sent: ", bytes)
4602+
4603+
while true do
4604+
local line, err, part = sock:receive()
4605+
if line then
4606+
ngx.say("received: ", line)
4607+
4608+
else
4609+
ngx.say("failed to receive a line: ", err, " [", part, "]")
4610+
break
4611+
end
4612+
end
4613+
4614+
ok, err = sock:close()
4615+
ngx.say("close: ", ok, " ", err)
4616+
}
4617+
}
4618+
4619+
location /foo {
4620+
content_by_lua 'ngx.say("foo")';
4621+
more_clear_headers Date;
4622+
}
4623+
4624+
--- request
4625+
GET /t
4626+
--- response_body eval
4627+
qr/fd: \d+
4628+
connected: 1
4629+
request sent: 57
4630+
received: HTTP\/1.1 200 OK
4631+
received: Server: nginx
4632+
received: Content-Type: text\/plain
4633+
received: Content-Length: 4
4634+
received: Connection: close
4635+
received:
4636+
received: foo
4637+
failed to receive a line: closed \[\]
4638+
close: 1 nil
4639+
/ms
4640+
--- no_error_log
4641+
[error]

t/062-count.t

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ n = 10
259259
POST /test
260260
hello world
261261
--- response_body
262-
n = 6
262+
n = 7
263263
--- no_error_log
264264
[error]
265265
--- skip_eval: 3: $ENV{TEST_NGINX_USE_HTTP3}
@@ -460,7 +460,7 @@ worker: 5
460460
--- request
461461
GET /test
462462
--- response_body
463-
n = 16
463+
n = 17
464464
--- no_error_log
465465
[error]
466466

@@ -513,7 +513,7 @@ n = 7
513513
--- request
514514
GET /test
515515
--- response_body
516-
n = 7
516+
n = 8
517517
--- no_error_log
518518
[error]
519519
--- skip_eval: 3:$ENV{TEST_NGINX_USE_HTTP3}

t/067-req-socket.t

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,3 +1176,31 @@ GET /t
11761176
received: received: abc
11771177
--- no_error_log
11781178
[error]
1179+
1180+
1181+
1182+
=== TEST 19: getfd
1183+
--- http_config
1184+
lua_package_path "../lua-resty-core/lib/?.lua;;";
1185+
--- config
1186+
location /t {
1187+
content_by_lua_block {
1188+
local sock, err = ngx.req.socket()
1189+
if sock then
1190+
ngx.say("got the request socket")
1191+
else
1192+
ngx.say("failed to get the request socket: ", err)
1193+
end
1194+
1195+
ngx.say(sock:getfd())
1196+
}
1197+
}
1198+
--- request
1199+
POST /t
1200+
hello world
1201+
--- response_body eval
1202+
qr/\Agot the request socket
1203+
\d+
1204+
\z/ms
1205+
--- no_error_log
1206+
[error]

t/116-raw-req-socket.t

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use Test::Nginx::Socket::Lua $SkipReason ? (skip_all => $SkipReason) : ();
1212

1313
repeat_each(2);
1414

15-
plan tests => repeat_each() * 43;
15+
plan tests => repeat_each() * 46;
1616

1717
our $HtmlDir = html_dir;
1818

@@ -977,3 +977,89 @@ GET /t
977977
msg: 1: received: hello
978978
--- no_error_log
979979
[error]
980+
981+
982+
983+
=== TEST 17: getfd()
984+
--- config
985+
server_tokens off;
986+
location = /t {
987+
#set $port 5000;
988+
set $port $TEST_NGINX_SERVER_PORT;
989+
990+
content_by_lua_block {
991+
local sock = ngx.socket.tcp()
992+
local port = ngx.var.port
993+
local ok, err = sock:connect("127.0.0.1", port)
994+
if not ok then
995+
ngx.say("failed to connect: ", err)
996+
return
997+
end
998+
999+
local req = "GET /mysock HTTP/1.1\r\nUpgrade: mysock\r\nHost: localhost\r\nConnection: close\r\n\r\nhello"
1000+
-- req = "OK"
1001+
1002+
local bytes, err = sock:send(req)
1003+
if not bytes then
1004+
ngx.say("failed to send request: ", err)
1005+
return
1006+
end
1007+
1008+
local reader = sock:receiveuntil("\r\n\r\n")
1009+
local data, err, partial = reader()
1010+
if not data then
1011+
ngx.say("no response header found")
1012+
return
1013+
end
1014+
1015+
local msg, err = sock:receive()
1016+
if not msg then
1017+
ngx.say("failed to receive: ", err)
1018+
return
1019+
end
1020+
1021+
ngx.say("msg: ", msg)
1022+
1023+
ok, err = sock:close()
1024+
if not ok then
1025+
ngx.say("failed to close socket: ", err)
1026+
return
1027+
end
1028+
}
1029+
}
1030+
1031+
location = /mysock {
1032+
content_by_lua_block {
1033+
ngx.status = 101
1034+
ngx.send_headers()
1035+
ngx.flush(true)
1036+
ngx.req.read_body()
1037+
local sock, err = ngx.req.socket(true)
1038+
if not sock then
1039+
ngx.log(ngx.ERR, "server: failed to get raw req socket: ", err)
1040+
return
1041+
end
1042+
1043+
local s = sock:getfd()
1044+
local data, err = sock:receive(5)
1045+
if not data then
1046+
ngx.log(ngx.ERR, "server: failed to receive: ", err)
1047+
return
1048+
end
1049+
1050+
local bytes, err = sock:send("fd: " .. tostring(s) .. " 1: received: " .. data .. "\n")
1051+
if not bytes then
1052+
ngx.log(ngx.ERR, "server: failed to send: ", err)
1053+
return
1054+
end
1055+
}
1056+
more_clear_headers Date;
1057+
}
1058+
1059+
--- request
1060+
GET /t
1061+
--- response_body eval
1062+
qr/\Amsg: fd: \d+ 1: received: hello
1063+
/ms
1064+
--- no_error_log
1065+
[error]

0 commit comments

Comments
 (0)