# vim:set ft= ts=4 sw=4 et fdm=marker: use Test::Nginx::Socket::Lua; use Cwd qw(abs_path realpath); use File::Basename; repeat_each(3); plan tests => repeat_each() * (blocks() * 6 + 2); $ENV{TEST_NGINX_HTML_DIR} ||= html_dir(); $ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211; $ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8'; $ENV{TEST_NGINX_CERT_DIR} ||= dirname(realpath(abs_path(__FILE__))); #log_level 'warn'; log_level 'debug'; no_long_string(); #no_diff(); run_tests(); __DATA__ === TEST 1: simple logging --- http_config server { listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; server_name test.com; ssl_session_store_by_lua_block { print("ssl session store by lua is running!") } ssl_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; ssl_certificate_key $TEST_NGINX_CERT_DIR/cert/test.key; ssl_protocols SSLv3; server_tokens off; } --- config server_tokens off; resolver $TEST_NGINX_RESOLVER; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua_block { do local sock = ngx.socket.tcp() sock:settimeout(5000) local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok) local sess, err = sock:sslhandshake(nil, "test.com", true) if not sess then ngx.say("failed to do SSL handshake: ", err) return end ngx.say("ssl handshake: ", type(sess)) local ok, err = sock:close() ngx.say("close: ", ok, " ", err) end -- do -- collectgarbage() } } --- request GET /t --- response_body connected: 1 ssl handshake: userdata close: 1 nil --- error_log lua ssl server name: "test.com" ssl_session_store_by_lua_block:1: ssl session store by lua is running! --- no_error_log [error] [alert] === TEST 2: sleep is not allowed --- http_config server { listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; server_name test.com; ssl_session_store_by_lua_block { local begin = ngx.now() ngx.sleep(0.1) print("elapsed in ssl store session by lua: ", ngx.now() - begin) } ssl_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; ssl_certificate_key $TEST_NGINX_CERT_DIR/cert/test.key; ssl_protocols SSLv3; server_tokens off; } --- config server_tokens off; resolver $TEST_NGINX_RESOLVER; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua_block { do local sock = ngx.socket.tcp() sock:settimeout(5000) local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok) local sess, err = sock:sslhandshake(nil, "test.com", true) if not sess then ngx.say("failed to do SSL handshake: ", err) return end ngx.say("ssl handshake: ", type(sess)) local ok, err = sock:close() ngx.say("close: ", ok, " ", err) end -- do -- collectgarbage() } } --- request GET /t --- response_body connected: 1 ssl handshake: userdata close: 1 nil --- error_log lua ssl server name: "test.com" API disabled in the context of ssl_session_store_by_lua* --- no_error_log [alert] [emerg] === TEST 3: timer --- http_config server { listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; server_name test.com; ssl_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; ssl_certificate_key $TEST_NGINX_CERT_DIR/cert/test.key; ssl_session_store_by_lua_block { local function f() print("my timer run!") end local ok, err = ngx.timer.at(0, f) if not ok then ngx.log(ngx.ERR, "failed to create timer: ", err) return end } ssl_protocols SSLv3; server_tokens off; } --- config server_tokens off; resolver $TEST_NGINX_RESOLVER; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua_block { do local sock = ngx.socket.tcp() sock:settimeout(5000) local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok) local sess, err = sock:sslhandshake(nil, "test.com", true) if not sess then ngx.say("failed to do SSL handshake: ", err) return end ngx.say("ssl handshake: ", type(sess)) local ok, err = sock:close() ngx.say("close: ", ok, " ", err) end -- do -- collectgarbage() } } --- request GET /t --- response_body connected: 1 ssl handshake: userdata close: 1 nil --- error_log lua ssl server name: "test.com" my timer run! --- no_error_log [error] [alert] === TEST 4: cosocket is not allowed --- http_config server { listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; server_name test.com; ssl_session_store_by_lua_block { local sock = ngx.socket.tcp() sock:settimeout(5000) local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT) if not ok then ngx.log(ngx.ERR, "failed to connect to memc: ", err) return end local bytes, err = sock:send("flush_all\\r\\n") if not bytes then ngx.log(ngx.ERR, "failed to send flush_all command: ", err) return end local res, err = sock:receive() if not res then ngx.log(ngx.ERR, "failed to receive memc reply: ", err) return end print("received memc reply: ", res) } ssl_protocols SSLv3; ssl_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; ssl_certificate_key $TEST_NGINX_CERT_DIR/cert/test.key; server_tokens off; } --- config server_tokens off; resolver $TEST_NGINX_RESOLVER; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua_block { do local sock = ngx.socket.tcp() sock:settimeout(5000) local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok) local sess, err = sock:sslhandshake(nil, "test.com", true) if not sess then ngx.say("failed to do SSL handshake: ", err) return end ngx.say("ssl handshake: ", type(sess)) local ok, err = sock:close() ngx.say("close: ", ok, " ", err) end -- do -- collectgarbage() } } --- request GET /t --- response_body connected: 1 ssl handshake: userdata close: 1 nil --- error_log lua ssl server name: "test.com" API disabled in the context of ssl_session_store_by_lua* --- no_error_log [alert] [emerg] === TEST 5: ngx.exit(0) - no yield --- http_config server { listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; server_name test.com; ssl_session_store_by_lua_block { ngx.exit(0) } ssl_protocols SSLv3; ssl_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; ssl_certificate_key $TEST_NGINX_CERT_DIR/cert/test.key; server_tokens off; } --- config server_tokens off; resolver $TEST_NGINX_RESOLVER; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; lua_ssl_verify_depth 3; location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua_block { do local sock = ngx.socket.tcp() sock:settimeout(5000) local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok) local sess, err = sock:sslhandshake(package.loaded.session, "test.com", true) if not sess then ngx.say("failed to do SSL handshake: ", err) return end ngx.say("ssl handshake: ", type(sess)) package.loaded.session = sess local ok, err = sock:close() ngx.say("close: ", ok, " ", err) end -- do -- collectgarbage() } } --- request GET /t --- response_body connected: 1 ssl handshake: userdata close: 1 nil --- error_log lua exit with code 0 --- no_error_log [error] [alert] [emerg] === TEST 6: ngx.exit(ngx.ERROR) - no yield ngx.exit does not yield and the error code is eaten. --- http_config server { listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; server_name test.com; ssl_session_store_by_lua_block { ngx.exit(ngx.ERROR) } ssl_protocols SSLv3; ssl_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; ssl_certificate_key $TEST_NGINX_CERT_DIR/cert/test.key; server_tokens off; } --- config server_tokens off; resolver $TEST_NGINX_RESOLVER; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; lua_ssl_verify_depth 3; location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua_block { do local sock = ngx.socket.tcp() sock:settimeout(5000) local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok) local sess, err = sock:sslhandshake(package.loaded.session, "test.com", true) if not sess then ngx.say("failed to do SSL handshake: ", err) return end ngx.say("ssl handshake: ", type(sess)) package.loaded.session = sess local ok, err = sock:close() ngx.say("close: ", ok, " ", err) end -- do -- collectgarbage() } } --- request GET /t --- response_body connected: 1 ssl handshake: userdata close: 1 nil --- error_log lua exit with code -1 ssl_session_store_by_lua*: handler return value: 0, sess new cb exit code: 0 --- no_error_log [error] [alert] [emerg] === TEST 7: lua exception - no yield --- http_config server { listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; server_name test.com; ssl_session_store_by_lua_block { error("bad bad bad") ngx.log(ngx.ERR, "should never reached here...") } ssl_protocols SSLv3; ssl_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; ssl_certificate_key $TEST_NGINX_CERT_DIR/cert/test.key; server_tokens off; } --- config server_tokens off; resolver $TEST_NGINX_RESOLVER; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; lua_ssl_verify_depth 3; location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua_block { do local sock = ngx.socket.tcp() sock:settimeout(5000) local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok) local sess, err = sock:sslhandshake(nil, "test.com", true) if not sess then ngx.say("failed to do SSL handshake: ", err) return end ngx.say("ssl handshake: ", type(sess)) local ok, err = sock:close() ngx.say("close: ", ok, " ", err) end -- do } } --- request GET /t --- response_body connected: 1 ssl handshake: userdata close: 1 nil --- error_log failed to run session_store_by_lua*: ssl_session_store_by_lua_block:2: bad bad bad --- no_error_log should never reached here [alert] [emerg] === TEST 8: get phase --- http_config server { listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; server_name test.com; ssl_session_store_by_lua_block { print("get_phase: ", ngx.get_phase()) } ssl_protocols SSLv3; ssl_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; ssl_certificate_key $TEST_NGINX_CERT_DIR/cert/test.key; server_tokens off; } --- config server_tokens off; resolver $TEST_NGINX_RESOLVER; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; lua_ssl_verify_depth 3; location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua_block { do local sock = ngx.socket.tcp() sock:settimeout(5000) local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok) local sess, err = sock:sslhandshake(nil, "test.com", true) if not sess then ngx.say("failed to do SSL handshake: ", err) return end ngx.say("ssl handshake: ", type(sess)) local ok, err = sock:close() ngx.say("close: ", ok, " ", err) end -- do } } --- request GET /t --- response_body connected: 1 ssl handshake: userdata close: 1 nil --- error_log get_phase: ssl_session_store --- no_error_log [alert] [emerg] [error] === TEST 9: inter-operation with ssl_certificate_by_lua --- http_config server { listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; server_name test.com; ssl_certificate_by_lua_block { local begin = ngx.now() ngx.sleep(0.1) print("elapsed in ssl cert by lua: ", ngx.now() - begin) } ssl_session_store_by_lua_block { print("ssl store session by lua is running!") } ssl_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; ssl_certificate_key $TEST_NGINX_CERT_DIR/cert/test.key; ssl_protocols SSLv3; server_tokens off; } --- config server_tokens off; resolver $TEST_NGINX_RESOLVER; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua_block { do local sock = ngx.socket.tcp() sock:settimeout(5000) local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok) local sess, err = sock:sslhandshake(nil, "test.com", true) if not sess then ngx.say("failed to do SSL handshake: ", err) return end ngx.say("ssl handshake: ", type(sess)) local ok, err = sock:close() ngx.say("close: ", ok, " ", err) end -- do -- collectgarbage() } } --- request GET /t --- response_body connected: 1 ssl handshake: userdata close: 1 nil --- error_log eval [ 'lua ssl server name: "test.com"', qr/elapsed in ssl cert by lua: 0.(?:09|1[01])\d+,/, 'ssl_session_store_by_lua_block:1: ssl store session by lua is running!', ] --- no_error_log [error] [alert] === TEST 10: simple logging (by file) --- http_config server { listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; server_name test.com; ssl_session_store_by_lua_file html/a.lua; ssl_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; ssl_certificate_key $TEST_NGINX_CERT_DIR/cert/test.key; ssl_protocols SSLv3; server_tokens off; } --- config server_tokens off; resolver $TEST_NGINX_RESOLVER; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua_block { do local sock = ngx.socket.tcp() sock:settimeout(5000) local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") if not ok then ngx.say("failed to connect: ", err) return end ngx.say("connected: ", ok) local sess, err = sock:sslhandshake(nil, "test.com", true) if not sess then ngx.say("failed to do SSL handshake: ", err) return end ngx.say("ssl handshake: ", type(sess)) local ok, err = sock:close() ngx.say("close: ", ok, " ", err) end -- do -- collectgarbage() } } --- user_files >>> a.lua print("ssl store session by lua is running!") --- request GET /t --- response_body connected: 1 ssl handshake: userdata close: 1 nil --- error_log lua ssl server name: "test.com" a.lua:1: ssl store session by lua is running! --- no_error_log [error] [alert]