Skip to content

feat: allow skip pass trailers in nginx grpc upstream #100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Apr 16, 2025
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ jobs:
matrix:
op_version:
- "1.25.3.1"
- "1.27.1.1"

runs-on: "ubuntu-20.04"

Expand All @@ -31,6 +32,7 @@ jobs:
sudo apt install -y cpanminus build-essential libncurses5-dev libreadline-dev libssl-dev perl luarocks libpcre3 libpcre3-dev zlib1g-dev
sudo luarocks install lua-resty-http > build.log 2>&1 || (cat build.log && exit 1)
sudo luarocks install lua-resty-openssl > build.log 2>&1 || (cat build.log && exit 1)
cd t/assets/grpc && ./setup.sh > build.log 2>&1 || (cat build.log && exit 1) && cd ../../..

- name: Before install
run: |
Expand Down
18 changes: 18 additions & 0 deletions lib/resty/apisix/upstream.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ local get_phase = ngx.get_phase
local C = ffi.C
local NGX_ERROR = ngx.ERROR
local NGX_OK = ngx.OK
local type = type


base.allows_subsystem("http")
Expand All @@ -15,6 +16,8 @@ typedef intptr_t ngx_int_t;
ngx_int_t ngx_http_apisix_upstream_set_cert_and_key(ngx_http_request_t *r, void *cert, void *key);
ngx_int_t ngx_http_apisix_upstream_set_ssl_trusted_store(ngx_http_request_t *r, void *store);
int ngx_http_apisix_upstream_set_ssl_verify(ngx_http_request_t *r, int verify);

ngx_int_t ngx_http_apisix_set_upstream_pass_trailers(ngx_http_request_t *r, int on);
]])
local _M = {}

Expand Down Expand Up @@ -106,4 +109,19 @@ end
_M.set_ssl_verify = set_ssl_verify


function _M.set_pass_trailers(on)
if type(on) ~= 'boolean' then
return nil, "on expects a boolean but found " .. type(on)
end

local r = get_request()
local ret = C.ngx_http_apisix_set_upstream_pass_trailers(r, on and 1 or 0)
if ret == NGX_ERROR then
return nil, "error while setting upstream pass_trailers"
end

return true
end


return _M
17 changes: 17 additions & 0 deletions patch/1.25.3.1/nginx-upstream_pass_trailers.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
diff --git src/http/ngx_http_upstream.c src/http/ngx_http_upstream.c
index d04d91e..2dd1102 100644
--- src/http/ngx_http_upstream.c
+++ src/http/ngx_http_upstream.c
@@ -2989,6 +2989,12 @@ ngx_http_upstream_process_trailers(ngx_http_request_t *r,
return NGX_OK;
}

+#if (NGX_HTTP_APISIX)
+ if (!ngx_http_apisix_is_upstream_pass_trailers(r)) {
+ return NGX_OK;
+ }
+#endif
+
part = &u->headers_in.trailers.part;
h = part->elts;

17 changes: 17 additions & 0 deletions patch/1.27.1.1/nginx-upstream_pass_trailers.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
diff --git src/http/ngx_http_upstream.c src/http/ngx_http_upstream.c
index d04d91e..2dd1102 100644
--- src/http/ngx_http_upstream.c
+++ src/http/ngx_http_upstream.c
@@ -2989,6 +2989,12 @@ ngx_http_upstream_process_trailers(ngx_http_request_t *r,
return NGX_OK;
}

+#if (NGX_HTTP_APISIX)
+ if (!ngx_http_apisix_is_upstream_pass_trailers(r)) {
+ return NGX_OK;
+ }
+#endif
+
part = &u->headers_in.trailers.part;
h = part->elts;

32 changes: 32 additions & 0 deletions src/ngx_http_apisix_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -1048,3 +1048,35 @@ ngx_http_apisix_error_log_request_id(ngx_conf_t *cf, ngx_command_t *cmd, void *c
return NGX_CONF_OK;
}


ngx_int_t
ngx_http_apisix_set_upstream_pass_trailers(ngx_http_request_t *r, int on)
{
ngx_http_apisix_ctx_t *ctx;

ctx = ngx_http_apisix_get_module_ctx(r);

if (ctx == NULL) {
return NGX_ERROR;
}

ctx->upstream_pass_trailers = on;
ctx->upstream_pass_trailers_set = 1;
return NGX_OK;
}


ngx_int_t
ngx_http_apisix_is_upstream_pass_trailers(ngx_http_request_t *r)
{
ngx_http_apisix_ctx_t *ctx;

ctx = ngx_http_apisix_get_module_ctx(r);

if (ctx != NULL && ctx->upstream_pass_trailers_set) {
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "apisix upstream pass trailers set: %d", ctx->upstream_pass_trailers);
return ctx->upstream_pass_trailers;
}

return 1;
}
5 changes: 5 additions & 0 deletions src/ngx_http_apisix_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ typedef struct {
unsigned body_filter_by_lua_skipped:1;
unsigned upstream_ssl_verify:1;
unsigned upstream_ssl_verify_set:1;
unsigned upstream_pass_trailers:1;
unsigned upstream_pass_trailers_set:1;
} ngx_http_apisix_ctx_t;


Expand Down Expand Up @@ -66,4 +68,7 @@ ngx_flag_t ngx_http_apisix_is_ntls_enabled(ngx_http_conf_ctx_t *conf_ctx);
char * ngx_http_apisix_error_log_request_id(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char * ngx_http_apisix_error_log_init(ngx_conf_t *cf);
char * ngx_http_apisix_error_log_request_id(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

ngx_int_t ngx_http_apisix_set_upstream_pass_trailers(ngx_http_request_t *r, int on);
ngx_int_t ngx_http_apisix_is_upstream_pass_trailers(ngx_http_request_t *r);
#endif /* _NGX_HTTP_APISIX_H_INCLUDED_ */
Loading
Loading