lxbme commented on issue #13673:
URL: https://github.com/apache/apisix/issues/13673#issuecomment-4921754993
Hi @mcupei, thanks for the issue. I've reproduced this bug and it seems
caused by a rebase mistake at api7/apisix-nginx-module repository.
## Reproduction
Confirmed with byte-identical standalone configs, only swapping the image
tag (`apache/apisix:3.16.0-debian` vs `3.17.0-debian`, default
`client_max_body_size: 0`):
| Test (11-byte body `hello=world`) | 3.16.0 | 3.17.0 |
|---|---|---|
| POST with `Content-Length` | 201 | 200 |
| POST with `Transfer-Encoding: chunked` | 200 | **413** |
Error log on 3.17:
```
[error] client intended to send too large chunked body: 0+11 bytes
```
An 11-byte body triggering "too large" shows this is not a real size
overflow.
## Root cause
APISIX 3.17 bumped the base from OpenResty **1.27.1.2** (apisix-runtime
1.3.3, apisix-nginx-module 1.19.3) to **1.29.2.4** (apisix-runtime 1.3.6,
apisix-nginx-module 1.19.5). It is **not** an upstream nginx change — vanilla
`nginx:1.29.2` with `client_max_body_size 0` proxies chunked requests fine, and
so does a bare (Lua-free) nginx built from the 3.16 image. The regression is in
the rebased patch in apisix-nginx-module:
`patch/1.29.2.4/nginx-client_max_body_size.patch`, hunk for
`ngx_http_request_body_chunked_filter()`:
```c
/* old patch (1.27.1.1, module 1.19.3) — correct */
if (max_body_size
&& max_body_size
- r->headers_in.content_length_n < rb->chunked->size)
/* new patch (1.29.2.4, module 1.19.5 / 1.19.6 / master) — guard line lost
in rebase */
if (max_body_size
- r->headers_in.content_length_n < rb->chunked->size)
```
The `&& max_body_size` zero-guard (which implements nginx's "0 = unlimited"
semantics) was dropped. With the default `client_max_body_size 0`, the check
becomes `0 - 0 < 11` → true → 413 for **every** HTTP/1.1 chunked request,
regardless of size. That's exactly the `0+11 bytes` in the log.
Requests with `Content-Length` take a different code path whose guards are
intact, which is why only chunked requests fail. The HTTP/2 hunk in the same
patch kept its guard, so only the HTTP/1.1 chunked path is affected. Note this
also breaks the `client-control` plugin's dynamic path:
`set_client_max_body_size(0)` returns 413 on 3.17 as well.
## Fix
Restore the lost guard line in
[`patch/1.29.2.4/nginx-client_max_body_size.patch#L86`](https://github.com/api7/apisix-nginx-module/blob/1.19.5/patch/1.29.2.4/nginx-client_max_body_size.patch#L86)
(still missing on `master` and tag `1.19.6`):
```diff
-@@ -1139,8 +1165,14 @@
ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
+@@ -1139,8 +1165,15 @@
ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
...
+ if (max_body_size
++ && max_body_size
+#else
```
This makes the hunk identical in shape to the old `1.27.1.1` patch. For any
non-zero limit `X`, `X && (X - n < s)` is equivalent to `X - n < s`, so the
change only affects the `0` case — restoring the "0 = unlimited" behavior with
no other behavior change.
I verified the fix by building openresty-1.29.2.4 + apisix-nginx-module
1.19.5 twice (as shipped vs. with the guard restored):
- As-shipped build reproduces the bug exactly (chunked + limit `0` → 413).
- Fixed build: chunked with limit `0` → 200 (11B and 5MB bodies); non-zero
limits still enforced (1m limit, 2MB chunked → 413); exact boundary preserved
(20-byte limit: 20B → 200, 21B → 413); `client-control` dynamic path correct
(`set_client_max_body_size(5)` → 413, `(0)` → 200).
- The fixed patch applies cleanly on a pristine openresty-1.29.2.4 tree.
Shipping it would need a new apisix-nginx-module tag, an apisix-runtime
release, and rebuilt 3.17.x images. Until then, a verified workaround for users
is setting any non-zero limit in `config.yaml`:
```yaml
nginx_config:
http:
client_max_body_size: 1000m
```
@Baoyuantop What do you think of this fix?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]