插件开发工具包(或称 PDK),是一组 Lua 方法和变量,插件可以使用这些方法和变量实现自己的逻辑,PDK 最初在 Kong 0.14.0 中发布,PDK 保证从1.0.0版本开始向前兼容,截至本版本,PDK 尚未达到1.0.0,然而插件作者可以放心依赖它与请求、响应或核心组件进行安全可靠的交互
用户可以通过全局变量访问插件开发工具包,例如 kong.request
、kong.log
当前 Kong 节点的版本号,字符串格式
用法:
print(kong.version) -- "0.14.0"
当前 Kong 节点的版本号,用来做版本比较,整数格式
用法:
if kong.version_num < 13000 then -- 000.130.00 -> 0.13.0
-- no support for Routes & Services
end
当前 PDK 的大版本号,整数格式
用法:
if kong.pdk_version_num < 2 then
-- PDK is below version 2
end
当前 PDK 的版本号,字符串格式
用法:
print(kong.pdk_version) -- "1.0.0"
当前 Kong 节点的配置信息,基于配置文件和环境变量,文件中以逗号分隔的列表此处显示为字符串数组
用法:
print(kong.configuration.prefix) -- "/usr/local/kong"
-- this table is read-only; the following throws an error:
kong.configuration.prefix = "foo"
Kong 的 DAO 实例(kong.db 模块),包含对多个实体的访问对象
用法:
kong.db.services:insert()
kong.db.routes:select()
Kong 的 DNS 解析器实例
Kong 的 IPC 模块实例,用于内部 worker 进程通信
Kong 的集群事件模块实例,用于节点间通信
Kong 缓存对象实例
Client 模块是一组方法,通过请求上下文,用于检索连接到Kong的客户端的信息
返回发起请求的远程 IP 地址,它将始终返回直连到 Kong 的客户端的地址,所以,当 Kong 之前有负载均衡器的情况下,这个方法会返回负载均衡器的地址,而不是下游客户端的地址
certificate, rewrite, access, header_filter, body_filter, log
-- 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"
返回发起请求的远程 IP 地址,与 kong.client.get_ip
不同,这个方法会考虑到位于 Kong 之前的负载均衡器以及转发地址,这个方法是否返回转发地址取决于几个 Kong 配置参数:trusted_ips、real_ip_header、real_ip_recursive
certificate, rewrite, access, header_filter, body_filter, log
-- 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 的客户端的端口,所以,当 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_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`.
返回当前经过身份验证的消费者的凭证,如果未设置,返回 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
返回当前经过身份验证的消费者实体,如果未设置,返回 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
为当前请求设置经过身份验证的消费者或凭证,消费者和凭证必须存在一个,否则方法将报错
access
-- assuming `credential` and `consumer` have been set by some authentication code
kong.client.authenticate(consumer, credentials)
返回当前路由匹配的协议,如果没有路由匹配,返回 nil
access, header_filter, body_filter, log
X-Forwarded-Proto
头kong.client.get_protocol() -- "http"
当前请求上下文
一个 table 结构的数据,它用于在给定请求的多个插件之间共享数据,由于它只与请求的上下文相关,所有无法从 Lua 模块的顶级块访问此表,只能在请求段中访问,对应插件的 rewrite
、access
、header_filter
、body_filter
、log
接口
所有插件都可以看到单个插件在此 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
一个 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
此模块根据 trusted_ips
配置确定给定的 IP 是否可信
根据 trusted_ips
配置属性,此方法将返回给定的 IP 是否可信,并且是否同时支持 ipv4 和 ipv6
init_worker, certificate, rewrite, access, header_filter, body_filter, log
if kong.ip.is_trusted("1.1.1.1") then
kong.log("The IP is trusted")
end
一个 table 结构的数据,此命名空间包含了日志工具的实例,含有下述所有方法,每个插件的实例有单独的命名空间,Kong 确保在执行插件之前,会将实例与专用于插件的日志工具交换,这允许日志以插件的名称作为前缀,以便进行调试
日志使用当前 Nginx 配置中的 error_log
指令,日志级别是 notice
,Nginx 的 error_log
指令通过 log_level
、proxy_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
%file_src
:调用日志的文件名%func_name
:调用日志的方法的名称%line_src
:调用日志的行号%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()
类似,但生成的日志具有 \
日志级别,而不是 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()
类似,此方法会生成 notice
级别的日志,并且可以接受任意数量的参数,如果通过 kong.log.inspect.off()
方法禁用了功能,那么此方法不会打印任何内容
kong.log.inspect("...")
与 kong.log()
不同的是,该方法会在拼接参数时加上空格,这个方法主要用于调试,应避免在生产代码中使用,因为它执行了很多格式化操作,消耗资源kong.log.inspect(…)
的日志格式如下:
%file_src:%func_name:%line_src %message
%file_src
:调用日志的文件名%func_name
:调用日志的方法的名称%line_src
:调用日志的行号%message
:日志消息init_worker, certificate, rewrite, access, header_filter, body_filter, log
kong.log.inspect("some value", a_variable)
启用 inspect
日志功能
init_worker, certificate, rewrite, access, header_filter, body_filter, log
kong.log.inspect.on()
禁用 notice
日志功能
init_worker, certificate, rewrite, access, header_filter, body_filter, log
kong.log.inspect.off()
Nginx 信息模块,一组用于检索 Nginx 实现细节和元信息的方法
any
http
或 stream
,字符串格式kong.nginx.get_subsystem() -- "http"
节点级别信息
返回此节点用于描述自身的 ID
local id = kong.node.get_id()
返回该节点的内存使用数据
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
}
}
}
一组方法,用于获取客户端发出的请求信息
返回请求 URL 的 schema 组件,返回值为小写格式
rewrite, access, header_filter, body_filter, log, admin_api
-- Given a request to https://example.com:1234/v1/movies
kong.request.get_scheme() -- "https"
返回请求 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"
返回请求 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
返回请求 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
kong.request.get_forwarded_scheme() -- "https"
返回请求 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"
返回请求 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
返回 Http 协议使用的版本号,返回值为 1.1
或 2.0
rewrite, access, header_filter, body_filter, log, admin_api
kong.request.get_http_version() -- "1.1"
返回请求的 Http 方法,返回值为大写格式
rewrite, access, header_filter, body_filter, log, admin_api
kong.request.get_method() -- "GET"
返回请求 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"
返回请求 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"
返回请求 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"
返回从当前请求的查询参数获取的指定参数的值,如果参数有值,返回的是字符串或者布尔类型,如果找不到参数,返回 nil,如果查询参数中多次出现具有相同名称的参数,该方法返回第一次出现的值
rewrite, access, header_filter, body_filter, log, admin_api
-- 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") -- ""
返回从请求参数提取的参数表,键是参数名称,值是参数值,键和值都未经转义,默认情况下,这个方法返回100个参数,可以指定 max_args
调整这个值,参数范围是1至1000
rewrite, access, header_filter, body_filter, log, admin_api
-- 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" ""
返回请求头的值,请求头名不区分大小写,并全部采用小写形式,-
可以写成 _
,比如 X-Custom-Header
可以写成 x_custom_header
rewrite, access, header_filter, body_filter, log, admin_api
-- 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"
返回请求头表,键是请求头名,值是请求头值,默认情况下,这个方法返回100个请求头,可以指定 max_headers
调整这个值,参数范围是1至1000
rewrite, access, header_filter, body_filter, log, admin_api
-- 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"
返回请求体,如果请求体没有内容,该方法返回一个空字符串,如果请求体大小大于 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!"
以键值对形式返回请求体数据,请求体以最合适的格式解析:
mimetype
,根据 content type 对请求体进行解码application/x-www-form-urlencoded
,以 form-encoded 形式返回请求体multipart/form-data
,以上述方式解析,multipart(kong.request.get_raw_body(), kong.request.get_header("Content-Type")):get_all()
application/json
,以 JSON 形式解析请求体,JSON 格式对应 Lua 的基本类型mimetype
可以取以下值:application/x-www-form-urlencoded
、application/json
、multipart/form-data
max_args
限定 application/x-www-form-urlencoded
解析参数的个数rewrite, access, admin_api
local body, err, mimetype = kong.request.get_body()
body.name -- "John Doe"
body.age -- "42"
响应模块,其中包含了一组方法,用于生成和操作发送发送给客户端的响应,响应可以由 Kong 生成,或者从服务的响应体中代理过来
返回当前为下游响应设置的的 Http 状态码,如果请求被代理,则返回值将是来自 Service 的响应值(与 kong.service.response.get_status()
相同),如果请求未被代理,并且响应是由 Kong 本身产生的(比如通过 kong.response.exit()
),则返回值将按原样返回
header_filter, body_filter, log, admin_api
kong.response.get_status() -- 200
返回指定响应头的值,该函数包含来自代理服务的响应头和 Kong 添加的响应头(例如,通过 kong.response.add_header()
)
header_filter, body_filter, log, admin_api
-
可以写成 _
,比如 X-Custom-Header
可以写成 x_custom_header
-- 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
包含响应头的 Lua table,与 kong.service.response.get_headers()
不同,该方法会返回客户端接收到的所有响应头,包括 Kong 本身添加的响应有,默认情况下,该方法最多返回100个响应头,可以指定 max_headers
调整这个值,参数范围是1至1000
header_filter, body_filter, log, admin_api
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.exit()
,即请求被插件或 Kong 本身短路的时候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
更改 Http 状态码,这个方法应该在 header_filter
段中使用,此时 Kong 准备将响应头发送回客户端
rewrite, access, header_filter, admin_api
kong.response.set_status(404)
设置响应头,会覆盖已经存在的响应头,这个方法应该在 header_filter
段中使用,此时 Kong 准备将响应头发送回客户端
rewrite, access, header_filter, admin_api
kong.response.set_header("X-Foo", "value")
设置响应头,与 kong.response.set_header()
不同,这个方法不会覆盖已经存在的响应头,另外相同的响应头可以继续添加在响应中,这个方法应该在 header_filter
段中使用,此时 Kong 准备将响应头发送回客户端
rewrite, access, header_filter, admin_api
kong.response.add_header("Cache-Control", "no-cache")
kong.response.add_header("Cache-Control", "no-store")
删除响应头,这个方法应该在 header_filter
段中使用,此时 Kong 准备将响应头发送回客户端
rewrite, access, header_filter, admin_api
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_header()
不同,headers
参数是一个 table,键是字符串格式,值是字符串或字符串数组,这个方法应该在 header_filter
段中使用,此时 Kong 准备将响应头发送回客户端,此方法会覆盖已经存在的响应头
rewrite, access, header_filter, admin_api
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
rewrite, access, admin_api, header_filter (仅当 body 为 nil 时)
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"
})
route 模块包含一组方法,用于访问请求的路由属性
返回路由实体,请求与此路由匹配
access, header_filter, body_filter, log
if kong.router.get_route() then
-- routed by route & service entities
else
-- routed by a legacy API entity
end
返回当前服务实体,请求会路由到这个服务上
access, header_filter, body_filter, log
if kong.router.get_service() then
-- routed by route & service entities
else
-- routed by a legacy API entity
end
service 模块包含一组方法,用于操作请求连接到服务上的属性,比如连接的主机,IP 地址或端口,用于负载均衡和健康检查的 upstream 实体
设置所需的 upstream 实体处理请求的负载均衡,使用此方法相当于创建一个配置了 host
属性的服务,并关联到了相应的 upstream 实体(这种情况下,请求将代理到绑定到这个 upstream 的 target 上)host
参数接收一个字符串,字符串内容需要与配置的 upstream 实体一致
access
local ok, err = kong.service.set_upstream("service.prod")
if not ok then
kong.log.err(err)
return
end
设置代理该请求的主机和端口地址,使用这个方法相当于要求 Kong 在接收请求时不执行负载均衡阶段,而是手动覆盖它,这个请求还会忽略重试和健康检查等负载均衡组件,host
参数为字符串格式,是一个(IPv4/IPv6地址),port
参数为端口号
access
kong.service.set_target("service.local", 443)
kong.service.set_target("192.168.130.1", 80)
设置与服务器端握手时使用的客户端证书,chain
参数是由 ngx.ssl.parse_pem_cert 等方法返回的客户端证书和中间链,key
参数是与 ngx.ssl.parse_pem_priv_key 等方法返回的客户端证书对应的私钥
rewrite, access, balancer
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
操作连接上服务的请求
在将请求路由到服务时设置 Http 协议
access
http
或 https
kong.service.request.set_scheme("https")
设置请求路径,不包含请求参数
access
kong.service.request.set_path("/v2/movies")
设置请求参数,query
参数是字符串格式(不包含 ?
字符),并且不会以任何方式处理,更高阶的设置请求参数方法参考 kong.service.request.set_query()
rewrite,access
kong.service.request.set_raw_query("zzz&bar=baz&bar=bla&bar&blo=&foo=hello%20world")
设置 Http 方法
rewrite,access
GET
、HEAD
、PUT
、POST
、DELETE
、OPTIONS
、MKCOL
、COPY
、MOVE
、PROPFIND
、PROPPATCH
、LOCK
、UNLOCK
、PATCH
、TRACE
kong.service.request.set_method("DELETE")
设置请求参数,与 kong.service.request.set_raw_query()
不同,args
参数必须是 table 格式,键是字符串类型,值可以是布尔值、字符串或数组,所有字符串都进行 URL 编码,生成的查询字符串根据字典顺序排序,保留同一键内的值顺序,如果需要进一步控制生成请求参数,可以使用 kong.service.request.set_raw_query()
方法
rewrite,access
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
设置请求头,会覆盖已经存在的请求头,如果 header
参数是 host
(大小写不敏感),会同时设置请求的 SNI
rewrite,access
kong.service.request.set_header("X-Foo", "value")
设置请求头,与 kong.service.request.set_header()
不同,不会覆盖已经存在的请求头
rewrite,access
kong.service.request.add_header("Cache-Control", "no-cache")
kong.service.request.add_header("Cache-Control", "no-store")
清除请求头
rewrite,access
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_header()
不同,headers
参数必须是 table 格式的
rewrite,access
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
设置请求体,body 参数必须是一个字符串,不会以任何方式处理处理,这个方法还会添加 Content-Length
头,如果想设置空请求体,直接设置空字符串,更高阶的设置参考 kong.service.request.set_body()
rewrite,access
kong.service.request.set_raw_body("Hello, world!")
设置请求体,与 kong.service.request.set_body()
不同,args
必须是 table 格式,并且以 MIME type 格式编码
application/x-www-form-urlencoded
:multipart/form-data
:application/json
:rewrite,access
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
操作服务的响应
从服务返回的响应的 Http 状态码
header_filter, body_filter, log
kong.log.inspect(kong.service.response.get_status()) -- 418
包含响应头的 Lua table,与 kong.response.get_headers()
不同,该方法仅会返回服务返回的响应中的请求头(忽略 Kong 本身添加的),如果请求未被代理到任何服务(比如被鉴权插件拒绝了并且产生了401响应),headers
值是 nil
,因为服务没有任何响应,默认情况下,该方法最多返回100个响应头,可以指定 max_headers
调整这个值,参数范围是1至1000
header_filter, body_filter, log
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.response.get_header()
不同,这个方法只会返回服务的响应中的请求头(忽略 Kong 本身添加的)
header_filter, body_filter, log
-- 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"
Lua table 工具类
返回一个 table,其中包含了预先分配的数组和散列
local tab = kong.table.new(4, 4)
清理 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