Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions api/v1alpha1/backendtrafficpolicy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,32 @@ type BackendTrafficPolicySpec struct {
//
// +optional
RequestBuffer *RequestBuffer `json:"requestBuffer,omitempty"`

// RequestBodyBufferLimit specifies the maximum size in bytes that Envoy may buffer for request bodies.
Comment thread
zhaohuabing marked this conversation as resolved.
// This configures Envoy's request body buffer limit without enabling full request buffering.
//
// This Request body buffer limit is independent of the connection buffer limits configured by
// ClientTrafficPolicy and BackendTrafficPolicy. The connection buffer limits control downstream
// and upstream connection read/write buffering and back pressure, while this field sets the
// maximum size of an individual request body that Envoy may buffer for HTTP processing.
//
// For HTTP/1, connection buffer limits can still affect how request body data is read and buffered
// before or while the request body limit is enforced. Configure connection buffer limits large
// enough for the request body buffering you expect to allow on those connections.
//
// For HTTP/2, initial stream and connection window sizes control HTTP/2 flow control: how much data
// can be in flight before back pressure applies. They affect upload throughput and buffering
// behavior, but they are not a replacement for this request body size limit.
//
// If exceeded, the request will be rejected with HTTP 413 Content Too Large.
//
// Accepts values in resource.Quantity format (e.g., "10Mi", "500Ki").
//
// +kubebuilder:validation:XIntOrString
// +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
// +optional
RequestBodyBufferLimit *resource.Quantity `json:"requestBodyBufferLimit,omitempty"`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a must, but could this be part of RequestBuffer?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They have different meanings:

  • RequestBuffer: buffer and fully receive each request from a client before continuing to send the request upstream to the backends.
  • RequestBodyBufferLimit: specifies the maximum size in bytes that Envoy may buffer for request bodies

I'm afraid it would cause confusion if we include both of them inside one RequestBuffer parent type.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @arkodg @guydc for another pair of eyes on the API shape.


// Telemetry configures the telemetry settings for the policy target (Gateway or xRoute).
// This will override the telemetry settings in the EnvoyProxy resource.
//
Expand Down
5 changes: 5 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2305,6 +2305,34 @@ spec:
- Local
type: string
type: object
requestBodyBufferLimit:
allOf:
- pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
- pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
anyOf:
- type: integer
- type: string
description: |-
RequestBodyBufferLimit specifies the maximum size in bytes that Envoy may buffer for request bodies.
This configures Envoy's request body buffer limit without enabling full request buffering.

This Request body buffer limit is independent of the connection buffer limits configured by
ClientTrafficPolicy and BackendTrafficPolicy. The connection buffer limits control downstream
and upstream connection read/write buffering and back pressure, while this field sets the
maximum size of an individual request body that Envoy may buffer for HTTP processing.

For HTTP/1, connection buffer limits can still affect how request body data is read and buffered
before or while the request body limit is enforced. Configure connection buffer limits large
enough for the request body buffering you expect to allow on those connections.

For HTTP/2, initial stream and connection window sizes control HTTP/2 flow control: how much data
can be in flight before back pressure applies. They affect upload throughput and buffering
behavior, but they are not a replacement for this request body size limit.

If exceeded, the request will be rejected with HTTP 413 Content Too Large.

Accepts values in resource.Quantity format (e.g., "10Mi", "500Ki").
x-kubernetes-int-or-string: true
requestBuffer:
description: |-
RequestBuffer allows the gateway to buffer and fully receive each request from a client before continuing to send the request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2304,6 +2304,34 @@ spec:
- Local
type: string
type: object
requestBodyBufferLimit:
allOf:
- pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
- pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
anyOf:
- type: integer
- type: string
description: |-
RequestBodyBufferLimit specifies the maximum size in bytes that Envoy may buffer for request bodies.
This configures Envoy's request body buffer limit without enabling full request buffering.

This Request body buffer limit is independent of the connection buffer limits configured by
ClientTrafficPolicy and BackendTrafficPolicy. The connection buffer limits control downstream
and upstream connection read/write buffering and back pressure, while this field sets the
maximum size of an individual request body that Envoy may buffer for HTTP processing.

For HTTP/1, connection buffer limits can still affect how request body data is read and buffered
before or while the request body limit is enforced. Configure connection buffer limits large
enough for the request body buffering you expect to allow on those connections.

For HTTP/2, initial stream and connection window sizes control HTTP/2 flow control: how much data
can be in flight before back pressure applies. They affect upload throughput and buffering
behavior, but they are not a replacement for this request body size limit.

If exceeded, the request will be rejected with HTTP 413 Content Too Large.

Accepts values in resource.Quantity format (e.g., "10Mi", "500Ki").
x-kubernetes-int-or-string: true
requestBuffer:
description: |-
RequestBuffer allows the gateway to buffer and fully receive each request from a client before continuing to send the request
Expand Down
65 changes: 46 additions & 19 deletions internal/gatewayapi/backendtrafficpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (

perr "github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
apiresource "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
Expand Down Expand Up @@ -1070,6 +1071,7 @@ func (t *Translator) buildTrafficFeatures(policy *egv1a1.BackendTrafficPolicy, o
h2 *ir.HTTP2Settings
ro *ir.ResponseOverride
rb *ir.RequestBuffer
rbbl *uint64
cp []*ir.Compression
httpUpgrade []ir.HTTPUpgradeConfig
err, errs error
Expand Down Expand Up @@ -1138,6 +1140,11 @@ func (t *Translator) buildTrafficFeatures(policy *egv1a1.BackendTrafficPolicy, o
errs = errors.Join(errs, err)
}

if rbbl, err = buildRequestBodyBufferLimit(policy.Spec.RequestBodyBufferLimit); err != nil {
err = perr.WithMessage(err, "RequestBodyBufferLimit")
errs = errors.Join(errs, err)
}

if err = validateTelemetry(policy.Spec.Telemetry); err != nil {
err = perr.WithMessage(err, "Telemetry")
errs = errors.Join(errs, err)
Expand All @@ -1154,25 +1161,26 @@ func (t *Translator) buildTrafficFeatures(policy *egv1a1.BackendTrafficPolicy, o
ds = translateDNS(&policy.Spec.ClusterSettings, utils.NamespacedName(policy).String())

return &ir.TrafficFeatures{
RateLimit: rl,
BandwidthLimit: bl,
LoadBalancer: lb,
ProxyProtocol: pp,
HealthCheck: hc,
CircuitBreaker: cb,
FaultInjection: fi,
AdmissionControl: ac,
TCPKeepalive: ka,
Retry: rt,
BackendConnection: bc,
HTTP2: h2,
DNS: ds,
Timeout: to,
ResponseOverride: ro,
RequestBuffer: rb,
Compression: cp,
HTTPUpgrade: httpUpgrade,
Telemetry: buildBackendTelemetry(policy.Spec.Telemetry),
RateLimit: rl,
BandwidthLimit: bl,
LoadBalancer: lb,
ProxyProtocol: pp,
HealthCheck: hc,
CircuitBreaker: cb,
FaultInjection: fi,
AdmissionControl: ac,
TCPKeepalive: ka,
Retry: rt,
BackendConnection: bc,
HTTP2: h2,
DNS: ds,
Timeout: to,
ResponseOverride: ro,
RequestBuffer: rb,
RequestBodyBufferLimit: rbbl,
Compression: cp,
HTTPUpgrade: httpUpgrade,
Telemetry: buildBackendTelemetry(policy.Spec.Telemetry),
}, errs
}

Expand Down Expand Up @@ -1906,6 +1914,25 @@ func buildRequestBuffer(spec *egv1a1.RequestBuffer) (*ir.RequestBuffer, error) {
}, nil
}

// buildRequestBodyBufferLimit converts the request body buffer limit Quantity into a byte count.
func buildRequestBodyBufferLimit(limit *apiresource.Quantity) (*uint64, error) {
if limit == nil {
return nil, nil
}

v, ok := limit.AsInt64()
if !ok {
return nil, fmt.Errorf("invalid RequestBodyBufferLimit value %s", limit.String())
}

if v < 0 {
return nil, fmt.Errorf("RequestBodyBufferLimit value %s is out of range, must be >= 0", limit.String())
}

out := uint64(v)
return &out, nil
}

func (t *Translator) buildResponseOverride(policy *egv1a1.BackendTrafficPolicy, owners *backendTrafficPolicyOwners) (*ir.ResponseOverride, error) {
if len(policy.Spec.ResponseOverride) == 0 {
return nil, nil
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gateway-1
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gateway-2
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http
protocol: HTTP
port: 8080
allowedRoutes:
namespaces:
from: All
httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: default
name: httproute-1
spec:
hostnames:
- gateway.envoyproxy.io
parentRefs:
- namespace: envoy-gateway
name: gateway-1
sectionName: http
rules:
- matches:
- path:
value: "/foo"
backendRefs:
- name: service-1
port: 8080
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: default
name: httproute-2
spec:
hostnames:
- gateway.envoyproxy.io
parentRefs:
- namespace: envoy-gateway
name: gateway-2
sectionName: http
rules:
- matches:
- path:
value: "/foo"
backendRefs:
- name: service-2
port: 8080
backendTrafficPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: policy-for-route
namespace: default
spec:
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
name: httproute-2
requestBodyBufferLimit: 4Mi
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: policy-for-gateway
namespace: envoy-gateway
spec:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
requestBodyBufferLimit: 4Mi
Loading