Kong插件開發工具包

Kong插件開發工具包

插件開發工具包(或稱 PDK),是一組 Lua 方法和變量,插件可以使用這些方法和變量實現自己的邏輯,PDK 最初在 Kong 0.14.0 中發佈,PDK 保證從1.0.0版本開始向前兼容,截至本版本,PDK 尚未達到1.0.0,然而插件作者可以放心依賴它與請求、響應或核心組件進行安全可靠的交互
用戶可以通過全局變量訪問插件開發工具包,例如 kong.requestkong.log

kong.version

當前 Kong 節點的版本號,字符串格式
用法:

print(kong.version) -- "0.14.0"

kong.version_num

當前 Kong 節點的版本號,用來做版本比較,整數格式
用法:

if kong.version_num < 13000 then -- 000.130.00 -> 0.13.0
-- no support for Routes & Services
end

kong.pdk_major_version

當前 PDK 的大版本號,整數格式
用法:

if kong.pdk_version_num < 2 then
-- PDK is below version 2
end

kong.pdk_version

當前 PDK 的版本號,字符串格式
用法:

print(kong.pdk_version) -- "1.0.0"

kong.configuration

當前 Kong 節點的配置信息,基於配置文件和環境變量,文件中以逗號分隔的列表此處顯示爲字符串數組
用法:

print(kong.configuration.prefix) -- "/usr/local/kong"
-- this table is read-only; the following throws an error:
kong.configuration.prefix = "foo"

kong.db

Kong 的 DAO 實例(kong.db 模塊),包含對多個實體的訪問對象
用法:

kong.db.services:insert()
kong.db.routes:select()

kong.dns

Kong 的 DNS 解析器實例

kong.worker_events

Kong 的 IPC 模塊實例,用於內部 worker 進程通信

kong.cluster_events

Kong 的集羣事件模塊實例,用於節點間通信

kong.cache

Kong 緩存對象實例

kong.client

Client 模塊是一組方法,通過請求上下文,用於檢索連接到Kong的客戶端的信息

kong.client.get_ip()

返回發起請求的遠程 IP 地址,它將始終返回直連到 Kong 的客戶端的地址,所以,當 Kong 之前有負載均衡器的情況下,這個方法會返回負載均衡器的地址,而不是下游客戶端的地址

  • 段:
certificate, rewrite, access, header_filter, body_filter, log
  • 返回值:
    發起請求的遠程 IP 地址,字符串格式
  • 用法:
-- Given a client with IP 127.0.0.1 making connection through
-- a load balancer with IP 10.0.0.1 to Kong answering the request for
-- https://example.com:1234/v1/movies
kong.client.get_ip() -- "10.0.0.1"

kong.client.get_forwarded_ip()

返回發起請求的遠程 IP 地址,與 kong.client.get_ip 不同,這個方法會考慮到位於 Kong 之前的負載均衡器以及轉發地址,這個方法是否返回轉發地址取決於幾個 Kong 配置參數:trusted_ips、real_ip_header、real_ip_recursive

  • 段:
certificate, rewrite, access, header_filter, body_filter, log
  • 返回值:
    發起請求的遠程 IP 地址,考慮轉發地址,字符串格式
  • 用法:
-- Given a client with IP 127.0.0.1 making connection through
-- a load balancer with IP 10.0.0.1 to Kong answering the request for
-- https://username:[email protected]:1234/v1/movies

kong.request.get_forwarded_ip() -- "127.0.0.1"

-- Note: assuming that 10.0.0.1 is one of the trusted IPs, and that
-- the load balancer adds the right headers matching with the configuration
-- of `real_ip_header`, e.g. `proxy_protocol`.

kong.client.get_port()

返回發起請求的端口,它將始終返回直連到 Kong 的客戶端的端口,所以,當 Kong 之前有負載均衡器的情況下,這個方法會返回負載均衡器的端口,而不是下游客戶端的端口

  • 段:
certificate, rewrite, access, header_filter, body_filter, log
  • 返回值:
    客戶端端口號,整數格式
  • 用法:
-- [client]:40000 <-> 80:[balancer]:30000 <-> 80:[kong]:20000 <-> 80:[service]
kong.client.get_port() -- 30000

kong.client.get_forwarded_port()

返回發起請求的端口,與 kong.client.get_port 不同,這個方法會考慮到位於 Kong 之前的負載均衡器以及轉發端口,這個方法是否返回轉發端口取決於幾個 Kong 配置參數:trusted_ips、real_ip_header、real_ip_recursive

  • 段:
certificate, rewrite, access, header_filter, body_filter, log
  • 返回值:
    客戶端端口號,考慮轉發端口號,整數格式
  • 用法:
-- [client]:40000 <-> 80:[balancer]:30000 <-> 80:[kong]:20000 <-> 80:[service]
kong.client.get_forwarded_port() -- 40000

-- Note: assuming that [balancer] is one of the trusted IPs, and that
-- the load balancer adds the right headers matching with the configuration
-- of `real_ip_header`, e.g. `proxy_protocol`.

kong.client.get_credential()

返回當前經過身份驗證的消費者的憑證,如果未設置,返回 nil

  • 段:
access, header_filter, body_filter, log
  • 返回值:
    經過身份驗證的憑證
  • 用法:
local credential = kong.client.get_credential()
if credential then
consumer_id = credential.consumer_id
else
-- request not authenticated yet
end

kong.client.get_consumer()

返回當前經過身份驗證的消費者實體,如果未設置,返回 nil

  • 段:
access, header_filter, body_filter, log
  • 返回值:
    經過身份驗證的消費者
  • 用法:
