Inject response headers

The following example walks you through how to use an Inja template to extract a value from a request header and to add this value as a header to your responses.

Before you begin

  1. Follow the Get started guide to install kgateway.

  2. Follow the Sample app guide to create an API gateway proxy with an HTTP listener and deploy the httpbin sample app.

  3. Get the external address of the gateway and save it in an environment variable.

    export INGRESS_GW_ADDRESS=$(kubectl get svc -n kgateway-system http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
    echo $INGRESS_GW_ADDRESS  
    kubectl port-forward deployment/http -n kgateway-system 8080:8080

Inject response headers

  1. Create a TrafficPolicy resource with your transformation rules. Make sure to create the TrafficPolicy in the same namespace as the HTTPRoute resource. In the following example, you use the value from the x-kgateway-request request header and populate the value of that header into an x-kgateway-response response header.

    kubectl apply -f- <<EOF
    apiVersion: gateway.kgateway.dev/v1alpha1
    kind: TrafficPolicy
    metadata:
      name: transformation
      namespace: httpbin
    spec:
      transformation:
        response:
          set:
          - name: x-kgateway-response
            value: '{{ request_header("x-kgateway-request") }}' 
    EOF
  2. Update the HTTPRoute resource to apply the TrafficPolicy to the httpbin route by using an extensionRef filter.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: httpbin
      namespace: httpbin
      labels:
        example: httpbin-route
    spec:
      parentRefs:
        - name: http
          namespace: kgateway-system
      hostnames:
        - "www.example.com"
      rules:
        - backendRefs:
            - name: httpbin
              port: 8000
          filters:
          - type: ExtensionRef
            extensionRef:
              group: gateway.kgateway.dev
              kind: TrafficPolicy
              name: transformation
    EOF
  3. Send a request to the httpbin app and include the x-kgateway-request request header.

    curl -vi http://$INGRESS_GW_ADDRESS:8080/response-headers \
     -H "host: www.example.com:8080" \
     -H "x-kgateway-request: my custom request header" 
    curl -vi localhost:8080/response-headers \
    -H "host: www.example.com" \
    -H "x-kgateway-request: my custom request header"

    In the example output, verify the following:

    • The x-kgateway-request request header is included in the request.
    • The request is successful and returns a 200 HTTP response code.
    • The x-kgateway-response response header is included in the response and has the same value as the x-kgateway-request request header.
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    
    * Host <host-address>:8080 was resolved.
    * IPv6: ::1
    * IPv4: 127.0.0.1
    *   Trying [::1]:8080...
    * Connected to <host-address> (::1) port 8080
    > GET /response-headers HTTP/1.1
    > Host: www.example.com
    > User-Agent: curl/8.7.1
    > Accept: */*
    > x-kgateway-request: my custom request header
    > 
    * Request completely sent off
    < HTTP/1.1 200 OK
    HTTP/1.1 200 OK
    < access-control-allow-credentials: true
    access-control-allow-credentials: true
    < access-control-allow-origin: *
    access-control-allow-origin: *
    < content-type: application/json; encoding=utf-8
    content-type: application/json; encoding=utf-8
    < date: Wed, 26 Jun 2024 02:54:48 GMT
    date: Wed, 26 Jun 2024 02:54:48 GMT
    < content-length: 3
    content-length: 3
    < x-envoy-upstream-service-time: 2
    x-envoy-upstream-service-time: 2
    < server: envoy
    server: envoy
    < x-envoy-decorator-operation: httpbin.httpbin.svc.cluster.local:8000/*
    x-envoy-decorator-operation: httpbin.httpbin.svc.cluster.local:8000/*
    < x-kgateway-response: my custom request header
    x-kgateway-response: my custom request header

Cleanup

You can remove the resources that you created in this guide.
  1. Delete the TrafficPolicy resource.

    kubectl delete TrafficPolicy transformation -n httpbin
  2. Remove the extensionRef filter from the HTTPRoute resource.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: httpbin
      namespace: httpbin
      labels:
        example: httpbin-route
    spec:
      parentRefs:
        - name: http
          namespace: kgateway-system
      hostnames:
        - "www.example.com"
      rules:
        - backendRefs:
            - name: httpbin
              port: 8000
    EOF