feat: add max_req_body_size to bound client request body in forward-auth and ai-proxy#13466
Conversation
When request_method is POST, the plugin reads the entire client request body into memory to forward it to the authorization service, with no upper bound. Add a max_req_body_size option (integer, default 1048576, minimum 1) passed to core.request.get_body() so oversized bodies are rejected with 413 instead of being buffered without limit.
|
P1 blocker: the PR description and documentation need to explicitly document this default behavior change. This PR adds Please update the PR description and the
|
…e forward-auth default Extend the max_req_body_size request-body cap to the AI proxy plugins and align the forward-auth default: - ai-proxy / ai-proxy-multi: add max_req_body_size (default 67108864 = 64 MiB); oversized requests are rejected with 413 in access() before the body is parsed for LLM proxying - forward-auth: raise the max_req_body_size default from 1 MiB to 64 MiB so existing large-body POST auth flows are not affected by the default Docs and e2e tests updated.
|
@membphis addressed: the PR description now includes an explicit Default behavior change section documenting exactly when the 64 MiB default is observable, and the user-facing docs for forward-auth, ai-proxy, and ai-proxy-multi document the new |
ai-proxy/ai-proxy-multi enforced max_req_body_size by calling core.request.get_body(max) at the top of access() and discarding the result. get_body() does not cache, and the body is read again immediately by detect_request_type -> get_json_request_body_table, so every request buffered the body twice. For large AI JSON bodies (which nginx spills to a temp file) this doubled the body read and cost ~7-9% throughput in benchmarks (1/5/10 MB). Read the body once instead: - core.request.get_request_body_table / get_json_request_body_table take an optional max_size, forwarded to their single internal get_body() call. - ai-proxy/base.lua detect_request_type forwards the limit into that parse and maps an oversized body to 413 (preserving the "failed to read request body" log); all other read/parse failures stay 400. - ai-proxy / ai-proxy-multi drop the read-and-discard get_body() block and run detect_request_type first, so oversized requests are rejected before any balancer / DNS / health-check work.
…ealthcheck After moving detect_request_type to the top of the access phase, a no-body warm-up request short-circuits with 400 before pick_ai_instance runs, so the active health checker is never created and the unhealthy instance is not marked down during the sleep. Send a valid body in the warm-up so it reaches instance selection and bootstraps the checker, as before.
565793e
Description
Several plugins read the entire client request body into memory with no upper bound, which lets a client force a worker to buffer an arbitrarily large body. The only existing backstop is the global nginx
client_max_body_size, which operators routinely raise or disable for upload routes.This adds a
max_req_body_sizeoption (integer, default67108864= 64 MiB, minimum1) to the affected request-body readers, so oversized requests are rejected with413before the body is buffered/parsed:forward-auth: caps the POST body forwarded to the authorization service (passed tocore.request.get_body()).ai-proxy/ai-proxy-multi: caps the body parsed for LLM proxying, enforced at the top ofaccess().Docs and e2e tests are included.
These plugins now default
max_req_body_sizeto 64 MiB. The change is observable only when all of the following hold:forward-authwithrequest_method=POST, orai-proxy/ai-proxy-multi; andclient_max_body_sizeabove 64 MiB (or set it to0); andIn that case the request is now rejected with
413instead of being buffered in full. Under the defaultclient_max_body_size(1 MiB) there is no change. The limit is configurable viamax_req_body_sizeto restore prior behavior.Which issue(s) this PR fixes:
Fixes #
Checklist
max_req_body_size)