local consumer = kong.client.get_consumer()
if consumer then
consumer_id = consumer.id
else
-- request not authenticated yet, or a credential
-- without a consumer (external auth)
end

kong.client.authenticate(consumer, credential)

爲當前請求設置經過身份驗證的消費者或憑證,消費者和憑證必須存在一個,否則方法將報錯

  • 段:
access
  • 參數:
    consumer(table|nil):設置消費者,如果不設置值,之前存在的值會被清空
    credential(table|nil):設置憑證,如果不設置值,之前存在的值會被清空
  • 用法:
-- assuming `credential` and `consumer` have been set by some authentication code
kong.client.authenticate(consumer, credentials)

kong.client.get_protocol(allow_terminated)

返回當前路由匹配的協議,如果沒有路由匹配,返回 nil

  • 段:
access, header_filter, body_filter, log
  • 參數:
    allow_terminated:布爾值,如果設置,則在檢查 https 時檢查 X-Forwarded-Proto 頭
  • 返回值:
  1. string | nil:"http"、"https"、"tcp"、"tls" 或 nil
  2. nil | err:成功返回 nil,失敗返回錯誤信息
  • 用法:
kong.client.get_protocol() -- "http"

kong.ctx

當前請求上下文

kong.ctx.shared

一個 table 結構的數據,它用於在給定請求的多個插件之間共享數據,由於它只與請求的上下文相關,所有無法從 Lua 模塊的頂級塊訪問此表,只能在請求段中訪問,對應插件的 rewriteaccessheader_filterbody_filterlog 接口
所有插件都可以看到單個插件在此 table 中插入的值,與其加護時必須謹慎,因爲命名衝突會導致數據被覆蓋

  • 段:
rewrite, access, header_filter, body_filter, log
  • 用法:
-- Two plugins A and B, and if plugin A has a higher priority than B's
-- (it executes before B):

-- plugin A handler.lua
function plugin_a_handler:access(conf)
kong.ctx.shared.foo = "hello world"

kong.ctx.shared.tab = {
bar = "baz"
}
end

-- plugin B handler.lua
function plugin_b_handler:access(conf)
kong.log(kong.ctx.shared.foo) -- "hello world"
kong.log(kong.ctx.shared.tab.bar) -- "baz"
end

kong.ctx.plugin

一個 table 結構的數據,與 kong.ctx.shared 不同,此 table 不在插件之間共享,相反,它僅對當前插件實例可見,也就是說,如果配置了多個限流插件實例(在不同的服務上),每個實例對於每個請求都有自己的 table
由於它自帶命名空間,所以它比 kong.ctx.shared 更安全,因爲它避免了潛在的命名衝突,這可能導致多個插件在不知不覺中覆蓋了彼此的數據

  • 段:
rewrite, access, header_filter, body_filter, log
  • 用法:
-- plugin handler.lua

function plugin_handler:access(conf)
kong.ctx.plugin.val_1 = "hello"
kong.ctx.plugin.val_2 = "world"
end

function plugin_handler:log(conf)
local value = kong.ctx.plugin.val_1 .. " " .. kong.ctx.plugin.val_2

kong.log(value) -- "hello world"
end

kong.ip

此模塊根據 trusted_ips 配置確定給定的 IP 是否可信

kong.ip.is_trusted(address)

根據 trusted_ips 配置屬性,此方法將返回給定的 IP 是否可信,並且是否同時支持 ipv4 和 ipv6

  • 段:
init_worker, certificate, rewrite, access, header_filter, body_filter, log
  • 參數:
    address(string):IP 地址
  • 返回值:
    true 代表受信,false代表不受信,布爾格式
  • 用法:
if kong.ip.is_trusted("1.1.1.1") then
kong.log("The IP is trusted")
end

kong.log

一個 table 結構的數據,此命名空間包含了日誌工具的實例,含有下述所有方法,每個插件的實例有單獨的命名空間,Kong 確保在執行插件之前,會將實例與專用於插件的日誌工具交換,這允許日誌以插件的名稱作爲前綴,以便進行調試

kong.log(…)

日誌使用當前 Nginx 配置中的 error_log 指令,日誌級別是 notice,Nginx 的 error_log 指令通過 log_levelproxy_error_log 和 admin_error_log 這三個配置設置
傳入此方法的參數的拼接方式與 ngx.log() 類似,日誌中將顯示調用它的 Lua 文件和行號,與 ngx.log() 不同,此方法將使用 [kong],而不是 [lua],作爲錯誤消息的前綴,參數可以是任何格式的,在打印日誌時會調用 tostring 方法轉換成字符串格式
核心生成的日誌格式:

[kong] %file_src:%line_src %message

相比較,插件生成的日誌格式:

[kong] %file_src:%line_src [%namespace] %message
  1. %file_src:調用日誌的文件名
  2. %func_name:調用日誌的方法的名稱
  3. %line_src:調用日誌的行號
  4. %message:日誌消息

示例,調用下列方法:

kong.log("hello ", "world")

核心打印日誌:

2017/07/09 19:36:25 [notice] 25932#0: *1 [kong] some_file.lua:54 hello world, client: 127.0.0.1, server: localhost, request: "GET /log HTTP/1.1", host: "localhost"

插件打印日誌:

2017/07/09 19:36:25 [notice] 25932#0: *1 [kong] some_file.lua:54 [key-auth] hello world, client: 127.0.0.1, server: localhost, request: "GET /log HTTP/1.1", host: "localhost"
  • 段:
