Skip to content

Commit 1326c0a

Browse files
halfcrazydoujiang24
authored andcommitted
feature: implemented the new ngx.ssl.server_port() API to get server port.
1 parent 176b05a commit 1326c0a

File tree

3 files changed

+241
-0
lines changed

3 files changed

+241
-0
lines changed

lib/ngx/ssl.lua

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ local ngx_lua_ffi_ssl_set_der_certificate
2424
local ngx_lua_ffi_ssl_clear_certs
2525
local ngx_lua_ffi_ssl_set_der_private_key
2626
local ngx_lua_ffi_ssl_raw_server_addr
27+
local ngx_lua_ffi_ssl_server_port
2728
local ngx_lua_ffi_ssl_server_name
2829
local ngx_lua_ffi_ssl_raw_client_addr
2930
local ngx_lua_ffi_cert_pem_to_der
@@ -51,6 +52,9 @@ if subsystem == 'http' then
5152
int ngx_http_lua_ffi_ssl_raw_server_addr(ngx_http_request_t *r, char **addr,
5253
size_t *addrlen, int *addrtype, char **err);
5354

55+
int ngx_http_lua_ffi_ssl_server_port(ngx_http_request_t *r,
56+
unsigned short *server_port, char **err);
57+
5458
int ngx_http_lua_ffi_ssl_server_name(ngx_http_request_t *r, char **name,
5559
size_t *namelen, char **err);
5660

@@ -90,6 +94,7 @@ if subsystem == 'http' then
9094
ngx_lua_ffi_ssl_set_der_private_key =
9195
C.ngx_http_lua_ffi_ssl_set_der_private_key
9296
ngx_lua_ffi_ssl_raw_server_addr = C.ngx_http_lua_ffi_ssl_raw_server_addr
97+
ngx_lua_ffi_ssl_server_port = C.ngx_http_lua_ffi_ssl_server_port
9398
ngx_lua_ffi_ssl_server_name = C.ngx_http_lua_ffi_ssl_server_name
9499
ngx_lua_ffi_ssl_raw_client_addr = C.ngx_http_lua_ffi_ssl_raw_client_addr
95100
ngx_lua_ffi_cert_pem_to_der = C.ngx_http_lua_ffi_cert_pem_to_der
@@ -117,6 +122,9 @@ elseif subsystem == 'stream' then
117122
int ngx_stream_lua_ffi_ssl_raw_server_addr(ngx_stream_lua_request_t *r,
118123
char **addr, size_t *addrlen, int *addrtype, char **err);
119124

125+
int ngx_stream_lua_ffi_ssl_server_port(ngx_stream_lua_request_t *r,
126+
unsigned short *server_port, char **err);
127+
120128
int ngx_stream_lua_ffi_ssl_server_name(ngx_stream_lua_request_t *r,
121129
char **name, size_t *namelen, char **err);
122130

@@ -156,6 +164,7 @@ elseif subsystem == 'stream' then
156164
ngx_lua_ffi_ssl_set_der_private_key =
157165
C.ngx_stream_lua_ffi_ssl_set_der_private_key
158166
ngx_lua_ffi_ssl_raw_server_addr = C.ngx_stream_lua_ffi_ssl_raw_server_addr
167+
ngx_lua_ffi_ssl_server_port = C.ngx_stream_lua_ffi_ssl_server_port
159168
ngx_lua_ffi_ssl_server_name = C.ngx_stream_lua_ffi_ssl_server_name
160169
ngx_lua_ffi_ssl_raw_client_addr = C.ngx_stream_lua_ffi_ssl_raw_client_addr
161170
ngx_lua_ffi_cert_pem_to_der = C.ngx_stream_lua_ffi_cert_pem_to_der
@@ -176,6 +185,7 @@ local _M = { version = base.version }
176185

177186
local charpp = ffi.new("char*[1]")
178187
local intp = ffi.new("int[1]")
188+
local ushortp = ffi.new("unsigned short[1]")
179189

180190

181191
function _M.clear_certs()
@@ -251,6 +261,21 @@ function _M.raw_server_addr()
251261
end
252262

