design/httpproxy-header-rewrite.md
Status: Draft
This document specifies a design for supporting request / response header manipulation in the HTTPProxy CRD.
Setting and removing headers from requests and responses at two levels:
There are a number of use cases where having this raw capability is useful, and many are called out in #70.
Add a new type: HeaderPolicy that captures setting and removing headers.
// HeaderPolicy defines alterations to the headers being sent to or returned from a service.
type HeaderPolicy struct {
// Set sets the specified headers replacing any existing values associated with the header names.
// +optional
Set []HeaderValue `json:"set,omitempty"`
// Remove removes any headers whose name matches those specified.
// +optional
Remove []string `json:"remove,omitempty"`
}
// HeaderValue defines a header key/value pair to be added to those sent to or return from a service.
type HeaderValue struct {
// Name is the header key to add.
Name string `json:"name"`
// Value is the header value to add.
Value string `json:"value"`
}
This will be added in two flavors (request and response) to both Route (pre-split) and Service (post-split).
// RequestHeadersPolicy defines how to set or remove headers from requests.
// +optional
RequestHeadersPolicy *HeaderPolicy `json:"requestHeadersPolicy,omitempty"`
// ResponseHeadersPolicy defines how to set or remove headers from responses.
// +optional
ResponseHeadersPolicy *HeaderPolicy `json:"responseHeadersPolicy,omitempty"`
For the most part, these fields will be directly translated to the following fields in the respective Envoy proto:
RequestHeadersToAdd (with append: false)RequestHeadersToRemoveResponseHeadersToAdd (with append: false)ResponseHeadersToRemoveThere are two notable exceptions to this translation:
Host header manipulations must be done via a separate Envoy directive.%-encoded variables are not supported, so literal %'s must be escaped in header values.There were a few alternatives discussed around API shapes for general header manipulation in #70, but this shape was chosen to address the various scenarios raised there (e.g. request/response).
There was some discussion of API shapes for Host rewriting in #1982.
There was significant discussion (in slack) of naming. Two threads in particular:
HeaderPolicy vs. HeaderRewritePolicy for both the type name, and as part of the field names. The decision was ultimately to avoid pigeonholing future extensions of this policy with the "rewrite" qualification. In the context of the field name, it was also felt that the verbs sufficiently disambiguated intent, e.g.requestHeadersPolicy:
set:
- name: Foo
value: bar
remove:
- Baz
- Blah
Policy, or just the Go type. The decision was to bias towards consistency with other applications of the Policy-style throughout the Contour API, which were already present in the "v1" API surface and impossible to change without revving the API version. In general, there was some loose agreement that it might have been better to name fields without the suffix, but the Go types with the suffix. However, the prevailing sentiment was that API consistency was more important.None at this time.