init_worker, certificate, rewrite, access, header_filter, body_filter, log
  • 參數:
    在發送到日誌之前,所有的參數會拼接到一起連成字符串
  • 返回值:
    沒有返回,無效的輸入拋錯
  • 用法:
kong.log("hello ", "world") -- alias to kong.log.notice()

kong.log.LEVEL(…)

與 kong.log() 類似,但生成的日誌具有 \<level\> 日誌級別,而不是 notice,支持的日誌級別包括:
kong.log.alert()
kong.log.crit()
kong.log.err()
kong.log.warn()
kong.log.notice()
kong.log.info()
kong.log.debug()
記錄日誌的語法與 kong.log() 類似,例如:

kong.log.err("hello ", "world")

在覈心內會生成一條日誌,如下:

2017/07/09 19:36:25 [error] 25932#0: *1 [kong] some_file.lua:54 hello world, client: 127.0.0.1, server: localhost, request: "GET /log HTTP/1.1", host: "localhost"

如果從插件中調用(例如 key-auth),它將包含命名空間前綴,如下:

2017/07/09 19:36:25 [error] 25932#0: *1 [kong] some_file.lua:54 [key-auth] hello world, client: 127.0.0.1, server: localhost, request: "GET /log HTTP/1.1", host: "localhost"
  • 段:
init_worker, certificate, rewrite, access, header_filter, body_filter, log
  • 參數:
    在發送到日誌之前,所有的參數會拼接到一起連成字符串
  • 返回值:
    沒有返回,無效的輸入拋錯
  • 用法:
kong.log.warn("something require attention")
kong.log.err("something failed: ", err)
kong.log.alert("something requires immediate action")

kong.log.inspect(…)

與 kong.log() 類似,此方法會生成 notice 級別的日誌,並且可以接受任意數量的參數,如果通過 kong.log.inspect.off() 方法禁用了功能,那麼此方法不會打印任何內容

kong.log.inspect("...")

與 kong.log() 不同的是,該方法會在拼接參數時加上空格,這個方法主要用於調試,應避免在生產代碼中使用,因爲它執行了很多格式化操作,消耗資源
kong.log.inspect(…) 的日誌格式如下:

%file_src:%func_name:%line_src %message
  1. %file_src:調用日誌的文件名
  2. %func_name:調用日誌的方法的名稱
  3. %line_src:調用日誌的行號
  4. %message:日誌消息
  • 段:
init_worker, certificate, rewrite, access, header_filter, body_filter, log
  • 參數:
    在發送到日誌之前,所有的參數會拼接到一起連成字符串
  • 用法:
kong.log.inspect("some value", a_variable)

kong.log.inspect.on()

啓用 inspect 日誌功能

  • 段:
init_worker, certificate, rewrite, access, header_filter, body_filter, log
  • 用法:
kong.log.inspect.on()

kong.log.inspect.off()

禁用 notice 日誌功能

  • 段:
init_worker, certificate, rewrite, access, header_filter, body_filter, log
  • 用法:
kong.log.inspect.off()

kong.nginx

Nginx 信息模塊,一組用於檢索 Nginx 實現細節和元信息的方法

kong.nginx.get_subsystem()

  • 段:
any
  • 返回值:
    http 或 stream,字符串格式
  • 用法:
kong.nginx.get_subsystem() -- "http"

kong.node

節點級別信息

kong.node.get_id()

返回此節點用於描述自身的 ID

  • 返回值:
    節點 ID,字符串格式
  • 用法:
local id = kong.node.get_id()

kong.node.get_memory_stats([unit[, scale]])

返回該節點的內存使用數據

  • 參數:
    unit(string, optional):內存計量單位,可以是 b/B、k/K、m/M 或 g/G
    scale(number, optional):精度,默認小數點後兩位
  • 返回值:
    包含此節點的內存使用統計數據,如果單位是 b/B(默認值),則值爲數字,否則統計數據爲字符串,後綴是單位,table 格式
  • 用法:
local res = kong.node.get_memory_stats()
-- res will have the following structure:
{
  lua_shared_dicts = {
    kong = {
      allocated_slabs = 12288,
      capacity = 24576
    },
    kong_db_cache = {
      allocated_slabs = 12288,
      capacity = 12288
    }
  },
  workers_lua_vms = {
    {
      http_allocated_gc = 1102,
      pid = 18004
    },
    {
      http_allocated_gc = 1102,
      pid = 18005
    }
  }
}

local res = kong.node.get_memory_stats("k", 1)
-- res will have the following structure:
{
  lua_shared_dicts = {
    kong = {
      allocated_slabs = "12.0 KiB",
      capacity = "24.0 KiB",
    },
    kong_db_cache = {
      allocated_slabs = "12.0 KiB",
      capacity = "12.0 KiB",
    }
  },
  workers_lua_vms = {
    {
      http_allocated_gc = "1.1 KiB",
      pid = 18004
    },
    {
      http_allocated_gc = "1.1 KiB",
      pid = 18005
    }
  }
}

kong.request

一組方法,用於獲取客戶端發出的請求信息

kong.request.get_scheme()

返回請求 URL 的 schema 組件,返回值爲小寫格式

  • 段:
rewrite, access, header_filter, body_filter, log, admin_api
  • 返回值:
    http 或者 https,字符串格式
  • 用法:
-- Given a request to https://example.com:1234/v1/movies
kong.request.get_scheme() -- "https"

kong.request.get_host()

返回請求 URL 的 host 組件,或者 Host 頭的值,返回值爲小寫格式

  • 段:
rewrite, access, header_filter, body_filter, log, admin_api
  • 返回值:
    主機地址,字符串格式
  • 用法:
