Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ssl support #5

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,13 @@ http {
local ok, err = hc.spawn_checker{
shm = "healthcheck", -- defined by "lua_shared_dict"
upstream = "foo.com", -- defined by "upstream"
type = "http",


type = "https",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because type = "http" is a more common case, we should at least put it in a comment here?

ssl_verify = true, -- verify SSL certs, see https://github.com/openresty/lua-nginx-module/pull/290

-- if you put this Lua snippet in separate .lua file,
-- then you should write this instead: http_req = "GET /status HTTP/1.0\r\nHost: foo.com\r\n\r\n",
http_req = "GET /status HTTP/1.0\\r\\nHost: foo.com\\r\\n\\r\\n",
-- raw HTTP request for checking
http_req = "GET /status HTTP/1.0\\r\\nHost: foo.com\\r\\n\\r\\n", -- raw HTTP request for checking

interval = 2000, -- run the check cycle every 2 sec
timeout = 1000, -- 1 sec is the timeout for network operations
Expand Down
92 changes: 55 additions & 37 deletions lib/resty/upstream/healthcheck.lua
Original file line number Diff line number Diff line change
Expand Up @@ -225,50 +225,65 @@ local function check_peer(ctx, id, peer, is_backup)
errlog("failed to connect to ", name, ": ", err)
end
peer_fail(ctx, is_backup, id, peer)
else
local bytes, err = sock:send(req)
if not bytes then
return
end

if ctx.type == "https" then
local session, err = sock:sslhandshake(nil, name, ctx.ssl_verify)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we could expose an option to reuse SSL sessions (directly saved in the healthcheck object, for example). This can reduce the healthcheck overhead considerably since a full SSL handshake is very expensive in CPU time.

if not session then
errlog("failed to do SSL handshake: ", name, ": ", err)
sock:close()
return
end
end

local bytes, err = sock:send(req)
if not bytes then
if not peer.down then
errlog("failed to send request to ", name, ": ", err)
end
peer_fail(ctx, is_backup, id, peer)
sock:close()
return
end

local status_line, err = sock:receive()
if not status_line then
if not peer.down then
errlog("failed to receive status line from ", name,
": ", err)
end
peer_fail(ctx, is_backup, id, peer)
sock:close()
return
end

sock:close()

if statuses then
local from, to, err = re_find(status_line,
[[^HTTP/\d+\.\d+\s+(\d+)]],
"joi", nil, 1)
if not from then
if not peer.down then
errlog("failed to send request to ", name, ": ", err)
errlog("bad status line from ", name, ": ",
status_line)
end
peer_fail(ctx, is_backup, id, peer)
else
local status_line, err = sock:receive()
if not status_line then
local status = tonumber(sub(status_line, from, to))
if not statuses[status] then
if not peer.down then
errlog("failed to receive status line from ", name,
": ", err)
errlog("bad status code from ",
name, ": ", status)
end
peer_fail(ctx, is_backup, id, peer)
else
if statuses then
local from, to, err = re_find(status_line,
[[^HTTP/\d+\.\d+\s+(\d+)]],
"joi", nil, 1)
if not from then
if not peer.down then
errlog("bad status line from ", name, ": ",
status_line)
end
peer_fail(ctx, is_backup, id, peer)
else
local status = tonumber(sub(status_line, from, to))
if not statuses[status] then
if not peer.down then
errlog("bad status code from ",
name, ": ", status)
end
peer_fail(ctx, is_backup, id, peer)
else
peer_ok(ctx, is_backup, id, peer)
end
end
else
peer_ok(ctx, is_backup, id, peer)
end
peer_ok(ctx, is_backup, id, peer)
end
sock:close()
end
else
peer_ok(ctx, is_backup, id, peer)
end
end

Expand Down Expand Up @@ -510,10 +525,12 @@ function _M.spawn_checker(opts)
return nil, "\"type\" option required"
end

if typ ~= "http" then
return nil, "only \"http\" type is supported right now"
if typ ~= "http" and typ ~= "https" then
return nil, "no support for this protocol type"
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style: we need a blank line before the else line here.


local ssl_verify = opts.ssl_verify and true

local http_req = opts.http_req
if not http_req then
return nil, "\"http_req\" option required"
Expand All @@ -527,7 +544,6 @@ function _M.spawn_checker(opts)
local interval = opts.interval
if not interval then
interval = 1

else
interval = interval / 1000
if interval < 0.002 then -- minimum 2ms
Expand Down Expand Up @@ -591,6 +607,8 @@ function _M.spawn_checker(opts)
upstream = u,
primary_peers = preprocess_peers(ppeers),
backup_peers = preprocess_peers(bpeers),
type = typ,
ssl_verify = ssl_verify,
http_req = http_req,
timeout = timeout,
interval = interval,
Expand Down