diff --git a/apisix/plugins/grpc-web.lua b/apisix/plugins/grpc-web.lua index 5771604e74f0..260e84c4eea3 100644 --- a/apisix/plugins/grpc-web.lua +++ b/apisix/plugins/grpc-web.lua @@ -32,6 +32,7 @@ local CONTENT_ENCODING_BINARY = "binary" local DEFAULT_CORS_ALLOW_ORIGIN = "*" local DEFAULT_CORS_ALLOW_METHODS = ALLOW_METHOD_POST local DEFAULT_CORS_ALLOW_HEADERS = "content-type,x-grpc-web,x-user-agent" +local DEFAULT_CORS_EXPOSE_HEADERS = "grpc-message,grpc-status" local DEFAULT_PROXY_CONTENT_TYPE = "application/grpc" @@ -39,7 +40,14 @@ local plugin_name = "grpc-web" local schema = { type = "object", - properties = {}, + properties = { + cors_allow_headers = { + description = + "multiple header use ',' to split. default: content-type,x-grpc-web,x-user-agent.", + type = "string", + default = DEFAULT_CORS_ALLOW_HEADERS + } + } } local grpc_web_content_encoding = { @@ -125,14 +133,14 @@ function _M.header_filter(conf, ctx) local method = core.request.get_method() if method == ALLOW_METHOD_OPTIONS then core.response.set_header("Access-Control-Allow-Methods", DEFAULT_CORS_ALLOW_METHODS) - core.response.set_header("Access-Control-Allow-Headers", DEFAULT_CORS_ALLOW_HEADERS) + core.response.set_header("Access-Control-Allow-Headers", conf.cors_allow_headers) end 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", "grpc-message,grpc-status") + core.response.set_header("Access-Control-Expose-Headers", DEFAULT_CORS_EXPOSE_HEADERS) end function _M.body_filter(conf, ctx) diff --git a/docs/en/latest/plugins/grpc-web.md b/docs/en/latest/plugins/grpc-web.md index a834e0e95fd6..a43ef64c10e8 100644 --- a/docs/en/latest/plugins/grpc-web.md +++ b/docs/en/latest/plugins/grpc-web.md @@ -32,6 +32,12 @@ description: This document contains information about the Apache APISIX grpc-web The `grpc-web` Plugin is a proxy Plugin that can process [gRPC Web](https://github.com/grpc/grpc-web) requests from JavaScript clients to a gRPC service. +## Attributes + +| Name | Type | Required | Default | Description | +|-------------------------|---------|----------|-----------------------------------------|----------------------------------------------------------------------------------------------------------| +| cors_allow_headers | string | False | "content-type,x-grpc-web,x-user-agent" | Headers in the request allowed when accessing a cross-origin resource. Use `,` to add multiple headers. | + ## Enable Plugin You can enable the `grpc-web` Plugin on a specific Route as shown below: diff --git a/docs/zh/latest/plugins/grpc-web.md b/docs/zh/latest/plugins/grpc-web.md index 48077a1c2400..76f4d3dcffb5 100644 --- a/docs/zh/latest/plugins/grpc-web.md +++ b/docs/zh/latest/plugins/grpc-web.md @@ -32,6 +32,12 @@ description: 本文介绍了关于 Apache APISIX `grpc-web` 插件的基本信 `grpc-web` 插件是一个代理插件,可以处理从 JavaScript 客户端到 gRPC Service 的 [gRPC Web](https://github.com/grpc/grpc-web) 请求。 +## 属性 + +| 名称 | 类型 | 必选项 | 默认值 | 描述 | +|---------------------| ------- |----|-----------------------------------------|----------------------------------------------------------------| +| cors_allow_headers | string | 否 | "content-type,x-grpc-web,x-user-agent" | 允许跨域访问时请求方携带哪些非 `CORS 规范` 以外的 Header。如果你有多个 Header,请使用 `,` 分割。 | + ## 启用插件 你可以通过如下命令在指定路由上启用 `gRPC-web` 插件: diff --git a/t/plugin/grpc-web.t b/t/plugin/grpc-web.t index 7069a8c2ccb8..1d3a3647e705 100644 --- a/t/plugin/grpc-web.t +++ b/t/plugin/grpc-web.t @@ -260,3 +260,97 @@ curl -iv --location 'http://127.0.0.1:1984/grpc/web/a6.RouteService/GetRoute' \ --data-binary '@./t/plugin/grpc-web/req.bin' --- response_body eval qr/grpc-status:0\x0d\x0agrpc-message:/ + + + +=== TEST 13: confg default response route +--- config + location /t { + content_by_lua_block { + local config = { + uri = "/grpc/web/*", + upstream = { + scheme = "grpc", + type = "roundrobin", + nodes = { + ["127.0.0.1:50001"] = 1 + } + }, + plugins = { + ["grpc-web"] = {} + } + } + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', ngx.HTTP_PUT, config) + + if code >= 300 then + ngx.status = code + ngx.say(body) + return + end + + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 14: check header in default response +--- request +OPTIONS /grpc/web/a6.RouteService/GetRoute +--- error_code: 204 +--- response_headers +Access-Control-Allow-Methods: POST +Access-Control-Allow-Headers: content-type,x-grpc-web,x-user-agent +Access-Control-Allow-Origin: * +Access-Control-Expose-Headers: grpc-message,grpc-status + + + +=== TEST 15: Custom configuration routing +--- config + location /t { + content_by_lua_block { + local config = { + uri = "/grpc/web/*", + upstream = { + scheme = "grpc", + type = "roundrobin", + nodes = { + ["127.0.0.1:50001"] = 1 + } + }, + plugins = { + ["grpc-web"] = { + cors_allow_headers = "grpc-accept-encoding" + } + } + } + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', ngx.HTTP_PUT, config) + + if code >= 300 then + ngx.status = code + ngx.say(body) + return + end + + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 16: check header in default response +--- request +OPTIONS /grpc/web/a6.RouteService/GetRoute +--- error_code: 204 +--- response_headers +Access-Control-Allow-Methods: POST +Access-Control-Allow-Headers: grpc-accept-encoding +Access-Control-Allow-Origin: * +Access-Control-Expose-Headers: grpc-message,grpc-status