| # vim:set ft= ts=4 sw=4 et fdm=marker: |
| |
| use lib 'lib'; |
| use Test::Nginx::Socket::Lua; |
| |
| #repeat_each(2); |
| |
| plan tests => repeat_each() * (blocks() * 5 + 7); |
| |
| 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] |
| |