diff --git a/lib/ngx/ssl.lua b/lib/ngx/ssl.lua index 89d42a533..1c68a03bf 100644 --- a/lib/ngx/ssl.lua +++ b/lib/ngx/ssl.lua @@ -58,6 +58,8 @@ int ngx_http_lua_ffi_set_priv_key(void *r, void *cdata, char **err); void ngx_http_lua_ffi_free_cert(void *cdata); void ngx_http_lua_ffi_free_priv_key(void *cdata); + +int ngx_http_lua_ffi_set_httpv(ngx_http_request_t *r, int hv, char **err); ]] @@ -284,4 +286,23 @@ do end +function _M.set_http_version(hv) + local r = getfenv(0).__ngx_req + if not r then + return error("no request found") + end + + local v = tonumber(hv) + if v < 0 then + return error("no negative number") + end + + local rc = C.ngx_http_lua_ffi_set_httpv(r, v, errmsg) + if rc == FFI_OK then + return true + end + + return nil, ffi_str(errmsg[0]) +end + return _M diff --git a/lib/ngx/ssl.md b/lib/ngx/ssl.md index fc7ecae5f..e6f4ffc21 100644 --- a/lib/ngx/ssl.md +++ b/lib/ngx/ssl.md @@ -23,6 +23,7 @@ Table of Contents * [parse_pem_priv_key](#parse_pem_priv_key) * [set_cert](#set_cert) * [set_priv_key](#set_priv_key) + * [set_http_version](#set_http_version) * [Community](#community) * [English Mailing List](#english-mailing-list) * [Chinese Mailing List](#chinese-mailing-list) @@ -45,8 +46,8 @@ Synopsis lua_package_path "/path/to/lua-resty-core/lib/?.lua;;"; server { - listen 443 ssl; - server_name test.com; + listen 443 ssl http2; + server_name test.com hello.com; # useless placeholders: just to shut up NGINX configuration # loader errors: @@ -91,6 +92,15 @@ server { ngx.log(ngx.ERR, "failed to set DER private key: ", err) return ngx.exit(ngx.ERROR) end + + local sn, err = ssl.server_name() + if not sn then + ngx.log(ngx.ERR, "failed to get server name: ", err) + return ngx.exit(ngx.ERROR) + end + if sn == "test.com" then + ssl.set_http_version(1) + end } location / { @@ -381,6 +391,23 @@ This function was first added in version `0.1.7`. [Back to TOC](#table-of-contents) +set_http_version +------------ +**syntax:** *ok, err = ssl.set_http_version(http_version)* + +**context:** *ssl_certificate_by_lua** + +Sets the ALPN(NPN) http version. + +http_version: + +* 1 - http1.1 +* 2 - http2 + +Returns `true` on success, or a `nil` value and a string describing the error otherwise. + +[Back to TOC](#table-of-contents) + Community ========= diff --git a/t/http2.t b/t/http2.t new file mode 100644 index 000000000..02d228a34 --- /dev/null +++ b/t/http2.t @@ -0,0 +1,80 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: + +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +log_level('debug'); +# server_port('443'); +server_name('test.com'); + +repeat_each(2); + +plan tests => repeat_each() * blocks(); + +our $CWD = cwd(); + +#no_diff(); +#no_long_string(); +no_shuffle(); + +$ENV{TEST_NGINX_USE_HTTP2} = 1; +$ENV{TEST_NGINX_LUA_PACKAGE_PATH} = "$::CWD/lib/?.lua;;"; + +run_tests(); + + +__DATA__ + + +=== TEST 1: test set http2 +--- http_config + lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH/?.lua;;"; + + +--- config + ssl_certificate ../../cert/test.crt; + ssl_certificate_key ../../cert/test.key; + + ssl_certificate_by_lua_block { + local ssl = require "ngx.ssl"; + ssl.set_http_version(2); + } + location /t { + return 200 "ok"; + } + +--- http2 +--- sni +--- request +GET /t +--- ignore_response +--- error_log +LUA SSL ALPN selected: h2 + + + +=== TEST 2: test set http1.1 +--- http_config + lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH/?.lua;;"; + + +--- config + ssl_certificate ../../cert/test.crt; + ssl_certificate_key ../../cert/test.key; + + ssl_certificate_by_lua_block { + local ssl = require "ngx.ssl"; + ssl.set_http_version(1); + } + location /t { + return 200 "ok"; + } + +--- http2 +--- sni +--- request +GET /t +--- ignore_response +--- error_log +LUA SSL ALPN selected: http/1.1 +