diff --git a/lib/resty/healthcheck.lua b/lib/resty/healthcheck.lua index d7dbf4c8..f754cf9a 100644 --- a/lib/resty/healthcheck.lua +++ b/lib/resty/healthcheck.lua @@ -39,6 +39,10 @@ local re_find = ngx.re.find local bit = require("bit") local ngx_worker_exiting = ngx.worker.exiting local ssl = require("ngx.ssl") +local isarray = require("table.isarray") +local nkeys = require("table.nkeys") +local new_tab = require("table.new") +local escape_uri = ngx.escape_uri -- constants local EVENT_SOURCE_PREFIX = "lua-resty-healthcheck" @@ -919,8 +923,26 @@ function checker:run_single_check(ip, port, hostname, hostheader) end local req_headers = self.checks.active.headers - local headers = table.concat(req_headers, "\r\n") - if #headers > 0 then + local headers + local headers_length = nkeys(req_headers) + if headers_length > 0 then + if isarray(req_headers) then + self:log(WARN, "array headers is deprecated") + headers = table.concat(req_headers, "\r\n") + return + end + + headers = new_tab(0, headers_length) + local idx = 0 + for k, v in pairs(req_headers) do + -- `k` is header name and `v` is header value + idx = idx + 1 + headers[idx] = escape_uri(k) .. ":" .. escape_uri(v) + end + headers = table.concat(headers, "\r\n") + end + + if headers and #headers > 0 then headers = headers .. "\r\n" end @@ -1271,7 +1293,7 @@ local defaults = { http_path = "/", https_sni = NO_DEFAULT, https_verify_certificate = true, - headers = {""}, + headers = NO_DEFAULT, healthy = { interval = 0, -- 0 = disabled by default http_statuses = { 200, 302 }, @@ -1347,7 +1369,7 @@ end -- * `checks.active.http_path`: path to use in `GET` HTTP request to run on active checks -- * `checks.active.https_sni`: SNI server name incase of HTTPS -- * `checks.active.https_verify_certificate`: boolean indicating whether to verify the HTTPS certificate --- * `checks.active.hheaders`: an array of headers (no hash-table! must be pre-formatted) +-- * `checks.active.headers`: one or more lists of values indexed by header name -- * `checks.active.healthy.interval`: interval between checks for healthy targets (in seconds) -- * `checks.active.healthy.http_statuses`: which HTTP statuses to consider a success -- * `checks.active.healthy.successes`: number of successes to consider a target healthy diff --git a/t/20-req-headers.t b/t/20-req-headers.t index 304315db..896ca03d 100644 --- a/t/20-req-headers.t +++ b/t/20-req-headers.t @@ -15,7 +15,7 @@ run_tests(); __DATA__ -=== TEST 1: headers: {"User-Agent", "curl/7.29.0"} +=== TEST 1: headers: {"User-Agent: curl/7.29.0"} --- http_config eval qq{ $::HttpConfig @@ -65,7 +65,7 @@ Host: 127.0.0.1 -=== TEST 2: headers: {"User-Agent", "curl"} +=== TEST 2: headers: {"User-Agent: curl"} --- http_config eval qq{ $::HttpConfig @@ -112,3 +112,53 @@ checking healthy targets: #1 GET /status HTTP/1.0 User-Agent: curl Host: 127.0.0.1 + + + +=== TEST 3: headers: {["User-Agent"] = {"curl"}} +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2112; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local we = require "resty.worker.events" + assert(we.configure{ shm = "my_worker_events", interval = 0.1 }) + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0.1 + }, + headers = { ["User-Agent"] = {"curl"} } + } + } + }) + ngx.sleep(0.2) -- wait twice the interval + local ok, err = checker:add_target("127.0.0.1", 2112, nil, true) + ngx.say(ok) + ngx.sleep(0.2) -- wait twice the interval + } + } +--- request +GET /t +--- response_body +true +--- error_log +checking healthy targets: nothing to do +checking healthy targets: #1 +GET /status HTTP/1.0 +User-Agent: curl +Host: 127.0.0.1