Skip to content

Commit

Permalink
chore: format code
Browse files Browse the repository at this point in the history
  • Loading branch information
bzp2010 committed Feb 24, 2025
1 parent 30e60f2 commit 26fc40b
Showing 1 changed file with 52 additions and 46 deletions.
98 changes: 52 additions & 46 deletions apisix/plugins/grpc-web.lua
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,32 @@ function _M.check_schema(conf)
return core.schema.check(schema, conf)
end

local function exit(ctx, status)
ctx.grpc_web_skip_body_filter = true
return status
end

local build_trailer = function (grpc_status, grpc_message)
local status_str = "grpc-status:" .. grpc_status
local status_msg = "grpc-message:" .. ( grpc_message or "")
local grpc_web_trailer = status_str .. "\r\n" .. status_msg .. "\r\n"
local len = #grpc_web_trailer

-- 1 byte: 0x80
local trailer_buf = string.char(0x80)
-- 4 bytes: length of the trailer
trailer_buf = trailer_buf .. string.char(
bit.band(bit.rshift(len, 24), 0xff),
bit.band(bit.rshift(len, 16), 0xff),
bit.band(bit.rshift(len, 8), 0xff),
bit.band(len, 0xff)
)
-- n bytes: trailer
trailer_buf = trailer_buf .. grpc_web_trailer

return trailer_buf
end

function _M.access(conf, ctx)
-- set context variable mime
-- When processing non gRPC Web requests, `mime` can be obtained in the context
Expand All @@ -76,19 +102,19 @@ function _M.access(conf, ctx)

local method = core.request.get_method()
if method == ALLOW_METHOD_OPTIONS then
return 204
return exit(ctx, 204)
end

if method ~= ALLOW_METHOD_POST then
-- https://github.com/grpc/grpc-web/blob/master/doc/browser-features.md#cors-support
core.log.error("request method: `", method, "` invalid")
return 400
return exit(ctx, 405)
end

local encoding = grpc_web_content_encoding[ctx.grpc_web_mime]
if not encoding then
core.log.error("request Content-Type: `", ctx.grpc_web_mime, "` invalid")
return 400
return exit(ctx, 400)
end

-- set context variable encoding method
Expand All @@ -98,7 +124,7 @@ function _M.access(conf, ctx)
if not (ctx.curr_req_matched and ctx.curr_req_matched[":ext"]) then
core.log.error("routing configuration error, grpc-web plugin only supports ",
"`prefix matching` pattern routing")
return 400
return exit(ctx, 400)
end

local path = ctx.curr_req_matched[":ext"]
Expand All @@ -110,16 +136,17 @@ function _M.access(conf, ctx)

-- set grpc body
local body, err = core.request.get_body()
if err then
if err or not body then
core.log.error("failed to read request body, err: ", err)
return 400
return exit(ctx, 400)
end

if encoding == CONTENT_ENCODING_BASE64 then
body = decode_base64(body)
ngx.log(ngx.WARN, "DECODE BODY: ", body)
if not body then
core.log.error("failed to decode request body")
return 400
return exit(ctx, 400)
end
end

Expand All @@ -139,11 +166,19 @@ function _M.header_filter(conf, ctx)
if not ctx.cors_allow_origins then
core.response.set_header("Access-Control-Allow-Origin", DEFAULT_CORS_ALLOW_ORIGIN)
end
core.response.set_header("Content-Type", ctx.grpc_web_mime)
core.response.set_header("Access-Control-Expose-Headers", DEFAULT_CORS_EXPOSE_HEADERS)

if not ctx.grpc_web_skip_body_filter then
core.response.set_header("Content-Type", ctx.grpc_web_mime)
core.response.set_header("Content-Length", nil)
end
end

function _M.body_filter(conf, ctx)
if ctx.grpc_web_skip_body_filter then
return
end

-- If the MIME extension type description of the gRPC-Web standard is not obtained,
-- indicating that the request is not based on the gRPC Web specification,
-- the processing of the request body will be ignored
Expand Down Expand Up @@ -176,46 +211,17 @@ function _M.body_filter(conf, ctx)
local status = ctx.var.upstream_trailer_grpc_status
local message = ctx.var.upstream_trailer_grpc_message

local build_trailer = function (grpc_status, grpc_message)
local status_str = "grpc-status:" .. grpc_status
local status_msg = "grpc-message:" .. ( grpc_message or "")
local grpc_web_trailer = status_str .. "\r\n" .. status_msg .. "\r\n"
local len = #grpc_web_trailer

-- 1 byte: 0x80
local trailer_buf = string.char(0x80)
-- 4 bytes: length of the trailer
trailer_buf = trailer_buf .. string.char(
bit.band(bit.rshift(len, 24), 0xff),
bit.band(bit.rshift(len, 16), 0xff),
bit.band(bit.rshift(len, 8), 0xff),
bit.band(len, 0xff)
)
-- n bytes: trailer
trailer_buf = trailer_buf .. grpc_web_trailer

return trailer_buf
end

local attach_trailer = function (trailer_buf)
if ctx.grpc_web_encoding == CONTENT_ENCODING_BINARY then
ngx_arg[1] = ngx_arg[1] .. trailer_buf
else
ngx_arg[1] = ngx_arg[1] .. encode_base64(trailer_buf)
end

-- clear trailer
ctx.var.upstream_trailer_grpc_status = nil
ctx.var.upstream_trailer_grpc_message = nil
end

-- When the response body completes and still does not receive the grpc status
if status == nil or status == "" then
core.log.error("upstream grpc status not received")
attach_trailer(build_trailer(2, "upstream grpc status not received"))
else
attach_trailer(build_trailer(status, message))
local resp_ok = status ~= nil and status ~= ""
local trailer_buf = build_trailer(
resp_ok and status or 2,
resp_ok and message or "upstream grpc status not received"
)
if ctx.grpc_web_encoding == CONTENT_ENCODING_BASE64 then
trailer_buf = encode_base64(trailer_buf)
end

ngx_arg[1] = ngx_arg[1] .. trailer_buf
end
end

Expand Down

0 comments on commit 26fc40b

Please sign in to comment.