Configuration: HTTP buffering

This page documents the buffer_request and buffer_response directives for configuring HTTP body buffering in Ferron. Buffering collects incoming request bodies and outgoing response bodies up to a configured size limit. It can serve as an additional protection layer against Slowloris-style attacks. It also helps control memory consumption for large payloads.

Request and response buffering⁠#

{
    buffer_request 8192
    buffer_response 65536
}

example.com {
    buffer_request 16384
    buffer_response 0
}

Both directives accept an integer value (buffer size in bytes). You can configure them at global or HTTP host scope. When set, the server buffers up to the specified number of bytes before passing the body downstream. The server still serves bodies larger than the buffer limit, but it collects the initial portion first.

Global buffering directives⁠#

DirectiveArgumentsDescriptionDefault
buffer_request<int>This directive specifies the buffer size in bytes for incoming HTTP request bodies. Buffering request bodies can protect backend servers from Slowloris-style attacks by collecting the body before processing.disabled
buffer_response<int>This directive specifies the buffer size in bytes for outgoing HTTP response bodies. Buffering responses can help control memory usage and make sure delivery to clients is consistent.disabled

Configuration example:

{
    buffer_request 8192
    buffer_response 32768
}

example.com {
    buffer_request 16384
}
Note

Ferron disables both buffer_request and buffer_response by default unless you configure them explicitly. This avoids unnecessary memory overhead. Set buffer sizes based on your expected request/response payload sizes. Typical values range from 4 KB to 64 KB. Setting the buffer too small provides little benefit. Setting it too large increases memory consumption per request.

Behavior⁠#

Tip
  • Each active connection uses memory proportional to the buffer size when you enable buffering. Under high concurrency, large buffer sizes can increase memory pressure. Monitor memory usage and adjust accordingly.
  • To disable inherited buffering at a specific host scope, set the directive to 0 (zero bytes). Remove the directive entirely if no parent scope configures it.

Request buffering⁠#

When you configure buffer_request:

  • The server collects incoming request body frames up to the configured byte limit.
  • If the request body is smaller than the buffer limit, the server collects the entire body. It does this before downstream stages (like reverse proxy or authentication) process it.
  • If the request body exceeds the buffer limit, the server collects the buffered portion and preserves the remaining body stream. Downstream stages receive a chained stream consisting of the buffered frames followed by the remaining body.
  • The server preserves non-data frames (such as trailing headers) and stops further collection.
Important

Slowloris protection: Request buffering is one layer of defense against Slowloris attacks. You should also configure the timeout directive to enforce connection timeouts. See Core directives for the timeout directive.

Response buffering⁠#

When you configure buffer_response:

  • The server collects outgoing response body frames up to the configured byte limit.
  • Like request buffering, the server splits the response body into buffered frames and a remaining stream. Buffered frames stay within the configured limit. The remaining stream exists only if the body exceeds the limit.
  • The server reassembles the buffered response and sends it to the client as a chained stream.
  • Response buffering only applies to custom responses generated by the pipeline. Built-in error responses are not buffered.

Buffering and pipeline stages⁠#

The buffer stage runs early in the HTTP pipeline. It runs after URL rewriting but before rate limiting, authentication, caching, reverse proxy, and static file stages. This ordering makes sure that the server buffers request bodies before they reach backend handlers.

Observability⁠#

Trace spans⁠#

The request buffer stage sets the following attributes on its ferron.stage.http_buffer span:

AttributeTypeDescription
ferron.buffer.capacityintConfigured buffer capacity in bytes.
ferron.buffer.sizeintActual buffered request body size in bytes.