|
50 | 50 | during GSON/Moshi serialization. The proxy never sees the full response |
51 | 51 | body as a single buffer; it forwards chunks as they arrive.</p> |
52 | 52 |
|
53 | | - <p><strong>What this does NOT solve:</strong> Large HTTP <em>request</em> |
54 | | - bodies (client to server). If a client sends a very large POST body and |
55 | | - the proxy rejects it, the fix is client-side: break the request into |
56 | | - smaller payloads (for example, date-range chunking) or add a pre-send |
57 | | - size guard. The streaming formatter operates on the response path only.</p> |
| 53 | + <p><strong>Request path (client to server):</strong> The streaming |
| 54 | + formatter operates on the <em>response</em> path only. For large |
| 55 | + HTTP POST request bodies, note that neither |
| 56 | + <a href="https://www.rfc-editor.org/rfc/rfc9110#section-8.6">HTTP/1.1 (RFC 9110)</a> |
| 57 | + nor <a href="https://www.rfc-editor.org/rfc/rfc9113">HTTP/2 (RFC 9113)</a> |
| 58 | + define a limit on request body size. HTTP/2 is actually better |
| 59 | + suited for large requests because the body is sent as DATA frames |
| 60 | + with flow control — the sender and receiver negotiate how much |
| 61 | + data to send at a time, preventing buffer overflow. In practice, |
| 62 | + size rejections come from infrastructure layers, not the HTTP |
| 63 | + spec:</p> |
| 64 | + |
| 65 | + <ul> |
| 66 | + <li><strong>Reverse proxies</strong> (CloudFlare, nginx) — |
| 67 | + <code>client_max_body_size</code> or equivalent; increase |
| 68 | + or remove the limit</li> |
| 69 | + <li><strong>Load balancers</strong> (AWS ALB/NLB) — ALB imposes |
| 70 | + no body size limit when routing to EC2/ECS targets. |
| 71 | + The 1MB limit applies only to the ALB→Lambda integration |
| 72 | + path (an AWS hard limit that cannot be increased). |
| 73 | + NLB operates at TCP level and has no body size limit</li> |
| 74 | + <li><strong>Web servers</strong> (Tomcat, WildFly) — |
| 75 | + <code>maxPostSize</code> / <code>max-post-size</code>; |
| 76 | + set to <code>-1</code> for unlimited</li> |
| 77 | + </ul> |
| 78 | + |
| 79 | + <p>When a large POST is rejected, debug the specific error and |
| 80 | + the infrastructure layer that imposed the limit — the fix is |
| 81 | + usually a configuration change, not a code refactor. Breaking |
| 82 | + requests into smaller payloads is a last resort when the |
| 83 | + infrastructure limit cannot be changed.</p> |
58 | 84 | </section> |
59 | 85 |
|
60 | 86 | <section name="Available Variants"> |
@@ -259,12 +285,14 @@ OutputStream flushingStream = new FlushingOutputStream(outputStream, flushInterv |
259 | 285 | </section> |
260 | 286 |
|
261 | 287 | <section name="Axis2/C Equivalent"> |
262 | | - <p>The same pattern applies to Axis2/C services using Apache httpd |
263 | | - with mod_axis2. During JSON response generation, call |
264 | | - <code>ap_rflush(r)</code> periodically to flush the response |
265 | | - bucket brigade. This causes mod_h2 to emit HTTP/2 DATA frames |
266 | | - incrementally, achieving the same proxy-friendly streaming behavior |
267 | | - as the Java formatter.</p> |
| 288 | + <p><a href="https://axis.apache.org/axis2/c/core/">Axis2/C</a> |
| 289 | + achieves the same streaming behavior natively through Apache httpd's |
| 290 | + <code>mod_h2</code>. During JSON response generation, the C service |
| 291 | + calls <code>ap_rflush(r)</code> periodically to flush the response |
| 292 | + bucket brigade. This causes <code>mod_h2</code> to emit HTTP/2 DATA |
| 293 | + frames incrementally — the same 64KB chunked pattern as the Java |
| 294 | + formatter, with identical proxy behavior. Both implementations |
| 295 | + produce matching HTTP/2 frame sequences for the same payload.</p> |
268 | 296 | </section> |
269 | 297 |
|
270 | 298 | </body> |
|
0 commit comments