fix: insert AI Gateway extproc after the buffer filter - #2227
Conversation
When an EnvoyPatchPolicy (or similar) adds an HTTP buffer filter to raise the request buffer limit, insertAIGatewayExtProcFilter could place the AI Gateway extproc ahead of the buffer filter. Because that extproc runs in RequestBodyMode: BUFFERED, it then buffers the request body against Envoy Gateway's default 32 KiB downstream per-connection buffer limit and rejects large request bodies with 413 Payload Too Large before the buffer filter's larger limit can take effect. (This is the downstream listener limit, not the 50 MiB limit AI Gateway sets on its extproc UDS cluster.) Envoy Gateway's canonical filter order already places the buffer filter before the ext_proc filters, so when a buffer filter sits at or after the chosen insertion point, insert the AI Gateway extproc immediately after the last buffer filter. The AI Gateway extproc is then the first ext_proc filter to run after the buffer filter rather than the first ext_proc filter overall, so a user-supplied ext_proc placed ahead of the buffer filter still runs before it. Behavior is unchanged when no buffer filter exists. The extension server only changes the placement of its own filter; it does not relocate the user's buffer filter, so this fixes the 413 for AI Gateway's BUFFERED extproc specifically rather than for every co-resident ext_proc. Signed-off-by: Chris Burns <29541485+ChrisJBurns@users.noreply.github.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2227 +/- ##
==========================================
+ Coverage 84.73% 84.75% +0.01%
==========================================
Files 144 144
Lines 21189 21195 +6
==========================================
+ Hits 17955 17963 +8
+ Misses 2152 2151 -1
+ Partials 1082 1081 -1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
/reetst |
|
Hi @ChrisJBurns , just wanted to check I am working on a PR: #2158 where you will be able to configure exact (or prefixed, under discussion) filter name which would be allowed to run before ai-gateway-extproc, could it be useful to solve your usecase as well? |
|
Thanks for flagging this @siddharth1036 - we're definitely in the same code path. I think they're complementary rather than overlapping though: your allowlist is opt-in, but the buffer filter ordering needs to apply by default since it's a correctness fix (large bodies get a 413 otherwise). Could we treat the buffer filter as an always-on default in #2158, or let the automatic buffer handling stack on top of your allowlist? |
**Description** **Problem** If a buffer filter (`envoy.filters.http.buffer`) is added to the chain, for example via an EnvoyPatchPolicy to raise the request buffer limit, the AI Gateway extproc could be placed ahead of it. The AI Gateway extproc runs with `RequestBodyMode: BUFFERED`, so when it runs before the buffer filter it buffers the body against Envoy Gateway's default 32 KiB downstream per-connection limit and returns `413 Payload Too Large` for larger bodies before the buffer filter's higher limit applies. The buffer filter raises the stream's buffer limit to `max_request_bytes`, but only for filters that decode after it. This was hit in practice with large request bodies such as Gemini CLI tool definitions. **Solution** When a buffer filter sits at or after the computed ext_proc insertion point, insert the AI Gateway extproc immediately after the last buffer filter. Envoy Gateway already orders the buffer filter before ext_proc, so this honors that order. Behavior is unchanged when no buffer filter is present. This works because EnvoyPatchPolicy patches are applied before the extension hook runs and Envoy Gateway does not re-sort filters afterward, so the buffer filter is visible to this code. The extension server only moves its own filter, not the user's buffer filter, so this fixes the 413 for AI Gateway's extproc specifically and not for other co-resident BUFFERED ext_procs. **Testing** Added table tests for three cases: ext_proc before buffer (inserted after buffer), buffer before ext_proc (inserted after buffer), and no buffer filter (unchanged). Signed-off-by: Chris Burns <29541485+ChrisJBurns@users.noreply.github.com> Co-authored-by: Ignasi Barrera <ignasi@tetrate.io> Signed-off-by: yxia216 <yxia216@bloomberg.net>
**Description** **Problem** If a buffer filter (`envoy.filters.http.buffer`) is added to the chain, for example via an EnvoyPatchPolicy to raise the request buffer limit, the AI Gateway extproc could be placed ahead of it. The AI Gateway extproc runs with `RequestBodyMode: BUFFERED`, so when it runs before the buffer filter it buffers the body against Envoy Gateway's default 32 KiB downstream per-connection limit and returns `413 Payload Too Large` for larger bodies before the buffer filter's higher limit applies. The buffer filter raises the stream's buffer limit to `max_request_bytes`, but only for filters that decode after it. This was hit in practice with large request bodies such as Gemini CLI tool definitions. **Solution** When a buffer filter sits at or after the computed ext_proc insertion point, insert the AI Gateway extproc immediately after the last buffer filter. Envoy Gateway already orders the buffer filter before ext_proc, so this honors that order. Behavior is unchanged when no buffer filter is present. This works because EnvoyPatchPolicy patches are applied before the extension hook runs and Envoy Gateway does not re-sort filters afterward, so the buffer filter is visible to this code. The extension server only moves its own filter, not the user's buffer filter, so this fixes the 413 for AI Gateway's extproc specifically and not for other co-resident BUFFERED ext_procs. **Testing** Added table tests for three cases: ext_proc before buffer (inserted after buffer), buffer before ext_proc (inserted after buffer), and no buffer filter (unchanged). Signed-off-by: Chris Burns <29541485+ChrisJBurns@users.noreply.github.com> Co-authored-by: Ignasi Barrera <ignasi@tetrate.io> Signed-off-by: yxia216 <yxia216@bloomberg.net>
Description
Problem
If a buffer filter (
envoy.filters.http.buffer) is added to the chain, for example via an EnvoyPatchPolicy to raise the request buffer limit, the AI Gateway extproc could be placed ahead of it. The AI Gateway extproc runs withRequestBodyMode: BUFFERED, so when it runs before the buffer filter it buffers the body against Envoy Gateway's default 32 KiB downstream per-connection limit and returns413 Payload Too Largefor larger bodies before the buffer filter's higher limit applies.The buffer filter raises the stream's buffer limit to
max_request_bytes, but only for filters that decode after it. This was hit in practice with large request bodies such as Gemini CLI tool definitions.Solution
When a buffer filter sits at or after the computed ext_proc insertion point, insert the AI Gateway extproc immediately after the last buffer filter. Envoy Gateway already orders the buffer filter before ext_proc, so this honors that order. Behavior is unchanged when no buffer filter is present.
This works because EnvoyPatchPolicy patches are applied before the extension hook runs and Envoy Gateway does not re-sort filters afterward, so the buffer filter is visible to this code.
The extension server only moves its own filter, not the user's buffer filter, so this fixes the 413 for AI Gateway's extproc specifically and not for other co-resident BUFFERED ext_procs.
Testing
Added table tests for three cases: ext_proc before buffer (inserted after buffer), buffer before ext_proc (inserted after buffer), and no buffer filter (unchanged).