Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for ResponseHeaderModifier for HTTPRouteRule objects #1880

Merged
merged 73 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from 66 commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
9e69057
Add support for ResponseHeaderModifier for HTTPRouteRule objects
kevin85421 Jan 21, 2024
d440ae7
refactor validateFilterHeaderModifier
kevin85421 Jan 22, 2024
c4cbba2
Rename ValidateRequestHeader to ValidateFilterHeader
kevin85421 Jan 22, 2024
ac6281c
Rename AddHeaders to AddHeaderDirectives
kevin85421 Jan 22, 2024
51b8238
Update servers_template.go
kevin85421 Jan 22, 2024
f247e7b
Pass conformance tests
kevin85421 Feb 4, 2024
3fc4053
Remove Map
kevin85421 Feb 4, 2024
d235286
Remove fmt.Printf
kevin85421 Feb 4, 2024
712411c
Change TODO to FIXME
kevin85421 Feb 4, 2024
6559b44
Address comments
kevin85421 Feb 19, 2024
bfe683d
Address comments
kevin85421 Feb 19, 2024
d372161
Address comments
kevin85421 Feb 19, 2024
20f2600
Address comments
kevin85421 Feb 19, 2024
120420b
Address comments
kevin85421 Feb 19, 2024
e622be9
Address comments
kevin85421 Feb 19, 2024
cd777a2
Address comments
kevin85421 Feb 20, 2024
d8ce13e
Add HTTPRouteResponseHeaderModification to the conformance tests
kevin85421 Feb 20, 2024
82e1280
Add support for ResponseHeaderModifier for HTTPRouteRule objects
kevin85421 Feb 20, 2024
5cd44a1
Add support for ResponseHeaderModifier for HTTPRouteRule objects
kevin85421 Feb 25, 2024
21af9bc
Add support for ResponseHeaderModifier for HTTPRouteRule objects
kevin85421 Feb 25, 2024
2719fa4
Add support for ResponseHeaderModifier for HTTPRouteRule objects
kevin85421 Feb 25, 2024
d4f0ea5
update
kevin85421 Mar 11, 2024
381fe04
fix unit tests after rebase
salonichf5 Apr 24, 2024
387f05a
address nit comments and add unit tests
salonichf5 Apr 29, 2024
decffb3
add docs for http filters
salonichf5 May 1, 2024
7a05dbc
fix lint issues
salonichf5 May 1, 2024
152c799
add tutorial for response headers
salonichf5 May 2, 2024
8239e31
line spacing
salonichf5 May 2, 2024
7f40457
fix docs and add unit tests
salonichf5 May 2, 2024
7930761
refactor code
salonichf5 May 2, 2024
a80a7b5
Update examples/http-response-header-filter/README.md
salonichf5 May 2, 2024
b375b2a
Update examples/http-response-header-filter/README.md
salonichf5 May 2, 2024
d9c50f3
Update site/content/overview/gateway-api-compatibility.md
salonichf5 May 2, 2024
52448c4
Update site/content/overview/gateway-api-compatibility.md
salonichf5 May 2, 2024
e3362e3
Update site/content/overview/gateway-api-compatibility.md
salonichf5 May 2, 2024
6a2bd93
Update site/content/overview/gateway-api-compatibility.md
salonichf5 May 2, 2024
bc6e8ea
Update examples/http-response-header-filter/README.md
salonichf5 May 2, 2024
60c1c5d
Update examples/http-response-header-filter/README.md
salonichf5 May 2, 2024
5aabd0a
address comments
salonichf5 May 2, 2024
394a3f3
update examples for response headers
salonichf5 May 2, 2024
bd0495f
improve docs
salonichf5 May 2, 2024
579eaca
update readme
salonichf5 May 2, 2024
5627b44
add tests for code coverage
salonichf5 May 3, 2024
07539fb
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 3, 2024
c3f040a
update doc links
salonichf5 May 3, 2024
35861ad
update tutorial
salonichf5 May 6, 2024
b661b40
Update site/content/how-to/traffic-management/response-headers.md
salonichf5 May 6, 2024
292ba3a
Update site/content/how-to/traffic-management/response-headers.md
salonichf5 May 6, 2024
db13795
Update site/content/how-to/traffic-management/response-headers.md
salonichf5 May 6, 2024
6c0ae2c
Update site/content/how-to/traffic-management/response-headers.md
salonichf5 May 6, 2024
7bc9897
Update site/content/how-to/traffic-management/response-headers.md
salonichf5 May 6, 2024
f390ccc
Update site/content/how-to/traffic-management/response-headers.md
salonichf5 May 6, 2024
3aa2f23
tutorial modifications
salonichf5 May 6, 2024
112eab9
remove extras
salonichf5 May 6, 2024
9c40e3a
Update site/content/how-to/traffic-management/response-headers.md
salonichf5 May 6, 2024
3ff6015
fix repetition in doc
salonichf5 May 6, 2024
d415f25
Update site/content/how-to/traffic-management/response-headers.md
salonichf5 May 7, 2024
f3695e4
Update site/content/how-to/traffic-management/response-headers.md
salonichf5 May 7, 2024
e56b8ab
Update site/content/how-to/traffic-management/response-headers.md
salonichf5 May 7, 2024
5826d32
Update site/content/how-to/traffic-management/response-headers.md
salonichf5 May 7, 2024
1dd4c8a
Update site/content/how-to/traffic-management/response-headers.md
salonichf5 May 7, 2024
71e1881
Update site/content/how-to/traffic-management/response-headers.md
salonichf5 May 7, 2024
9fbb7de
Update internal/mode/static/nginx/config/validation/http_filters.go
salonichf5 May 7, 2024
9fcdbd3
address comments
salonichf5 May 7, 2024
241bab4
update tutorial
salonichf5 May 8, 2024
5b6df53
Update site/content/how-to/traffic-management/response-headers.md
salonichf5 May 8, 2024
a7374be
capitalize resource name
salonichf5 May 8, 2024
31b3415
capitalization of resource name
salonichf5 May 8, 2024
f802db1
Update site/content/how-to/traffic-management/response-headers.md
salonichf5 May 9, 2024
2fc154f
arrange headers for tutorial
salonichf5 May 9, 2024
268acb8
Update site/content/how-to/traffic-management/response-headers.md
salonichf5 May 14, 2024
0cbfa7b
address nit comments
salonichf5 May 14, 2024
987a368
Merge branch 'main' into feat/response-header
salonichf5 May 14, 2024
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
2 changes: 1 addition & 1 deletion conformance/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ NGINX_PREFIX = $(PREFIX)/nginx
NGINX_PLUS_PREFIX ?= $(PREFIX)/nginx-plus
GW_API_VERSION ?= 1.0.0
GATEWAY_CLASS = nginx
SUPPORTED_FEATURES = HTTPRouteQueryParamMatching,HTTPRouteMethodMatching,HTTPRoutePortRedirect,HTTPRouteSchemeRedirect,HTTPRouteHostRewrite,HTTPRoutePathRewrite,GatewayPort8080
SUPPORTED_FEATURES = HTTPRouteQueryParamMatching,HTTPRouteMethodMatching,HTTPRoutePortRedirect,HTTPRouteSchemeRedirect,HTTPRouteHostRewrite,HTTPRoutePathRewrite,GatewayPort8080,HTTPRouteResponseHeaderModification
KIND_IMAGE ?= $(shell grep -m1 'FROM kindest/node' <tests/Dockerfile | awk -F'[ ]' '{print $$2}')
KIND_KUBE_CONFIG=$${HOME}/.kube/kind/config
CONFORMANCE_TAG = latest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ headers to the request.
GW_PORT=<port number>
```

## 2. Deploy the Cafe Application
## 2. Deploy the Headers Application

1. Create the headers Deployment and Service:

Expand Down
3 changes: 3 additions & 0 deletions examples/http-response-header-filter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# HTTP Response Headers

This directory contains the YAML files used in the [HTTP Response Headers](https://docs.nginx.com/nginx-gateway-fabric/how-to/traffic-management/response-headers.md) guide.
10 changes: 10 additions & 0 deletions examples/http-response-header-filter/gateway.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: gateway
spec:
gatewayClassName: nginx
listeners:
- name: http
port: 80
protocol: HTTP
70 changes: 70 additions & 0 deletions examples/http-response-header-filter/headers.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: headers
spec:
replicas: 1
selector:
matchLabels:
app: headers
template:
metadata:
labels:
app: headers
spec:
containers:
- name: headers
image: nginx
ports:
- containerPort: 8080
volumeMounts:
- name: config-volume
mountPath: /etc/nginx
readOnly: true
volumes:
- name: config-volume
configMap:
name: headers-config
---
apiVersion: v1
kind: ConfigMap
metadata:
name: headers-config
# yamllint disable rule:indentation
data:
nginx.conf: |-
user nginx;
worker_processes 1;

pid /var/run/nginx.pid;

events {}

http {
default_type text/plain;

server {
listen 8080;

add_header X-Header-Unmodified "unmodified";
add_header X-Header-Add "add-to";
add_header X-Header-Set "overwrite";
add_header X-Header-Remove "remove";

return 200 "ok";
}
}
# yamllint enable rule:indentation
---
apiVersion: v1
kind: Service
metadata:
name: headers
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: headers
29 changes: 29 additions & 0 deletions examples/http-response-header-filter/http-route-filters.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: headers
spec:
parentRefs:
- name: gateway
sectionName: http
hostnames:
- "cafe.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /headers
filters:
- type: ResponseHeaderModifier
responseHeaderModifier:
set:
- name: X-Header-Set
value: overwritten-value
add:
- name: X-Header-Add
value: this-is-the-appended-value
remove:
- X-Header-Remove
backendRefs:
- name: headers
port: 80
18 changes: 18 additions & 0 deletions examples/http-response-header-filter/http-route.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: headers
spec:
parentRefs:
- name: gateway
sectionName: http
hostnames:
- "cafe.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /headers
backendRefs:
- name: headers
port: 80
11 changes: 10 additions & 1 deletion internal/mode/static/nginx/config/http/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ type Location struct {
Path string
ProxyPass string
HTTPMatchKey string
HTTPMatchVar string
Rewrites []string
ProxySetHeaders []Header
ProxySSLVerify *ProxySSLVerify
Return *Return
Rewrites []string
ResponseHeaders ResponseHeaders
GRPC bool
}

Expand All @@ -29,6 +31,13 @@ type Header struct {
Value string
}

// ResponseHeaders holds all response headers to be added, set, or removed.
type ResponseHeaders struct {
Add []Header
Set []Header
Remove []string
}

// Return represents an HTTP return.
type Return struct {
Body string
Expand Down
28 changes: 24 additions & 4 deletions internal/mode/static/nginx/config/servers.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ func updateLocationsForFilters(

rewrites := createRewritesValForRewriteFilter(filters.RequestURLRewrite, path)
proxySetHeaders := generateProxySetHeaders(&matchRule.Filters, grpc)
responseHeaders := generateResponseHeaders(&matchRule.Filters)
salonichf5 marked this conversation as resolved.
Show resolved Hide resolved
for i := range buildLocations {
if rewrites != nil {
if rewrites.Rewrite != "" {
Expand All @@ -308,6 +309,7 @@ func updateLocationsForFilters(
generateProtocolString(buildLocations[i].ProxySSLVerify, grpc),
grpc,
)
buildLocations[i].ResponseHeaders = responseHeaders
buildLocations[i].ProxyPass = proxyPass
buildLocations[i].GRPC = grpc
}
Expand Down Expand Up @@ -578,11 +580,11 @@ func generateProxySetHeaders(filters *dataplane.HTTPFilters, grpc bool) []http.H
headerLen := len(headerFilter.Add) + len(headerFilter.Set) + len(headerFilter.Remove) + len(headers)
proxySetHeaders := make([]http.Header, 0, headerLen)
if len(headerFilter.Add) > 0 {
addHeaders := convertAddHeaders(headerFilter.Add)
addHeaders := createHeadersWithVarName(headerFilter.Add)
proxySetHeaders = append(proxySetHeaders, addHeaders...)
}
if len(headerFilter.Set) > 0 {
setHeaders := convertSetHeaders(headerFilter.Set)
setHeaders := createHeaders(headerFilter.Set)
proxySetHeaders = append(proxySetHeaders, setHeaders...)
}
// If the value of a header field is an empty string then this field will not be passed to a proxied server
Expand All @@ -596,7 +598,25 @@ func generateProxySetHeaders(filters *dataplane.HTTPFilters, grpc bool) []http.H
return append(proxySetHeaders, headers...)
}

func convertAddHeaders(headers []dataplane.HTTPHeader) []http.Header {
func generateResponseHeaders(filters *dataplane.HTTPFilters) http.ResponseHeaders {
if filters == nil || filters.ResponseHeaderModifiers == nil {
return http.ResponseHeaders{}
}

headerFilter := filters.ResponseHeaderModifiers
responseRemoveHeaders := make([]string, len(headerFilter.Remove))

// Make a deep copy to prevent the slice from being accidentally modified.
copy(responseRemoveHeaders, headerFilter.Remove)

return http.ResponseHeaders{
Add: createHeaders(headerFilter.Add),
Set: createHeaders(headerFilter.Set),
Remove: responseRemoveHeaders,
}
}

func createHeadersWithVarName(headers []dataplane.HTTPHeader) []http.Header {
locHeaders := make([]http.Header, 0, len(headers))
for _, h := range headers {
mapVarName := "${" + generateAddHeaderMapVariableName(h.Name) + "}"
Expand All @@ -608,7 +628,7 @@ func convertAddHeaders(headers []dataplane.HTTPHeader) []http.Header {
return locHeaders
}

func convertSetHeaders(headers []dataplane.HTTPHeader) []http.Header {
func createHeaders(headers []dataplane.HTTPHeader) []http.Header {
locHeaders := make([]http.Header, 0, len(headers))
for _, h := range headers {
locHeaders = append(locHeaders, http.Header{
Expand Down
10 changes: 10 additions & 0 deletions internal/mode/static/nginx/config/servers_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ server {
{{ $proxyOrGRPC }}_set_header {{ $h.Name }} "{{ $h.Value }}";
{{- end }}
{{ $proxyOrGRPC }}_pass {{ $l.ProxyPass }};
{{ range $h := $l.ResponseHeaders.Add }}
add_header {{ $h.Name }} "{{ $h.Value }}" always;
{{- end }}
{{ range $h := $l.ResponseHeaders.Set }}
proxy_hide_header {{ $h.Name }};
add_header {{ $h.Name }} "{{ $h.Value }}" always;
{{- end }}
{{ range $h := $l.ResponseHeaders.Remove }}
proxy_hide_header {{ $h }};
{{- end }}
proxy_http_version 1.1;
{{- if $l.ProxySSLVerify }}
{{ $proxyOrGRPC }}_ssl_verify on;
Expand Down
Loading
Loading