107 lines
2.6 KiB
Lua
107 lines
2.6 KiB
Lua
-- Copyright (c) Kong Inc. 2020
|
|
|
|
local deco = require "kong.plugins.grpc-web.deco"
|
|
local kong_meta = require "kong.meta"
|
|
|
|
local ngx = ngx
|
|
local kong = kong
|
|
|
|
local string_format = string.format
|
|
|
|
local ngx_arg = ngx.arg
|
|
local ngx_var = ngx.var
|
|
|
|
local kong_request_get_path = kong.request.get_path
|
|
local kong_request_get_header = kong.request.get_header
|
|
local kong_request_get_method = kong.request.get_method
|
|
local kong_request_get_raw_body = kong.request.get_raw_body
|
|
local kong_response_exit = kong.response.exit
|
|
local kong_response_set_header = kong.response.set_header
|
|
local kong_service_request_set_header = kong.service.request.set_header
|
|
local kong_service_request_set_raw_body = kong.service.request.set_raw_body
|
|
|
|
|
|
local grpc_web = {
|
|
PRIORITY = 3,
|
|
VERSION = kong_meta.version,
|
|
}
|
|
|
|
|
|
local CORS_HEADERS = {
|
|
["Content-Type"] = "application/grpc-web-text+proto",
|
|
["Access-Control-Allow-Origin"] = "*",
|
|
["Access-Control-Allow-Methods"] = "POST",
|
|
["Access-Control-Allow-Headers"] = "content-type,x-grpc-web,x-user-agent",
|
|
}
|
|
|
|
function grpc_web:access(conf)
|
|
kong_response_set_header("Access-Control-Allow-Origin", conf.allow_origin_header)
|
|
|
|
if kong_request_get_method() == "OPTIONS" then
|
|
CORS_HEADERS["Access-Control-Allow-Origin"] = conf.allow_origin_header
|
|
return kong_response_exit(200, "OK", CORS_HEADERS)
|
|
end
|
|
|
|
local uri
|
|
if conf.pass_stripped_path then
|
|
uri = ngx_var.upstream_uri
|
|
ngx.req.set_uri(uri)
|
|
else
|
|
uri = kong_request_get_path()
|
|
end
|
|
|
|
local dec, err = deco.new(
|
|
kong_request_get_header("Content-Type"),
|
|
uri, conf.proto)
|
|
|
|
if not dec then
|
|
kong.log.err(err)
|
|
return kong_response_exit(400, err)
|
|
end
|
|
|
|
kong.ctx.plugin.dec = dec
|
|
|
|
kong_service_request_set_header("Content-Type", "application/grpc")
|
|
kong_service_request_set_header("TE", "trailers")
|
|
kong_service_request_set_raw_body(dec:upstream(kong_request_get_raw_body()))
|
|
end
|
|
|
|
|
|
function grpc_web:header_filter(conf)
|
|
if kong_request_get_method() == "OPTIONS" then
|
|
return
|
|
end
|
|
|
|
local dec = kong.ctx.plugin.dec
|
|
if dec then
|
|
kong_response_set_header("Content-Type", dec.mimetype)
|
|
end
|
|
end
|
|
|
|
|
|
function grpc_web:body_filter(conf)
|
|
if kong_request_get_method() ~= "POST" then
|
|
return
|
|
end
|
|
local dec = kong.ctx.plugin.dec
|
|
if not dec then
|
|
return
|
|
end
|
|
|
|
local chunk, eof = ngx_arg[1], ngx_arg[2]
|
|
|
|
chunk = dec:downstream(chunk)
|
|
|
|
if eof and dec.framing == "grpc" then
|
|
chunk = chunk .. dec:frame(0x80, string_format(
|
|
"grpc-status:%s\r\ngrpc-message:%s\r\n",
|
|
ngx_var["sent_trailer_grpc_status"] or "0",
|
|
ngx_var["sent_trailer_grpc_message"] or ""))
|
|
end
|
|
|
|
ngx_arg[1] = chunk
|
|
end
|
|
|
|
|
|
return grpc_web
|