Skip to content

Commit b81a279

Browse files
committed
feature(socket.tcp): enhance the logic of parameter verification in
connect
1 parent f6b486b commit b81a279

File tree

5 files changed

+272
-9
lines changed

5 files changed

+272
-9
lines changed

src/ngx_http_lua_socket_tcp.c

+30-3
Original file line numberDiff line numberDiff line change
@@ -970,8 +970,16 @@ ngx_http_lua_socket_tcp_connect(lua_State *L)
970970
n--;
971971
}
972972

973-
if (n == 3) {
974-
port = luaL_checkinteger(L, 3);
973+
/* most popular suit: host:port */
974+
if (n == 3 && lua_isnumber(L, 3)) {
975+
976+
/* Hit the following parameter combination:
977+
* sock:connect("127.0.0.1", port)
978+
* sock:connect("127.0.0.1", port, opts)
979+
* sock:connect("unix:/path", port)
980+
* sock:connect("unix:/path", port, opts) */
981+
982+
port = (int) lua_tointeger(L, 3);
975983

976984
if (port < 0 || port > 65535) {
977985
lua_pushnil(L);
@@ -987,8 +995,27 @@ ngx_http_lua_socket_tcp_connect(lua_State *L)
987995

988996
dd("socket key: %s", lua_tostring(L, -1));
989997

990-
} else { /* n == 2 */
998+
} else if (len >= 5 && ngx_strncasecmp(p, (u_char *) "unix:", 5) == 0) {
999+
1000+
/* Hit the following parameter combination:
1001+
* sock:connect("unix:/path")
1002+
* sock:connect("unix:/path", nil)
1003+
* sock:connect("unix:/path", opts)
1004+
* sock:connect("unix:/path", nil, opts) */
1005+
9911006
port = 0;
1007+
1008+
} else {
1009+
1010+
/* Ban the following parameter combination:
1011+
* sock:connect("127.0.0.1")
1012+
* sock:connect("127.0.0.1", nil)
1013+
* sock:connect("127.0.0.1", opts)
1014+
* sock:connect("127.0.0.1", nil, opts) */
1015+
1016+
lua_pushnil(L);
1017+
lua_pushfstring(L, "missing the port number");
1018+
return 2;
9921019
}
9931020

9941021
if (!custom_pool) {

t/023-rewrite/unix-socket.t

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ qr{\[crit\] .*? connect\(\) to unix:/tmp/nosuchfile\.sock failed}
7979
--- request
8080
GET /test
8181
--- response_body
82-
failed to connect: failed to parse host name "/tmp/test-nginx.sock": invalid host
82+
failed to connect: missing the port number
8383

8484

8585

t/058-tcp-socket.t

+43-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use Test::Nginx::Socket::Lua;
44

55
repeat_each(2);
66

7-
plan tests => repeat_each() * 228;
7+
plan tests => repeat_each() * 231;
88

99
our $HtmlDir = html_dir;
1010

@@ -3029,7 +3029,7 @@ qr/runtime error: content_by_lua\(nginx\.conf:\d+\):16: bad request/
30293029
--- user_files
30303030
>>> myfoo.lua
30313031
local sock = ngx.socket.tcp()
3032-
local ok, err = sock:connect("agentzh.org")
3032+
local ok, err = sock:connect("agentzh.org", 12345)
30333033
if not ok then
30343034
ngx.log(ngx.ERR, "failed to connect: ", err)
30353035
return
@@ -3059,7 +3059,7 @@ runtime error: attempt to yield across C-call boundary
30593059
end
30603060
local function err()
30613061
local sock = ngx.socket.tcp()
3062-
local ok, err = sock:connect("agentzh.org")
3062+
local ok, err = sock:connect("agentzh.org", 12345)
30633063
if not ok then
30643064
ngx.log(ngx.ERR, "failed to connect: ", err)
30653065
return
@@ -4327,3 +4327,43 @@ failed to receive a line: closed []
43274327
close: 1 nil
43284328
--- no_error_log
43294329
[error]
4330+
4331+
4332+
4333+
=== TEST 72: port is not number
4334+
--- config
4335+
server_tokens off;
4336+
location = /t {
4337+
set $port $TEST_NGINX_SERVER_PORT;
4338+
content_by_lua_block {
4339+
local sock = ngx.socket.tcp()
4340+
sock:settimeout(500)
4341+
4342+
local ok, err = sock:connect("127.0.0.1")
4343+
if not ok then
4344+
ngx.say("connect failed: ", err)
4345+
end
4346+
4347+
local ok, err = sock:connect("127.0.0.1", nil)
4348+
if not ok then
4349+
ngx.say("connect failed: ", err)
4350+
end
4351+
4352+
local ok, err = sock:connect("127.0.0.1", {})
4353+
if not ok then
4354+
ngx.say("connect failed: ", err)
4355+
end
4356+
4357+
ngx.say("finish")
4358+
}
4359+
}
4360+
4361+
--- request
4362+
GET /t
4363+
--- response_body
4364+
connect failed: missing the port number
4365+
connect failed: missing the port number
4366+
connect failed: missing the port number
4367+
finish
4368+
--- no_error_log
4369+
[error]

t/059-unix-socket.t

+137-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ qr{\[crit\] .*? connect\(\) to unix:/tmp/nosuchfile\.sock failed}
6464
--- request
6565
GET /test
6666
--- response_body
67-
failed to connect: failed to parse host name "/tmp/test-nginx.sock": invalid host
67+
failed to connect: missing the port number
6868
6969
7070
@@ -201,3 +201,139 @@ received:
201201
received: foo
202202
failed to receive a line: closed
203203
close: 1 nil
204+
205+
206+
207+
=== TEST 5: port will be ignored
208+
--- http_config
209+
server {
210+
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock;
211+
default_type 'text/plain';
212+
213+
server_tokens off;
214+
location /foo {
215+
content_by_lua 'ngx.say("foo")';
216+
more_clear_headers Date;
217+
}
218+
}
219+
--- config
220+
location /test {
221+
content_by_lua '
222+
local sock = ngx.socket.tcp()
223+
local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock", 80)
224+
if not ok then
225+
ngx.say("failed to connect: ", err)
226+
return
227+
end
228+
229+
ngx.say("connected: ", ok)
230+
231+
local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
232+
-- req = "OK"
233+
234+
local bytes, err = sock:send(req)
235+
if not bytes then
236+
ngx.say("failed to send request: ", err)
237+
return
238+
end
239+
240+
ngx.say("request sent: ", bytes)
241+
242+
while true do
243+
print("calling receive")
244+
local line, err = sock:receive()
245+
if line then
246+
ngx.say("received: ", line)
247+
248+
else
249+
ngx.say("failed to receive a line: ", err)
250+
break
251+
end
252+
end
253+
254+
ok, err = sock:close()
255+
ngx.say("close: ", ok, " ", err)
256+
';
257+
}
258+
--- request
259+
GET /test
260+
--- response_body
261+
connected: 1
262+
request sent: 57
263+
received: HTTP/1.1 200 OK
264+
received: Server: nginx
265+
received: Content-Type: text/plain
266+
received: Content-Length: 4
267+
received: Connection: close
268+
received:
269+
received: foo
270+
failed to receive a line: closed
271+
close: 1 nil
272+
273+
274+
275+
=== TEST 6: second parameter is nil
276+
--- http_config
277+
server {
278+
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock;
279+
default_type 'text/plain';
280+
281+
server_tokens off;
282+
location /foo {
283+
content_by_lua 'ngx.say("foo")';
284+
more_clear_headers Date;
285+
}
286+
}
287+
--- config
288+
location /test {
289+
content_by_lua '
290+
local sock = ngx.socket.tcp()
291+
local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock", nil)
292+
if not ok then
293+
ngx.say("failed to connect: ", err)
294+
return
295+
end
296+
297+
ngx.say("connected: ", ok)
298+
299+
local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
300+
-- req = "OK"
301+
302+
local bytes, err = sock:send(req)
303+
if not bytes then
304+
ngx.say("failed to send request: ", err)
305+
return
306+
end
307+
308+
ngx.say("request sent: ", bytes)
309+
310+
while true do
311+
print("calling receive")
312+
local line, err = sock:receive()
313+
if line then
314+
ngx.say("received: ", line)
315+
316+
else
317+
ngx.say("failed to receive a line: ", err)
318+
break
319+
end
320+
end
321+
322+
ok, err = sock:close()
323+
ngx.say("close: ", ok, " ", err)
324+
';
325+
}
326+
--- request
327+
GET /test
328+
--- response_body
329+
connected: 1
330+
request sent: 57
331+
received: HTTP/1.1 200 OK
332+
received: Server: nginx
333+
received: Content-Type: text/plain
334+
received: Content-Length: 4
335+
received: Connection: close
336+
received:
337+
received: foo
338+
failed to receive a line: closed
339+
close: 1 nil

t/068-socket-keepalive.t

+61-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use Test::Nginx::Socket::Lua;
44

55
#repeat_each(2);
66

7-
plan tests => repeat_each() * (blocks() * 4 + 31);
7+
plan tests => repeat_each() * (blocks() * 4 + 34);
88

99
our $HtmlDir = html_dir;
1010

@@ -2956,3 +2956,63 @@ GET /t
29562956
lua tcp socket abort queueing
29572957
--- response_body
29582958
ok
2959+
2960+
2961+
2962+
=== TEST 53: custom pools in third parameters for unix domain socket
2963+
--- http_config eval
2964+
"
2965+
lua_package_path '$::HtmlDir/?.lua;./?.lua;;';
2966+
server {
2967+
listen unix:$::HtmlDir/nginx.sock;
2968+
default_type 'text/plain';
2969+
2970+
server_tokens off;
2971+
location /foo {
2972+
echo foo;
2973+
more_clear_headers Date;
2974+
}
2975+
}
2976+
"
2977+
--- config
2978+
location /t {
2979+
set $port $TEST_NGINX_MEMCACHED_PORT;
2980+
content_by_lua '
2981+
local test = require "test"
2982+
local path = "$TEST_NGINX_HTML_DIR/nginx.sock";
2983+
test.go(path, "A")
2984+
test.go(path, "B")
2985+
';
2986+
}
2987+
--- user_files
2988+
>>> test.lua
2989+
module("test", package.seeall)
2990+
2991+
function go(path, pool)
2992+
local sock = ngx.socket.tcp()
2993+
local ok, err = sock:connect("unix:" .. path, nil, {pool = pool})
2994+
if not ok then
2995+
ngx.say("failed to connect: ", err)
2996+
return
2997+
end
2998+
2999+
ngx.say("connected: ", ok, ", reused: ", sock:getreusedtimes())
3000+
3001+
local ok, err = sock:setkeepalive()
3002+
if not ok then
3003+
ngx.say("failed to set reusable: ", err)
3004+
end
3005+
end
3006+
--- request
3007+
GET /t
3008+
--- response_body
3009+
connected: 1, reused: 0
3010+
connected: 1, reused: 0
3011+
--- no_error_log eval
3012+
["[error]",
3013+
"lua tcp socket keepalive: free connection pool for ",
3014+
"lua tcp socket get keepalive peer: using connection"
3015+
]
3016+
--- error_log
3017+
lua tcp socket keepalive create connection pool for key "A"
3018+
lua tcp socket keepalive create connection pool for key "B"

0 commit comments

Comments
 (0)