-- Given a request to https://example.com:1234/v1/movies
kong.request.get_host() -- "example.com"

kong.request.get_port()

返回請求 URL 的 port 組件

  • 段:
certificate, rewrite, access, header_filter, body_filter, log, admin_api
  • 返回值:
    端口號,整數格式
  • 用法:
-- Given a request to https://example.com:1234/v1/movies
kong.request.get_port() -- 1234

kong.request.get_forwarded_scheme()

返回請求 URL 的 schema 組件,如果請求來自可信源,也會考慮 X-Forwarded-Proto 請求頭,返回值爲小寫格式,該方法是否考慮 X-Forwarded-Proto 請求頭取決於幾個 Kong 配置參數:trusted_ips、real_ip_header、real_ip_recursive

  • 段:
rewrite, access, header_filter, body_filter, log, admin_api
  • 返回值:
    轉發的 schema,字符串格式
  • 用法:
kong.request.get_forwarded_scheme()  -- "https"

kong.request.get_forwarded_host()

返回請求 URL 的 host 組件,不同於 kong.request.get_host(),如果請求來自可信源,也會考慮 X-Forwarded-Host 請求頭,該方法是否考慮 X-Forwarded-Host 請求頭取決於幾個 Kong 配置參數:trusted_ips、real_ip_header、real_ip_recursive

  • 段:
rewrite, access, header_filter, body_filter, log, admin_api
  • 返回值:
    轉發的主機地址,字符串格式
  • 用法:
kong.request.get_forwarded_host()  -- "example.com"

kong.request.get_forwareded_port()

返回請求 URL 的 port 組件,如果請求來自可信源,也會考慮 X-Forwarded-Host 請求頭,該方法是否考慮 X-Forwarded-Proto 請求頭取決於幾個 Kong 配置參數:trusted_ips、real_ip_header、real_ip_recursive

  • 段:
rewrite, access, header_filter, body_filter, log, admin_api
  • 返回值:
    轉發的端口,整數格式
  • 用法:
kong.request.get_forwarded_port()  -- 1234

kong.request.get_http_version()

返回 Http 協議使用的版本號,返回值爲 1.1 或 2.0

  • 段:
rewrite, access, header_filter, body_filter, log, admin_api
  • 返回值:
    字符串類型,或者是 nil
  • 用法:
kong.request.get_http_version()  -- "1.1"

kong.request.get_method()

返回請求的 Http 方法,返回值爲大寫格式

  • 段:
rewrite, access, header_filter, body_filter, log, admin_api
  • 返回值:
    請求方法,字符串格式
  • 用法:
kong.request.get_method()  -- "GET"

kong.request.get_path()

返回請求 URL 的 path 組件,不包含請求參數

  • 段:
rewrite, access, header_filter, body_filter, log, admin_api
  • 返回值:
    請求路徑,字符串格式
  • 用法:
-- Given a request to https://example.com:1234/v1/movies?movie=foo
kong.request.get_path() -- "/v1/movies"

kong.request.get_path_with_query()

返回請求 URL 的 path 組件,包含請求參數

  • 段:
rewrite, access, header_filter, body_filter, log, admin_api
  • 返回值:
    請求路徑,包含請求參數,字符串格式
  • 用法:
-- Given a request to https://example.com:1234/v1/movies?movie=foo
kong.request.get_path_with_query() -- "/v1/movies?movie=foo"

kong.request.get_raw_query()

返回請求 URL 的 query 組件,不包含 ? 字符

  • 段:
rewrite, access, header_filter, body_filter, log, admin_api
  • 返回值:
    請求參數
  • 用法:
-- Given a request to https://example.com/foo?msg=hello%20world&bla=&bar
kong.request.get_raw_query() -- "msg=hello%20world&bla=&bar"

kong.request.get_query_arg()

返回從當前請求的查詢參數獲取的指定參數的值,如果參數有值,返回的是字符串或者布爾類型,如果找不到參數,返回 nil,如果查詢參數中多次出現具有相同名稱的參數,該方法返回第一次出現的值

  • 段:
rewrite, access, header_filter, body_filter, log, admin_api
  • 返回值:
    請求參數,字符串類型、布爾類型、nil
  • 用法:
-- Given a request GET /test?foo=hello%20world&bar=baz&zzz&blo=&bar=bla&bar
kong.request.get_query_arg("foo") -- "hello world"
kong.request.get_query_arg("bar") -- "baz"
kong.request.get_query_arg("zzz") -- true
kong.request.get_query_arg("blo") -- ""

kong.request.get_query([max_args])

返回從請求參數提取的參數表,鍵是參數名稱,值是參數值,鍵和值都未經轉義,默認情況下,這個方法返回100個參數,可以指定 max_args 調整這個值,參數範圍是1至1000

  • 段:
rewrite, access, header_filter, body_filter, log, admin_api
  • 參數:
    max_args(number, optional):參數表的最大個數
  • 返回值:
    請求參數,table 格式
  • 用法:
-- Given a request GET /test?foo=hello%20world&bar=baz&zzz&blo=&bar=bla&bar
for k, v in pairs(kong.request.get_query()) do
  kong.log.inspect(k, v)
end
-- Will print
-- "foo" "hello world"
-- "bar" {"baz", "bla", true}
-- "zzz" true
-- "blo" ""

kong.request.get_header(name)

返回請求頭的值,請求頭名不區分大小寫,並全部採用小寫形式,- 可以寫成 _,比如 X-Custom-Header 可以寫成 x_custom_header

  • 段:
