# vim:set ft= ts=4 sw=4 et fdm=marker: use Test::Nginx::Socket::Lua; #repeat_each(2); plan tests => repeat_each() * (blocks() * 5 + 9); our $HtmlDir = html_dir; $ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211; $ENV{TEST_NGINX_HTML_DIR} = $HtmlDir; $ENV{TEST_NGINX_REDIS_PORT} ||= 6379; $ENV{LUA_PATH} ||= '/usr/local/openresty-debug/lualib/?.lua;/usr/local/openresty/lualib/?.lua;;'; no_long_string(); #no_diff(); #log_level 'warn'; log_level 'debug'; no_shuffle(); run_tests(); __DATA__ === TEST 1: sanity --- http_config eval "lua_package_path '$::HtmlDir/?.lua;./?.lua';" --- config location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua ' local test = require "test" local port = ngx.var.port test.go(port) test.go(port) '; } --- user_files >>> test.lua module("test", package.seeall) function go(port) local sock = ngx.socket.tcp() local ok, err = sock:connect("127.0.0.1", port) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok, ", reused: ", sock:getreusedtimes()) local req = "flush_all\r\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send request: ", err) return end ngx.say("request sent: ", bytes) local line, err, part = sock:receive() if line then ngx.say("received: ", line) else ngx.say("failed to receive a line: ", err, " [", part, "]") end local ok, err = sock:setkeepalive() if not ok then ngx.say("failed to set reusable: ", err) end end --- request GET /t --- response_body connected: 1, reused: 0 request sent: 11 received: OK connected: 1, reused: 1 request sent: 11 received: OK --- no_error_log eval ["[error]", "lua tcp socket keepalive: free connection pool for "] --- error_log eval qq{lua tcp socket get keepalive peer: using connection lua tcp socket keepalive create connection pool for key "127.0.0.1:$ENV{TEST_NGINX_MEMCACHED_PORT}" } === TEST 2: free up the whole connection pool if no active connections --- http_config eval "lua_package_path '$::HtmlDir/?.lua;./?.lua';" --- config location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua ' local test = require "test" local port = ngx.var.port test.go(port, true) test.go(port, false) '; } --- request GET /t --- user_files >>> test.lua module("test", package.seeall) function go(port, keepalive) local sock = ngx.socket.tcp() local ok, err = sock:connect("127.0.0.1", port) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok, ", reused: ", sock:getreusedtimes()) local req = "flush_all\r\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send request: ", err) return end ngx.say("request sent: ", bytes) local line, err, part = sock:receive() if line then ngx.say("received: ", line) else ngx.say("failed to receive a line: ", err, " [", part, "]") end if keepalive then local ok, err = sock:setkeepalive() if not ok then ngx.say("failed to set reusable: ", err) end else sock:close() end end --- response_body connected: 1, reused: 0 request sent: 11 received: OK connected: 1, reused: 1 request sent: 11 received: OK --- no_error_log [error] --- error_log eval ["lua tcp socket get keepalive peer: using connection", "lua tcp socket keepalive: free connection pool for "] === TEST 3: upstream sockets close prematurely --- http_config eval "lua_package_path '$::HtmlDir/?.lua;./?.lua';" --- config server_tokens off; keepalive_timeout 100ms; location /t { set $port $TEST_NGINX_SERVER_PORT; content_by_lua ' local port = ngx.var.port local sock = ngx.socket.tcp() local ok, err = sock:connect("127.0.0.1", port) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok) local req = "GET /foo HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: keepalive\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send request: ", err) return end ngx.say("request sent: ", bytes) local reader = sock:receiveuntil("\\r\\n0\\r\\n\\r\\n") local data, err = reader() if not data then ngx.say("failed to receive response body: ", err) return end ngx.say("received response of ", #data, " bytes") local ok, err = sock:setkeepalive() if not ok then ngx.say("failed to set reusable: ", err) end ngx.location.capture("/sleep") ngx.say("done") '; } location /foo { echo foo; } location /sleep { echo_sleep 1; } --- request GET /t --- response_body connected: 1 request sent: 61 received response of 156 bytes done --- no_error_log [error] --- error_log eval ["lua tcp socket keepalive close handler", "lua tcp socket keepalive: free connection pool for "] --- timeout: 3 === TEST 4: http keepalive --- http_config eval "lua_package_path '$::HtmlDir/?.lua;./?.lua';" --- config server_tokens off; location /t { keepalive_timeout 60s; set $port $TEST_NGINX_SERVER_PORT; content_by_lua ' local port = ngx.var.port local sock = ngx.socket.tcp() local ok, err = sock:connect("127.0.0.1", port) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok) local req = "GET /foo HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: keepalive\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send request: ", err) return end ngx.say("request sent: ", bytes) local reader = sock:receiveuntil("\\r\\n0\\r\\n\\r\\n") local data, err = reader() if not data then ngx.say("failed to receive response body: ", err) return end ngx.say("received response of ", #data, " bytes") local ok, err = sock:setkeepalive() if not ok then ngx.say("failed to set reusable: ", err) end ngx.location.capture("/sleep") ngx.say("done") '; } location /foo { echo foo; } location /sleep { echo_sleep 1; } --- request GET /t --- response_body connected: 1 request sent: 61 received response of 156 bytes done --- no_error_log eval ["[error]", "lua tcp socket keepalive close handler: fd:", "lua tcp socket keepalive: free connection pool for "] --- timeout: 4 === TEST 5: lua_socket_keepalive_timeout --- config server_tokens off; location /t { keepalive_timeout 60s; lua_socket_keepalive_timeout 100ms; set $port $TEST_NGINX_SERVER_PORT; content_by_lua ' local port = ngx.var.port local sock = ngx.socket.tcp() local ok, err = sock:connect("127.0.0.1", port) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok) local req = "GET /foo HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: keepalive\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send request: ", err) return end ngx.say("request sent: ", bytes) local reader = sock:receiveuntil("\\r\\n0\\r\\n\\r\\n") local data, res = reader() if not data then ngx.say("failed to receive response body: ", err) return end ngx.say("received response of ", #data, " bytes") local ok, err = sock:setkeepalive() if not ok then ngx.say("failed to set reusable: ", err) end ngx.location.capture("/sleep") ngx.say("done") '; } location /foo { echo foo; } location /sleep { echo_sleep 1; } --- request GET /t --- response_body connected: 1 request sent: 61 received response of 156 bytes done --- no_error_log [error] --- error_log eval ["lua tcp socket keepalive close handler", "lua tcp socket keepalive: free connection pool for ", "lua tcp socket keepalive timeout: 100 ms", qr/lua tcp socket connection pool size: 30\b/] --- timeout: 4 === TEST 6: lua_socket_pool_size --- config server_tokens off; location /t { keepalive_timeout 60s; lua_socket_keepalive_timeout 100ms; lua_socket_pool_size 1; set $port $TEST_NGINX_SERVER_PORT; content_by_lua ' local port = ngx.var.port local sock = ngx.socket.tcp() local ok, err = sock:connect("127.0.0.1", port) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok) local req = "GET /foo HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: keepalive\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send request: ", err) return end ngx.say("request sent: ", bytes) local reader = sock:receiveuntil("\\r\\n0\\r\\n\\r\\n") local data, res = reader() if not data then ngx.say("failed to receive response body: ", err) return end ngx.say("received response of ", #data, " bytes") local ok, err = sock:setkeepalive() if not ok then ngx.say("failed to set reusable: ", err) end ngx.location.capture("/sleep") ngx.say("done") '; } location /foo { echo foo; } location /sleep { echo_sleep 1; } --- request GET /t --- response_body connected: 1 request sent: 61 received response of 156 bytes done --- no_error_log [error] --- error_log eval ["lua tcp socket keepalive close handler", "lua tcp socket keepalive: free connection pool for ", "lua tcp socket keepalive timeout: 100 ms", qr/lua tcp socket connection pool size: 1\b/] --- timeout: 4 === TEST 7: "lua_socket_keepalive_timeout 0" means unlimited --- config server_tokens off; location /t { keepalive_timeout 60s; lua_socket_keepalive_timeout 0; set $port $TEST_NGINX_SERVER_PORT; content_by_lua ' local port = ngx.var.port local sock = ngx.socket.tcp() local ok, err = sock:connect("127.0.0.1", port) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok) local req = "GET /foo HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: keepalive\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send request: ", err) return end ngx.say("request sent: ", bytes) local reader = sock:receiveuntil("\\r\\n0\\r\\n\\r\\n") local data, res = reader() if not data then ngx.say("failed to receive response body: ", err) return end ngx.say("received response of ", #data, " bytes") local ok, err = sock:setkeepalive() if not ok then ngx.say("failed to set reusable: ", err) end ngx.location.capture("/sleep") ngx.say("done") '; } location /foo { echo foo; } location /sleep { echo_sleep 1; } --- request GET /t --- response_body connected: 1 request sent: 61 received response of 156 bytes done --- no_error_log [error] --- error_log eval ["lua tcp socket keepalive timeout: unlimited", qr/lua tcp socket connection pool size: 30\b/] --- timeout: 4 === TEST 8: setkeepalive(timeout) overrides lua_socket_keepalive_timeout --- config server_tokens off; location /t { keepalive_timeout 60s; lua_socket_keepalive_timeout 60s; set $port $TEST_NGINX_SERVER_PORT; content_by_lua ' local port = ngx.var.port local sock = ngx.socket.tcp() local ok, err = sock:connect("127.0.0.1", port) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok) local req = "GET /foo HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: keepalive\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send request: ", err) return end ngx.say("request sent: ", bytes) local reader = sock:receiveuntil("\\r\\n0\\r\\n\\r\\n") local data, res = reader() if not data then ngx.say("failed to receive response body: ", err) return end ngx.say("received response of ", #data, " bytes") local ok, err = sock:setkeepalive(123) if not ok then ngx.say("failed to set reusable: ", err) end ngx.location.capture("/sleep") ngx.say("done") '; } location /foo { echo foo; } location /sleep { echo_sleep 1; } --- request GET /t --- response_body connected: 1 request sent: 61 received response of 156 bytes done --- no_error_log [error] --- error_log eval ["lua tcp socket keepalive close handler", "lua tcp socket keepalive: free connection pool for ", "lua tcp socket keepalive timeout: 123 ms", qr/lua tcp socket connection pool size: 30\b/] --- timeout: 4 === TEST 9: sock:setkeepalive(timeout, size) overrides lua_socket_pool_size --- config server_tokens off; location /t { keepalive_timeout 60s; lua_socket_keepalive_timeout 100ms; lua_socket_pool_size 100; set $port $TEST_NGINX_SERVER_PORT; content_by_lua ' local port = ngx.var.port local sock = ngx.socket.tcp() local ok, err = sock:connect("127.0.0.1", port) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok) local req = "GET /foo HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: keepalive\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send request: ", err) return end ngx.say("request sent: ", bytes) local reader = sock:receiveuntil("\\r\\n0\\r\\n\\r\\n") local data, res = reader() if not data then ngx.say("failed to receive response body: ", err) return end ngx.say("received response of ", #data, " bytes") local ok, err = sock:setkeepalive(101, 25) if not ok then ngx.say("failed to set reusable: ", err) end ngx.location.capture("/sleep") ngx.say("done") '; } location /foo { echo foo; } location /sleep { echo_sleep 1; } --- request GET /t --- response_body connected: 1 request sent: 61 received response of 156 bytes done --- no_error_log [error] --- error_log eval ["lua tcp socket keepalive close handler", "lua tcp socket keepalive: free connection pool for ", "lua tcp socket keepalive timeout: 101 ms", qr/lua tcp socket connection pool size: 25\b/] --- timeout: 4 === TEST 10: sock:keepalive_timeout(0) means unlimited --- config server_tokens off; location /t { keepalive_timeout 60s; lua_socket_keepalive_timeout 1000ms; set $port $TEST_NGINX_SERVER_PORT; content_by_lua ' local port = ngx.var.port local sock = ngx.socket.tcp() local ok, err = sock:connect("127.0.0.1", port) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok) local req = "GET /foo HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: keepalive\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send request: ", err) return end ngx.say("request sent: ", bytes) local reader = sock:receiveuntil("\\r\\n0\\r\\n\\r\\n") local data, res = reader() if not data then ngx.say("failed to receive response body: ", err) return end ngx.say("received response of ", #data, " bytes") local ok, err = sock:setkeepalive(0) if not ok then ngx.say("failed to set reusable: ", err) end ngx.location.capture("/sleep") ngx.say("done") '; } location /foo { echo foo; } location /sleep { echo_sleep 1; } --- request GET /t --- response_body connected: 1 request sent: 61 received response of 156 bytes done --- no_error_log [error] --- error_log eval ["lua tcp socket keepalive timeout: unlimited", qr/lua tcp socket connection pool size: 30\b/] --- timeout: 4 === TEST 11: sanity (uds) --- http_config eval " lua_package_path '$::HtmlDir/?.lua;./?.lua'; server { listen unix:$::HtmlDir/nginx.sock; default_type 'text/plain'; server_tokens off; location /foo { echo foo; more_clear_headers Date; } } " --- config location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua ' local test = require "test" local path = "$TEST_NGINX_HTML_DIR/nginx.sock"; local port = ngx.var.port test.go(path, port) test.go(path, port) '; } --- request GET /t --- user_files >>> test.lua module("test", package.seeall) function go(path, port) local sock = ngx.socket.tcp() local ok, err = sock:connect("unix:" .. path) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok, ", reused: ", sock:getreusedtimes()) local req = "GET /foo HTTP/1.1\r\nHost: localhost\r\nConnection: keepalive\r\n\r\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send request: ", err) return end ngx.say("request sent: ", bytes) local reader = sock:receiveuntil("\r\n0\r\n\r\n") local data, err = reader() if not data then ngx.say("failed to receive response body: ", err) return end ngx.say("received response of ", #data, " bytes") local ok, err = sock:setkeepalive() if not ok then ngx.say("failed to set reusable: ", err) end end --- response_body connected: 1, reused: 0 request sent: 61 received response of 119 bytes connected: 1, reused: 1 request sent: 61 received response of 119 bytes --- no_error_log eval ["[error]", "lua tcp socket keepalive: free connection pool for "] --- error_log eval ["lua tcp socket get keepalive peer: using connection", 'lua tcp socket keepalive create connection pool for key "unix:'] === TEST 12: github issue #108: ngx.locaiton.capture + redis.set_keepalive --- http_config eval qq{ lua_package_path "$::HtmlDir/?.lua;;"; } --- config location /t { default_type text/html; set $port $TEST_NGINX_MEMCACHED_PORT; #lua_code_cache off; lua_need_request_body on; content_by_lua_file html/t.lua; } location /anyurl { internal; proxy_pass http://127.0.0.1:$server_port/dummy; } location = /dummy { echo dummy; } --- user_files >>> t.lua local sock, err = ngx.socket.connect("127.0.0.1", ngx.var.port) if not sock then ngx.say(err) return end sock:send("flush_all\r\n") sock:receive() sock:setkeepalive() sock, err = ngx.socket.connect("127.0.0.1", ngx.var.port) if not sock then ngx.say(err) return end local res = ngx.location.capture("/anyurl") --3 ngx.say("ok") --- request GET /t --- response_body ok --- error_log lua tcp socket get keepalive peer: using connection --- no_error_log [error] [alert] === TEST 13: github issue #110: ngx.exit with HTTP_NOT_FOUND causes worker process to exit --- http_config eval "lua_package_path '$::HtmlDir/?.lua;./?.lua';" --- config error_page 404 /404.html; location /t { set $port $TEST_NGINX_MEMCACHED_PORT; access_by_lua ' local test = require "test" local port = ngx.var.port test.go(port) ngx.exit(404) '; echo hello; } --- user_files >>> 404.html Not found, dear... >>> test.lua module("test", package.seeall) function go(port) local sock = ngx.socket.tcp() local ok, err = sock:connect("127.0.0.1", port) if not ok then ngx.log(ngx.ERR, "failed to connect: ", err) return end local req = "flush_all\r\n" local bytes, err = sock:send(req) if not bytes then ngx.log(ngx.ERR, "failed to send request: ", err) return end local line, err, part = sock:receive() if not line then ngx.log(ngx.ERR, "failed to receive a line: ", err, " [", part, "]") return end -- local ok, err = sock:setkeepalive() -- if not ok then -- ngx.log(ngx.ERR, "failed to set reusable: ", err) -- return -- end end --- request GET /t --- response_body Not found, dear... --- error_code: 404 --- no_error_log [error] === TEST 14: custom pools (different pool for the same host:port) - tcp --- http_config eval "lua_package_path '$::HtmlDir/?.lua;./?.lua';" --- config location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua ' local test = require "test" local port = ngx.var.port test.go(port, "A") test.go(port, "B") '; } --- user_files >>> test.lua module("test", package.seeall) function go(port, pool) local sock = ngx.socket.tcp() local ok, err = sock:connect("127.0.0.1", port, {pool = pool}) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok, ", reused: ", sock:getreusedtimes()) local ok, err = sock:setkeepalive() if not ok then ngx.say("failed to set reusable: ", err) end end --- request GET /t --- response_body connected: 1, reused: 0 connected: 1, reused: 0 --- no_error_log eval ["[error]", "lua tcp socket keepalive: free connection pool for ", "lua tcp socket get keepalive peer: using connection" ] --- error_log lua tcp socket keepalive create connection pool for key "A" lua tcp socket keepalive create connection pool for key "B" === TEST 15: custom pools (same pool for different host:port) - tcp --- http_config eval "lua_package_path '$::HtmlDir/?.lua;./?.lua';" --- config location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua ' local test = require "test" local port = ngx.var.port test.go($TEST_NGINX_MEMCACHED_PORT, "foo") test.go($TEST_NGINX_SERVER_PORT, "foo") '; } --- user_files >>> test.lua module("test", package.seeall) function go(port, pool) local sock = ngx.socket.tcp() local ok, err = sock:connect("127.0.0.1", port, {pool = pool}) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok, ", reused: ", sock:getreusedtimes()) local ok, err = sock:setkeepalive() if not ok then ngx.say("failed to set reusable: ", err) end end --- request GET /t --- response_body connected: 1, reused: 0 connected: 1, reused: 1 --- no_error_log eval ["[error]", "lua tcp socket keepalive: free connection pool for ", ] --- error_log lua tcp socket keepalive create connection pool for key "foo" lua tcp socket get keepalive peer: using connection === TEST 16: custom pools (different pool for the same host:port) - unix --- http_config eval " lua_package_path '$::HtmlDir/?.lua;./?.lua'; server { listen unix:$::HtmlDir/nginx.sock; default_type 'text/plain'; server_tokens off; location /foo { echo foo; more_clear_headers Date; } } " --- config location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua ' local test = require "test" local path = "$TEST_NGINX_HTML_DIR/nginx.sock"; test.go(path, "A") test.go(path, "B") '; } --- user_files >>> test.lua module("test", package.seeall) function go(path, pool) local sock = ngx.socket.tcp() local ok, err = sock:connect("unix:" .. path, {pool = pool}) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok, ", reused: ", sock:getreusedtimes()) local ok, err = sock:setkeepalive() if not ok then ngx.say("failed to set reusable: ", err) end end --- request GET /t --- response_body connected: 1, reused: 0 connected: 1, reused: 0 --- no_error_log eval ["[error]", "lua tcp socket keepalive: free connection pool for ", "lua tcp socket get keepalive peer: using connection" ] --- error_log lua tcp socket keepalive create connection pool for key "A" lua tcp socket keepalive create connection pool for key "B" === TEST 17: custom pools (same pool for the same path) - unix --- http_config eval " lua_package_path '$::HtmlDir/?.lua;./?.lua'; server { listen unix:$::HtmlDir/nginx.sock; default_type 'text/plain'; server_tokens off; } " --- config location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua ' local test = require "test" local path = "$TEST_NGINX_HTML_DIR/nginx.sock"; test.go(path, "A") test.go(path, "A") '; } --- user_files >>> test.lua module("test", package.seeall) function go(path, pool) local sock = ngx.socket.tcp() local ok, err = sock:connect("unix:" .. path, {pool = pool}) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok, ", reused: ", sock:getreusedtimes()) local ok, err = sock:setkeepalive() if not ok then ngx.say("failed to set reusable: ", err) end end --- request GET /t --- response_body connected: 1, reused: 0 connected: 1, reused: 1 --- no_error_log eval ["[error]", "lua tcp socket keepalive: free connection pool for ", ] --- error_log lua tcp socket keepalive create connection pool for key "A" lua tcp socket get keepalive peer: using connection === TEST 18: numeric pool option value --- http_config eval "lua_package_path '$::HtmlDir/?.lua;./?.lua';" --- config location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua ' local test = require "test" local port = ngx.var.port test.go($TEST_NGINX_MEMCACHED_PORT, 3.14) test.go($TEST_NGINX_SERVER_PORT, 3.14) '; } --- user_files >>> test.lua module("test", package.seeall) function go(port, pool) local sock = ngx.socket.tcp() local ok, err = sock:connect("127.0.0.1", port, {pool = pool}) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok, ", reused: ", sock:getreusedtimes()) local ok, err = sock:setkeepalive() if not ok then ngx.say("failed to set reusable: ", err) end end --- request GET /t --- response_body connected: 1, reused: 0 connected: 1, reused: 1 --- no_error_log eval ["[error]", "lua tcp socket keepalive: free connection pool for ", ] --- error_log lua tcp socket keepalive create connection pool for key "3.14" lua tcp socket get keepalive peer: using connection === TEST 19: nil pool option value --- http_config eval "lua_package_path '$::HtmlDir/?.lua;./?.lua';" --- config location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua ' local test = require "test" local port = ngx.var.port test.go($TEST_NGINX_MEMCACHED_PORT, nil) test.go($TEST_NGINX_SERVER_PORT, nil) '; } --- user_files >>> test.lua module("test", package.seeall) function go(port, pool) local sock = ngx.socket.tcp() local ok, err = sock:connect("127.0.0.1", port, {pool = pool}) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok, ", reused: ", sock:getreusedtimes()) local ok, err = sock:setkeepalive() if not ok then ngx.say("failed to set reusable: ", err) end end --- request GET /t --- response_body connected: 1, reused: 0 connected: 1, reused: 0 --- error_code: 200 --- no_error_log [error] === TEST 20: (bad) table pool option value --- http_config eval "lua_package_path '$::HtmlDir/?.lua;./?.lua';" --- config location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua ' local test = require "test" local port = ngx.var.port test.go($TEST_NGINX_MEMCACHED_PORT, {}) test.go($TEST_NGINX_SERVER_PORT, {}) '; } --- user_files >>> test.lua module("test", package.seeall) function go(port, pool) local sock = ngx.socket.tcp() local ok, err = sock:connect("127.0.0.1", port, {pool = pool}) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok, ", reused: ", sock:getreusedtimes()) local ok, err = sock:setkeepalive() if not ok then ngx.say("failed to set reusable: ", err) end end --- request GET /t --- response_body_like: 500 Internal Server Error --- error_code: 500 --- error_log bad argument #3 to 'connect' (bad "pool" option type: table) === TEST 21: (bad) boolean pool option value --- http_config eval "lua_package_path '$::HtmlDir/?.lua;./?.lua';" --- config location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua ' local test = require "test" local port = ngx.var.port test.go($TEST_NGINX_MEMCACHED_PORT, true) test.go($TEST_NGINX_SERVER_PORT, false) '; } --- user_files >>> test.lua module("test", package.seeall) function go(port, pool) local sock = ngx.socket.tcp() local ok, err = sock:connect("127.0.0.1", port, {pool = pool}) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok, ", reused: ", sock:getreusedtimes()) local ok, err = sock:setkeepalive() if not ok then ngx.say("failed to set reusable: ", err) end end --- request GET /t --- response_body_like: 500 Internal Server Error --- error_code: 500 --- error_log bad argument #3 to 'connect' (bad "pool" option type: boolean) === TEST 22: clear the redis store --- config location /t { redis2_query flushall; redis2_pass 127.0.0.1:$TEST_NGINX_REDIS_PORT; } --- request GET /t --- response_body eval "+OK\r\n" --- no_error_log [error] [alert] [warn] === TEST 23: bug in send(): clear the chain writer ctx --- http_config eval "lua_package_path '$::HtmlDir/?.lua;./?.lua';" --- config location /t { set $port $TEST_NGINX_REDIS_PORT; content_by_lua ' local test = require "test" local port = ngx.var.port test.go(port) '; } --- user_files >>> test.lua module("test", package.seeall) function go(port) local sock = ngx.socket.tcp() local ok, err = sock:connect("127.0.0.1", port) if not ok then ngx.say("failed to connect: ", err) return end local bytes, err = sock:send({}) if err then ngx.say("failed to send empty request: ", err) return end local req = "*2\r\n$3\r\nget\r\n$3\r\ndog\r\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send request: ", err) return end local line, err, part = sock:receive() if line then ngx.say("received: ", line) else ngx.say("failed to receive a line: ", err, " [", part, "]") end local ok, err = sock:setkeepalive() if not ok then ngx.say("failed to set reusable: ", err) end ngx.say("done") end --- request GET /t --- stap2 global active M(http-lua-socket-tcp-send-start) { active = 1 printf("send [%s] %d\n", text_str(user_string_n($arg3, $arg4)), $arg4) } M(http-lua-socket-tcp-receive-done) { printf("receive [%s]\n", text_str(user_string_n($arg3, $arg4))) } F(ngx_output_chain) { #printf("ctx->in: %s\n", ngx_chain_dump($ctx->in)) #printf("ctx->busy: %s\n", ngx_chain_dump($ctx->busy)) printf("output chain: %s\n", ngx_chain_dump($in)) } F(ngx_linux_sendfile_chain) { printf("linux sendfile chain: %s\n", ngx_chain_dump($in)) } F(ngx_chain_writer) { printf("chain writer ctx out: %p\n", $data) printf("nginx chain writer: %s\n", ngx_chain_dump($in)) } F(ngx_http_lua_socket_tcp_setkeepalive) { delete active } M(http-lua-socket-tcp-setkeepalive-buf-unread) { printf("setkeepalive unread: [%s]\n", text_str(user_string_n($arg3, $arg4))) } probe syscall.recvfrom { if (active && pid() == target()) { printf("recvfrom(%s)", argstr) } } probe syscall.recvfrom.return { if (active && pid() == target()) { printf(" = %s, data [%s]\n", retstr, text_str(user_string_n($ubuf, $size))) } } probe syscall.writev { if (active && pid() == target()) { printf("writev(%s)", ngx_iovec_dump($vec, $vlen)) /* for (i = 0; i < $vlen; i++) { printf(" %p [%s]", $vec[i]->iov_base, text_str(user_string_n($vec[i]->iov_base, $vec[i]->iov_len))) } */ } } probe syscall.writev.return { if (active && pid() == target()) { printf(" = %s\n", retstr) } } --- response_body received: $-1 done --- no_error_log [error] === TEST 24: setkeepalive() with explicit nil args --- config server_tokens off; location /t { lua_socket_keepalive_timeout 100ms; set $port $TEST_NGINX_SERVER_PORT; content_by_lua_block { local port = ngx.var.port local sock = ngx.socket.tcp() local ok, err = sock:connect("127.0.0.1", port) if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok) local req = "GET /foo HTTP/1.1\r\nHost: localhost\r\nConnection: keepalive\r\n\r\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send request: ", err) return end ngx.say("request sent: ", bytes) local reader = sock:receiveuntil("\r\n0\r\n\r\n") local data, res = reader() if not data then ngx.say("failed to receive response body: ", err) return end ngx.say("received response of ", #data, " bytes") local ok, err = sock:setkeepalive(nil, nil) if not ok then ngx.say("failed to set reusable: ", err) end ngx.location.capture("/sleep") ngx.say("done") } } location /foo { echo foo; } location /sleep { echo_sleep 1; } --- request GET /t --- response_body connected: 1 request sent: 61 received response of 156 bytes done --- no_error_log [error] --- error_log eval ["lua tcp socket keepalive close handler", "lua tcp socket keepalive: free connection pool for ", "lua tcp socket keepalive timeout: 100 ms", qr/lua tcp socket connection pool size: 30\b/] --- timeout: 4