253263

264+
function _M.server_port()
265+
local r = get_request()
266+
if not r then
267+
error("no request found")
268+
end
269+
270+
local rc = ngx_lua_ffi_ssl_server_port(r, ushortp, errmsg)
271+
if rc == FFI_OK then
272+
return ushortp[0]
273+
end
274+
275+
return nil, ffi_str(errmsg[0])
276+
end
277+
278+
254279
function _M.server_name()
255280
local r = get_request()
256281
if not r then

lib/ngx/ssl.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Table of Contents
1717
* [priv_key_pem_to_der](#priv_key_pem_to_der)
1818
* [set_der_priv_key](#set_der_priv_key)
1919
* [server_name](#server_name)
20+
* [server_port](#server_port)
2021
* [raw_server_addr](#raw_server_addr)
2122
* [raw_client_addr](#raw_client_addr)
2223
* [get_tls1_version](#get_tls1_version)
@@ -251,6 +252,21 @@ This function can be called in any context where downstream https is used.
251252

252253
[Back to TOC](#table-of-contents)
253254

255+
server_port
256+
-----------
257+
**syntax:** port, err = ssl.server_port()
258+
259+
**context:** *any*
260+
261+
Returns the server port. Returns `nil`
262+
when server dont have a port.
263+
264+
In case of failures, it returns `nil` *and* a string describing the error.
265+
266+
This function can be called in any context where downstream https is used.
267+
268+
[Back to TOC](#table-of-contents)
269+
254270
raw_server_addr
255271
---------------
256272
**syntax:** *addr_data, addr_type, err = ssl.raw_server_addr()*

t/ssl.t

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2504,3 +2504,203 @@ client certificate subject: nil
25042504
[error]
25052505
[alert]
25062506
[emerg]
2507+
2508+
2509+
2510+
=== TEST 26: read server port via ssl.server_port() with ipv4
2511+
--- http_config
2512+
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
2513+
2514+
server {
2515+
listen 127.0.0.1:12345 ssl;
2516+
server_name test.com;
2517+
ssl_certificate_by_lua_block {
2518+
local ssl = require "ngx.ssl"
2519+
local port, err = ssl.server_port()
2520+
print("read server port from Lua: ", port)
2521+
}
2522+
ssl_certificate ../../cert/test.crt;
2523+
ssl_certificate_key ../../cert/test.key;
2524+
2525+
server_tokens off;
2526+
location /foo {
2527+
default_type 'text/plain';
2528+
content_by_lua_block {ngx.status = 201 ngx.say("foo") ngx.exit(201)}
2529+
more_clear_headers Date;
2530+
}
2531+
}
2532+
--- config
2533+
server_tokens off;
2534+
lua_ssl_trusted_certificate ../../cert/test.crt;
2535+
2536+
location /t {
2537+
content_by_lua_block {
2538+
do
2539+
local sock = ngx.socket.tcp()
2540+
2541+
sock:settimeout(3000)
2542+
2543+
local ok, err = sock:connect("127.0.0.1", 12345)
2544+
if not ok then
2545+
ngx.say("failed to connect: ", err)
2546+
return
2547+
end
2548+
2549+
ngx.say("connected: ", ok)
2550+
2551+
local sess, err = sock:sslhandshake(nil, "test.com", true)
2552+
if not sess then
2553+
ngx.say("failed to do SSL handshake: ", err)
2554+
return
2555+
end
2556+
2557+
ngx.say("ssl handshake: ", type(sess))
2558+
2559+
local req = "GET /foo HTTP/1.0\r\nHost: test.com\r\nConnection: close\r\n\r\n"
2560+
local bytes, err = sock:send(req)
2561+
if not bytes then
2562+
ngx.say("failed to send http request: ", err)
2563+
return
2564+
end
2565+
2566+
ngx.say("sent http request: ", bytes, " bytes.")
2567+
2568+
while true do
2569+
local line, err = sock:receive()
2570+
if not line then
2571+
-- ngx.say("failed to receive response status line: ", err)
2572+
break
2573+
end
2574+
2575+
ngx.say("received: ", line)
2576+
end
2577+
2578+
local ok, err = sock:close()
2579+
ngx.say("close: ", ok, " ", err)
2580+
end -- do
2581+
-- collectgarbage()
2582+
}
2583+
}
2584+
2585+
--- request
2586+
GET /t
2587+
--- response_body
2588+
connected: 1
2589+
ssl handshake: userdata
2590+
sent http request: 56 bytes.
2591+
received: HTTP/1.1 201 Created
2592+
received: Server: nginx
2593+
received: Content-Type: text/plain
2594+
received: Content-Length: 4
2595+
received: Connection: close
2596+
received:
2597+
received: foo
2598+
close: 1 nil
2599+
2600+
--- error_log
2601+
read server port from Lua: 12345
2602+
2603+
--- no_error_log
2604+
[error]
2605+
[alert]
2606+
[emerg]
2607+
2608+
2609+
2610+
=== TEST 27: read server port via ssl.server_port() with unix domain socket
2611+
--- http_config
2612+
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
2613+
2614+
server {
2615+
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
2616+
server_name test.com;
2617+
ssl_certificate_by_lua_block {
2618+
local ssl = require "ngx.ssl"
2619+
local port, err = ssl.server_port()
2620+
print("read server port from Lua: ", port, err)
2621+
}
2622+
ssl_certificate ../../cert/test.crt;
2623+
ssl_certificate_key ../../cert/test.key;
2624+
2625+
server_tokens off;
2626+
location /foo {
2627+
default_type 'text/plain';
2628+
content_by_lua_block {ngx.status = 201 ngx.say("foo") ngx.exit(201)}
2629+
more_clear_headers Date;
2630+
}
2631+
}
2632+
--- config
2633+
server_tokens off;
2634+
lua_ssl_trusted_certificate ../../cert/test.crt;
2635+
2636+
location /t {
2637+
content_by_lua_block {
2638+
do
2639+
local sock = ngx.socket.tcp()
2640+
2641+
sock:settimeout(3000)
2642+
2643+
local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock")
2644+
if not ok then
2645+
ngx.say("failed to connect: ", err)
2646+
return
2647+
end
2648+
2649+
ngx.say("connected: ", ok)
2650+
2651+
local sess, err = sock:sslhandshake(nil, "test.com", true)
2652+
if not sess then
2653+
ngx.say("failed to do SSL handshake: ", err)
2654+
return
2655+
end
2656+
2657+
ngx.say("ssl handshake: ", type(sess))
2658+
2659+
local req = "GET /foo HTTP/1.0\r\nHost: test.com\r\nConnection: close\r\n\r\n"
2660+
local bytes, err = sock:send(req)
2661+
if not bytes then
2662+
ngx.say("failed to send http request: ", err)
2663+
return
2664+
end
2665+
2666+
ngx.say("sent http request: ", bytes, " bytes.")
2667+
2668+
while true do
2669+
local line, err = sock:receive()
2670+
if not line then
2671+
-- ngx.say("failed to receive response status line: ", err)
2672+
break
2673+
end
2674+
2675+
ngx.say("received: ", line)
2676+
end
2677+
2678+
local ok, err = sock:close()
2679+
ngx.say("close: ", ok, " ", err)
2680+
end -- do
2681+
-- collectgarbage()
2682+
}
2683+
}
2684+
2685+
--- request
2686+
GET /t
2687+
--- response_body
2688+
connected: 1
2689+
ssl handshake: userdata
2690+
sent http request: 56 bytes.
2691+
received: HTTP/1.1 201 Created
2692+
received: Server: nginx
2693+
received: Content-Type: text/plain
2694+
received: Content-Length: 4
2695+
received: Connection: close
2696+
received:
2697+
received: foo
2698+
close: 1 nil
2699+
2700+
--- error_log
2701+
read server port from Lua: nilunix domain has no port
2702+
2703+
--- no_error_log
2704+
[error]
2705+
[alert]
2706+
[emerg]

0 commit comments

Comments
 (0)