rewrite, access, header_filter, body_filter, log, admin_api
  • 參數:
    name(string):請求頭的名稱
  • 返回值:
    請求頭的值,字符串類型或者 nil
  • 用法:
-- Given a request with the following headers:
-- Host: foo.com
-- X-Custom-Header: bla
-- X-Another: foo bar
-- X-Another: baz
kong.request.get_header("Host")            -- "foo.com"
kong.request.get_header("x-custom-header") -- "bla"
kong.request.get_header("X-Another")       -- "foo bar"

kong.request.get_headers([max_headers])

返回請求頭表,鍵是請求頭名,值是請求頭值,默認情況下,這個方法返回100個請求頭,可以指定 max_headers 調整這個值,參數範圍是1至1000

  • 段:
rewrite, access, header_filter, body_filter, log, admin_api
  • 參數:
    max_headers(number, optional):請求頭表的最大個數
  • 返回值:
    請求頭,table 格式
  • 用法:
-- Given a request with the following headers:
-- Host: foo.com
-- X-Custom-Header: bla
-- X-Another: foo bar
-- X-Another: baz
local headers = kong.request.get_headers()
headers.host            -- "foo.com"
headers.x_custom_header -- "bla"
headers.x_another[1]    -- "foo bar"
headers["X-Another"][2] -- "baz"

kong.request.get_raw_body()

返回請求體,如果請求體沒有內容,該方法返回一個空字符串,如果請求體大小大於 Nginx 緩衝區大小(通過 client_body_buffer_size 設置),該方法會失敗並返回錯誤信息

  • 段:
rewrite, access, admin_api
  • 返回值:
    請求體,字符串格式
  • 用法:
-- Given a body with payload "Hello, Earth!":
kong.request.get_raw_body():gsub("Earth", "Mars") -- "Hello, Mars!"

kong.request.get_body([mimetype[, max_args]])

以鍵值對形式返回請求體數據,請求體以最合適的格式解析:

  1. 如果指定了 mimetype,根據 content type 對請求體進行解碼
  2. 如果 content type 是 application/x-www-form-urlencoded,以 form-encoded 形式返回請求體
  3. 如果 content type 是 multipart/form-data,以上述方式解析,multipart(kong.request.get_raw_body(), kong.request.get_header("Content-Type")):get_all()
  4. 如果 content type 是 application/json,以 JSON 形式解析請求體,JSON 格式對應 Lua 的基本類型
  5. 如果不是上述情況,返回 nil 表示請求未被解析
    mimetype 可以取以下值:application/x-www-form-urlencodedapplication/jsonmultipart/form-data
    max_args 限定 application/x-www-form-urlencoded 解析參數的個數
  • 段:
rewrite, access, admin_api
  • 參數:
    mimetype(string, optional):mimetype
    max_args(number, optional):請求體表的最大個數
  • 返回值:
  1. 請求體,table 格式或 nil
  2. 錯誤信息,table 格式或 nil
  3. mimetype 類型,table 格式或 nil
  • 用法:
local body, err, mimetype = kong.request.get_body()
body.name -- "John Doe"
body.age  -- "42"

kong.response

響應模塊,其中包含了一組方法,用於生成和操作發送發送給客戶端的響應,響應可以由 Kong 生成,或者從服務的響應體中代理過來

kong.response.get_status()

返回當前爲下游響應設置的的 Http 狀態碼,如果請求被代理,則返回值將是來自 Service 的響應值(與 kong.service.response.get_status() 相同),如果請求未被代理,並且響應是由 Kong 本身產生的(比如通過 kong.response.exit()),則返回值將按原樣返回

  • 段:
header_filter, body_filter, log, admin_api
  • 返回值:
    爲下游響應設置的 Http 狀態碼
  • 用法:
kong.response.get_status()  -- 200

kong.response.get_header(name)

返回指定響應頭的值,該函數包含來自代理服務的響應頭和 Kong 添加的響應頭(例如,通過 kong.response.add_header()

  • 段:
header_filter, body_filter, log, admin_api
  • 參數:
    name(string):請求頭的名稱,請求頭名不區分大小寫,並全部採用小寫形式,- 可以寫成 _,比如 X-Custom-Header 可以寫成 x_custom_header
  • 返回值:
    響應頭的值,字符串格式或 nil
  • 用法:
-- Given a response with the following headers:
-- X-Custom-Header: bla
-- X-Another: foo bar
-- X-Another: baz

kong.response.get_header("x-custom-header") -- "bla"
kong.response.get_header("X-Another")       -- "foo bar"
kong.response.get_header("X-None")          -- nil

kong.response.get_headers([max_headers])

包含響應頭的 Lua table,與 kong.service.response.get_headers() 不同,該方法會返回客戶端接收到的所有響應頭,包括 Kong 本身添加的響應有,默認情況下,該方法最多返回100個響應頭,可以指定 max_headers 調整這個值,參數範圍是1至1000

  • 段:
header_filter, body_filter, log, admin_api
  • 參數:
    max_headers(number, optional):
  • 返回值:
  1. 響應中的響應頭 table,table 格式
  2. 如果響應頭數目超過 max_headers,返回 truncated,字符串格式
  • 用法:
-- Given an response from the Service with the following headers:
-- X-Custom-Header: bla
-- X-Another: foo bar
-- X-Another: baz

local headers = kong.response.get_headers()

headers.x_custom_header -- "bla"
headers.x_another[1]    -- "foo bar"
headers["X-Another"][2] -- "baz"

kong.response.get_source()

這個方法確定當前響應的來源,返回值可能包含三類字符串:

  1. exit:調用了 kong.response.exit(),即請求被插件或 Kong 本身短路的時候
  2. error:發生錯誤,比如連接到上游服務超時,返回 error
  3. service:連接到代理服務,返回 service
  • 段:
header_filter, body_filter, log, admin_api
  • 返回值:
    響應源,字符串格式
  • 用法:
if kong.response.get_source() == "service" then
  kong.log("The response comes from the Service")
elseif kong.response.get_source() == "error" then
  kong.log("There was an error while processing the request")
elseif kong.response.get_source() == "exit" then
  kong.log("There was an early exit while processing the request")
end

kong.response.set_status(status)

更改 Http 狀態碼,這個方法應該在 header_filter 段中使用,此時 Kong 準備將響應頭髮送回客戶端

  • 段:
rewrite, access, header_filter, admin_api
  • 參數:
    status(number):新的 Http 狀態碼
  • 返回值:
    無;無效的輸入拋出錯誤
  • 用法:
kong.response.set_status(404)

kong.response.set_header(name, value)

設置響應頭,會覆蓋已經存在的響應頭,這個方法應該在 header_filter 段中使用,此時 Kong 準備將響應頭髮送回客戶端

  • 段:
rewrite, access, header_filter, admin_api
  • 參數:
    name(string): 響應頭的名稱
    value(string,number,boolean):響應頭的值
  • 返回值:
    無;無效的輸入拋出錯誤
  • 用法:
kong.response.set_header("X-Foo",  "value")

kong.response.add_header(name, value)

設置響應頭,與 kong.response.set_header() 不同,這個方法不會覆蓋已經存在的響應頭,另外相同的響應頭可以繼續添加在響應中,這個方法應該在 header_filter 段中使用,此時 Kong 準備將響應頭髮送回客戶端

  • 段:
rewrite, access, header_filter, admin_api
  • 參數:
    name(string): 響應頭的名稱
    value(string,number,boolean):響應頭的值
  • 返回值:
    無;無效的輸入拋出錯誤
  • 用法:
kong.response.add_header("Cache-Control", "no-cache")
kong.response.add_header("Cache-Control", "no-store")

kong.response.clear_header(name)

刪除響應頭,這個方法應該在 header_filter 段中使用,此時 Kong 準備將響應頭髮送回客戶端

  • 段:
rewrite, access, header_filter, admin_api
  • 參數:
    name(string): 需要清除的響應頭的名稱
  • 返回值:
    無;無效的輸入拋出錯誤
  • 用法:
kong.response.set_header("X-Foo", "foo")
kong.response.add_header("X-Foo", "bar")

kong.response.clear_header("X-Foo")
-- from here onwards, no X-Foo headers will exist in the response

kong.response.set_headers(headers)

設置響應頭,與 kong.response.set_header() 不同,headers 參數是一個 table,鍵是字符串格式,值是字符串或字符串數組,這個方法應該在 header_filter 段中使用,此時 Kong 準備將響應頭髮送回客戶端,此方法會覆蓋已經存在的響應頭

  • 段:
rewrite, access, header_filter, admin_api
  • 參數:
    headers(table)
  • 返回值:
    無;無效的輸入拋出錯誤
  • 用法:
kong.response.set_headers({
  ["Bla"] = "boo",
  ["X-Foo"] = "foo3",
  ["Cache-Control"] = { "no-store", "no-cache" }
})

-- Will add the following headers to the response, in this order:
-- X-Bar: bar1
-- Bla: boo
-- Cache-Control: no-store
-- Cache-Control: no-cache
-- X-Foo: foo3

kong.response.exit(status[, body[, headers]])

  • 段:
rewrite, access, admin_api, header_filter (僅當 body 爲 nil 時)
  • 參數:
  1. status(number):Http 狀態碼
  2. body(table,string,optional):響應體
  3. headers(table,optional):響應頭
  • 返回值:
    無;無效的輸入拋出錯誤
  • 用法:
return kong.response.exit(403, "Access Forbidden", {
  ["Content-Type"] = "text/plain",
  ["WWW-Authenticate"] = "Basic"
})

---

return kong.response.exit(403, [[{"message":"Access Forbidden"}]], {
  ["Content-Type"] = "application/json",
  ["WWW-Authenticate"] = "Basic"
})

---

return kong.response.exit(403, { message = "Access Forbidden" }, {
  ["WWW-Authenticate"] = "Basic"
})

kong.router

route 模塊包含一組方法,用於訪問請求的路由屬性

kong.router.get_route()

返回路由實體,請求與此路由匹配

  • 段:
access, header_filter, body_filter, log
  • 返回值:
    路由實體,table 格式
  • 用法:
if kong.router.get_route() then
  -- routed by route & service entities
else
  -- routed by a legacy API entity
end

kong.router.get_service()

返回當前服務實體,請求會路由到這個服務上

  • 段:
access, header_filter, body_filter, log
  • 返回值:
    服務實體,table 格式
  • 用法:
if kong.router.get_service() then
  -- routed by route & service entities
else
  -- routed by a legacy API entity
end

kong.service

service 模塊包含一組方法,用於操作請求連接到服務上的屬性,比如連接的主機,IP 地址或端口,用於負載均衡和健康檢查的 upstream 實體

kong.service.set_upstream(host)

設置所需的 upstream 實體處理請求的負載均衡,使用此方法相當於創建一個配置了 host 屬性的服務,並關聯到了相應的 upstream 實體(這種情況下,請求將代理到綁定到這個 upstream 的 target 上)
host 參數接收一個字符串,字符串內容需要與配置的 upstream 實體一致

  • 段:
access
  • 參數:
    host(string)
  • 返回值:
  1. 成功返回 true,沒有找到 upstream 實體返回 nil
  2. 錯誤發生時返回字符串格式的錯誤,沒有返回 nil
  • 用法:
local ok, err = kong.service.set_upstream("service.prod")
if not ok then
  kong.log.err(err)
  return
end

kong.service.set_target(host, port)

設置代理該請求的主機和端口地址,使用這個方法相當於要求 Kong 在接收請求時不執行負載均衡階段,而是手動覆蓋它,這個請求還會忽略重試和健康檢查等負載均衡組件,host 參數爲字符串格式,是一個(IPv4/IPv6地址),port 參數爲端口號

  • 段:
access
  • 參數:
    host(string)
    port(number)
  • 用法:
kong.service.set_target("service.local", 443)
kong.service.set_target("192.168.130.1", 80)

kong.service.set_tls_cert_key(chain, key)

設置與服務器端握手時使用的客戶端證書,chain 參數是由 ngx.ssl.parse_pem_cert 等方法返回的客戶端證書和中間鏈,key 參數是與 ngx.ssl.parse_pem_priv_key 等方法返回的客戶端證書對應的私鑰

  • 段:
rewrite, access, balancer
  • 參數:
    chain(cdata):客戶端證書鏈
    key(cdata):客戶端證書私鑰
  • 返回值:
  1. 操作成功返回 true,發生錯誤返回 nil
  2. 錯誤發生時返回字符串格式的錯誤,沒有返回 nil
  • 用法:
local chain = assert(ssl.parse_pem_cert(cert_data))
local key = assert(ssl.parse_pem_priv_key(key_data))

local ok, err = tls.set_cert_key(chain, key)
if not ok then
  -- do something with error
end

kong.service.request

操作連接上服務的請求

kong.service.request.set_scheme(scheme)

在將請求路由到服務時設置 Http 協議

  • 段:
access
  • 參數:
    schema(string):Http 協議,支持 http 或 https
  • 返回值:
    無;無效的輸入拋出錯誤
  • 用法:
kong.service.request.set_scheme("https")

kong.service.request.set_path(path)

設置請求路徑,不包含請求參數

  • 段:
access
  • 參數:
    path(string):請求路徑
  • 返回值:
    無;無效的輸入拋出錯誤
  • 用法:
kong.service.request.set_path("/v2/movies")

kong.service.request.set_raw_query(query)

設置請求參數,query 參數是字符串格式(不包含 ? 字符),並且不會以任何方式處理,更高階的設置請求參數方法參考 kong.service.request.set_query()

  • 段:
rewrite,access
  • 參數:
    query(string):原生的請求參數
  • 返回值:
    無;無效的輸入拋出錯誤
  • 用法:
kong.service.request.set_raw_query("zzz&bar=baz&bar=bla&bar&blo=&foo=hello%20world")

kong.service.request.set_method(method)

設置 Http 方法

  • 段:
rewrite,access
  • 參數:
    method(string):Http 方法,需要大小,支持的方法有:GETHEADPUTPOSTDELETEOPTIONSMKCOLCOPYMOVEPROPFINDPROPPATCHLOCKUNLOCKPATCHTRACE
  • 返回值:
    無;無效的輸入拋出錯誤
  • 用法:
kong.service.request.set_method("DELETE")

kong.service.request.set_query(args)

設置請求參數,與 kong.service.request.set_raw_query() 不同,args 參數必須是 table 格式,鍵是字符串類型,值可以是布爾值、字符串或數組,所有字符串都進行 URL 編碼,生成的查詢字符串根據字典順序排序,保留同一鍵內的值順序,如果需要進一步控制生成請求參數,可以使用 kong.service.request.set_raw_query() 方法

  • 段:
rewrite,access
  • 參數:
    args(table):
  • 返回值:
    無;無效的輸入拋出錯誤
  • 用法:
kong.service.request.set_query({
  foo = "hello world",
  bar = {"baz", "bla", true},
  zzz = true,
  blo = ""
})
-- Will produce the following query string:
-- bar=baz&bar=bla&bar&blo=&foo=hello%20world&zzz

kong.service.request.set_header(header, value)

設置請求頭,會覆蓋已經存在的請求頭,如果 header 參數是 host(大小寫不敏感),會同時設置請求的 SNI

  • 段:
rewrite,access
  • 參數:
    header(string):請求頭名稱
    value(string,boolean,number):請求頭值
  • 返回值:
    無;無效的輸入拋出錯誤
  • 用法:
kong.service.request.set_header("X-Foo",  "value")

kong.service.request.add_header(header, value)

設置請求頭,與 kong.service.request.set_header() 不同,不會覆蓋已經存在的請求頭

  • 段:
rewrite,access
  • 參數:
    header(string):請求頭名稱
    value(string,boolean,number):請求頭值
  • 返回值:
    無;無效的輸入拋出錯誤
  • 用法:
kong.service.request.add_header("Cache-Control", "no-cache")
kong.service.request.add_header("Cache-Control", "no-store")

kong.service.request.clear_header(header)

清除請求頭

  • 段:
rewrite,access
  • 參數:
    header(string):請求頭名稱
  • 返回值:
    無;無效的輸入拋出錯誤
  • 用法:
kong.service.request.set_header("X-Foo", "foo")
kong.service.request.add_header("X-Foo", "bar")
kong.service.request.clear_header("X-Foo")
-- from here onwards, no X-Foo headers will exist in the request

kong.service.request.set_headers(headers)

設置請求頭,與 kong.service.request.set_header() 不同,headers 參數必須是 table 格式的

  • 段:
rewrite,access
  • 參數:
    headers(table):table 格式的請求頭集合
  • 返回值:
    無;無效的輸入拋出錯誤
  • 用法:
kong.service.request.set_header("X-Foo", "foo1")
kong.service.request.add_header("X-Foo", "foo2")
kong.service.request.set_header("X-Bar", "bar1")
kong.service.request.set_headers({
  ["X-Foo"] = "foo3",
  ["Cache-Control"] = { "no-store", "no-cache" },
  ["Bla"] = "boo"
})

-- Will add the following headers to the request, in this order:
-- X-Bar: bar1
-- Bla: boo
-- Cache-Control: no-store
-- Cache-Control: no-cache
-- X-Foo: foo3

kong.service.request.set_raw_body(body)

設置請求體,body 參數必須是一個字符串,不會以任何方式處理處理,這個方法還會添加 Content-Length 頭,如果想設置空請求體,直接設置空字符串,更高階的設置參考 kong.service.request.set_body()

  • 段:
rewrite,access
  • 參數:
    body(string):原始 body 請求體
  • 返回值:
    無;無效的輸入拋出錯誤
  • 用法:
kong.service.request.set_raw_body("Hello, world!")

kong.service.request.set_body(args[, mimetype])

設置請求體,與 kong.service.request.set_body() 不同,args 必須是 table 格式,並且以 MIME type 格式編碼

  1. 如果 MIME type 是 application/x-www-form-urlencoded
    以 form-encoded 方式對參數進行編碼
  2. 如果 MIME type 是 multipart/form-data
    以 multipart form data 方式對參數進行編碼
  3. 如果 MIME type 是 application/json
    以 JSON 格式對參數進行編碼
  • 段:
rewrite,access
  • 參數:
    args(table):請求體參數,會轉化成相應的格式
    mimetype(string,optional)
  • 返回值:
  1. 成功返回 true,失敗返回 nil
  2. 錯誤返回失敗信息,成果返回 nil
  • 用法:
kong.service.set_header("application/json")
local ok, err = kong.service.request.set_body({
  name = "John Doe",
  age = 42,
  numbers = {1, 2, 3}
})

-- Produces the following JSON body:
-- { "name": "John Doe", "age": 42, "numbers":[1, 2, 3] }

local ok, err = kong.service.request.set_body({
  foo = "hello world",
  bar = {"baz", "bla", true},
  zzz = true,
  blo = ""
}, "application/x-www-form-urlencoded")

-- Produces the following body:
-- bar=baz&bar=bla&bar&blo=&foo=hello%20world&zzz

kong.service.response

操作服務的響應

kong.service.response.get_status()

從服務返回的響應的 Http 狀態碼

  • 段:
header_filter, body_filter, log
  • 返回值:
    從服務返回的響應的 Http 狀態碼,整數格式;如果請求未被代理,返回 nil
  • 用法:
kong.log.inspect(kong.service.response.get_status())  -- 418

kong.service.response.get_headers([max_headers])

包含響應頭的 Lua table,與 kong.response.get_headers() 不同,該方法僅會返回服務返回的響應中的請求頭(忽略 Kong 本身添加的),如果請求未被代理到任何服務(比如被鑑權插件拒絕了並且產生了401響應),headers 值是 nil,因爲服務沒有任何響應,默認情況下,該方法最多返回100個響應頭,可以指定 max_headers 調整這個值,參數範圍是1至1000

  • 段:
header_filter, body_filter, log
  • 參數:
    max_header(number, optional):
  • 返回值:
  1. 響應頭,table 格式
  2. 如果響應頭數目超過 max_headers,返回 truncated,字符串格式
  • 用法:
-- Given a response with the following headers:
-- X-Custom-Header: bla
-- X-Another: foo bar
-- X-Another: baz
local headers = kong.service.response.get_headers()
if headers then
  kong.log.inspect(headers.x_custom_header) -- "bla"
  kong.log.inspect(headers.x_another[1])    -- "foo bar"
  kong.log.inspect(headers["X-Another"][2]) -- "baz"
end

kong.service.response.get_header(name)

返回指定響應頭的值,與 kong.response.get_header() 不同,這個方法只會返回服務的響應中的請求頭(忽略 Kong 本身添加的)

  • 段:
header_filter, body_filter, log
  • 參數:
    name(string):響應頭的名稱
  • 返回值:
    指定響應頭的值,字符串格式;如果沒有請求頭,返回 nil
  • 用法:
-- Given a response with the following headers:
-- X-Custom-Header: bla
-- X-Another: foo bar
-- X-Another: baz

kong.log.inspect(kong.service.response.get_header("x-custom-header")) -- "bla"
kong.log.inspect(kong.service.response.get_header("X-Another"))       -- "foo bar"

kong.table

Lua table 工具類

kong.table.new([narr[, nrec]])

返回一個 table,其中包含了預先分配的數組和散列

  • 參數:
    narr(number, optional):指定在數組組件中預分佈的插槽數
    nrec(number, optional):指定在散列組件中預分佈的插槽數
  • 返回值:
    新創建的 table,table 格式
  • 用法:
local  tab  =  kong.table.new(4,  4)

kong.table.clear(tab)

清理 table

  • 參數:
    tab(table):需要被清理的 table
  • 返回值:
  • 用法:
local tab = {
  "hello",
  foo = "bar"
}

kong.table.clear(tab)

kong.log(tab[1]) -- nil
kong.log(tab.foo) -- nil

 

2人點贊

 

Kong中文文檔

轉自:https://www.jianshu.com/p/bf7f7bfb0639

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章