Request headers

Use the RequestHeaderModifier filter to add, append, overwrite, or remove request headers for a specific route.

For more information, see the HTTPHeaderFilter specification.

Before you begin

  1. Follow the Get started guide to install kgateway.

  2. Follow the Sample app guide to create a 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

Add and append request headers

Add headers to incoming requests before they are forwarded to an upstream service. If the request already has the header set, the value of the header in the RequestHeaderModifier filter is appended to the value of the header in the request.

  1. Set up a header modifier that adds a my-header: hello request header. Choose between the HTTPRoute for a Gateway API-native way, or TrafficPolicy for more flexible attachment options such as a gateway-level policy.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: httpbin-headers
      namespace: httpbin
    spec:
      parentRefs:
      - name: http
        namespace: kgateway-system
      hostnames:
        - headers.example
      rules:
        - filters:
            - type: RequestHeaderModifier
              requestHeaderModifier:
                add: 
                - name: my-header
                  value: hello
          backendRefs:
            - name: httpbin
              port: 8000
    EOF
    Setting Description
    spec.parentRefs The name and namespace of the gateway that serves this HTTPRoute. In this example, you use the http Gateway that was created as part of the get started guide.
    spec.rules.filters.type The type of filter that you want to apply to incoming requests. In this example, the RequestHeaderModifier filter is used.
    spec.rules.filters.requestHeaderModifier.add The name and value of the request header that you want to add.
    spec.rules.backendRefs The backend destination you want to forward traffic to. In this example, all traffic is forwarded to the httpbin app that you set up as part of the get started guide.

    Note: The steps in this section use the Envoy-based kgateway proxy. The steps do not work with the agentgateway proxy.

    1. Create an HTTPRoute resource for the route that you want to modify. Note that the example selects the http Gateway that you created before you began.

      kubectl apply -f- <<EOF
      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: httpbin-headers
        namespace: httpbin
      spec:
        parentRefs:
        - name: http
          namespace: kgateway-system
        hostnames:
          - headers.example
        rules:
          - backendRefs:
              - name: httpbin
                port: 8000
      EOF
    2. Create a TrafficPolicy that adds a my-header: hello header to a request. The following example attaches the TrafficPolicy to the http Gateway.

      kubectl apply -f- <<EOF
      apiVersion: gateway.kgateway.dev/v1alpha1
      kind: TrafficPolicy
      metadata:
        name: httpbin-headers
        namespace: kgateway-system
      spec:
        targetRefs:
        - group: gateway.networking.k8s.io
          kind: Gateway
          name: http
        headerModifiers:
          request:
            add:
            - name: my-header
              value: hello
      EOF

  2. Send a request to the httpbin app on the headers.example domain and verify that you get back a 200 HTTP response code and that you see the my-header request header.

    curl -vi http://$INGRESS_GW_ADDRESS:8080/headers -H "host: headers.example:8080"
    curl -vi localhost:8080/headers -H "host: headers.example"

    Example output:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    HTTP/1.1 200 OK
    ...
    {
      "headers": {
        "Accept": [
          "*/*"
       ],
        "Host": [
          "headers.example:8080"
        ],
        "My-Header": [
          "hello"
        ],
       "User-Agent": [
          "curl/7.77.0"
        ],
    ...
  3. Send another request to the httpbin app. This time, you already include the my-header header in your request. Verify that you get back a 200 HTTP response code and that your my-header header value is appended with the value from the RequestHeaderModifier filter.

    curl -vi http://$INGRESS_GW_ADDRESS:8080/headers -H "host: headers.example:8080" \
    -H "my-header: foo"
    curl -vi localhost:8080/headers -H "host: headers.example" \
    -H "my-header: foo" 

    Example output:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    HTTP/1.1 200 OK
    ...
    {
      "headers": {
         "Accept": [
          "*/*"
        ],
        "Host": [
          "headers.example:8080"
        ],
        "My-Header": [
          "foo",
          "hello"
        ],
    ...
  4. Optional: Remove the resources that you created.

    kubectl delete httproute httpbin-headers -n httpbin
    kubectl delete httproute httpbin-headers -n httpbin
    kubectl delete TrafficPolicy httpbin-headers -n kgateway-system

Set request headers

Setting headers is similar to adding headers. If the request does not include the header, it is added by the RequestHeaderModifier filter. However, if the request already contains the header, its value is overwritten with the value from the RequestHeaderModifier filter.

  1. Set up a header modifier that sets a my-header: hello request header. Choose between the HTTPRoute for a Gateway API-native way, or TrafficPolicy for more flexible attachment options such as a gateway-level policy.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: httpbin-headers
      namespace: httpbin
    spec:
      parentRefs:
      - name: http
        namespace: kgateway-system
      hostnames:
        - headers.example
      rules:
        - filters:
            - type: RequestHeaderModifier
              requestHeaderModifier:
                set: 
                - name: my-header
                  value: hello
          backendRefs:
            - name: httpbin
              port: 8000
    EOF
    Setting Description
    spec.parentRefs The name and namespace of the gateway that serves this HTTPRoute. In this example, you use the http Gateway that was created as part of the get started guide.
    spec.rules.filters.type The type of filter that you want to apply to incoming requests. In this example, the RequestHeaderModifier filter is used.
    spec.rules.filters.requestHeaderModifier.set The name and value of the request header that you want to set.
    spec.rules.backendRefs The Kubernetes service you want to forward traffic to. In this example, all traffic is forwarded to the httpbin app that you set up as part of the get started guide.

    Note: The steps in this section use the Envoy-based kgateway proxy. The steps do not work with the agentgateway proxy.

    1. Create an HTTPRoute resource for the route that you want to modify. Note that the example selects the http Gateway that you created before you began.

      kubectl apply -f- <<EOF
      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: httpbin-headers
        namespace: httpbin
      spec:
        parentRefs:
        - name: http
          namespace: kgateway-system
        hostnames:
          - headers.example
        rules:
          - backendRefs:
              - name: httpbin
                port: 8000
      EOF
    2. Create a TrafficPolicy that sets the my-header header value to hello on a request. The following example attaches the TrafficPolicy to the http Gateway.

      kubectl apply -f- <<EOF
      apiVersion: gateway.kgateway.dev/v1alpha1
      kind: TrafficPolicy
      metadata:
        name: httpbin-headers
        namespace: kgateway-system
      spec:
        targetRefs:
        - group: gateway.networking.k8s.io
          kind: Gateway
          name: http
        headerModifiers:
          request:
            set:
            - name: my-header
              value: hello
      EOF

  2. Send a request to the httpbin app on the headers.example domain. Verify that you get back a 200 HTTP response code and that the my-header: hello header was added.

    curl -vi http://$INGRESS_GW_ADDRESS:8080/headers -H "host: headers.example:8080"
    curl -vi localhost:8080/headers -H "host: headers.example"

    Example output:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    HTTP/1.1 200 OK
    ...
    {
      "headers": {
        "Accept": [
          "*/*"
       ],
        "Host": [
          "headers.example:8080"
        ],
        "My-Header": [
          "hello"
        ],
       "User-Agent": [
          "curl/7.77.0"
        ],
    ...
  3. Send another request to the httpbin app. This time, you already include the my-header header in your request. Verify that you get back a 200 HTTP response code and that your my-header header value is overwritten with the value from the RequestHeaderModifier filter.

    curl -vi http://$INGRESS_GW_ADDRESS:8080/headers -H "host: headers.example:8080" \
    -H "my-header: foo"
    curl -vi localhost:8080/headers -H "host: headers.example" \
    -H "my-header: foo" 

    Example output:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    HTTP/1.1 200 OK
    ...
    {
      "headers": {
         "Accept": [
          "*/*"
        ],
        "Host": [
          "headers.example:8080"
        ],
        "My-Header": [
          "hello"
        ],
    ...
  4. Optional: Remove the resources that you created.

    kubectl delete httproute httpbin-headers -n httpbin
    kubectl delete httproute httpbin-headers -n httpbin
    kubectl delete TrafficPolicy httpbin-headers -n kgateway-system

Remove request headers

You can remove HTTP headers from a request before the request is forwarded to the target service in the cluster.

  1. Send a request to the httpbin app and find the User-Agent header.

    curl -vi http://$INGRESS_GW_ADDRESS:8080/headers -H "host: www.example.com:8080"
    curl -vi localhost:8080/headers -H "host: www.example.com"

    Example output:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    ...
    {
      "headers": {
        "Accept": [
          "*/*"
        ],
        "Host": [
          "www.example.com:8080"
        ],
        "User-Agent": [
          "curl/7.77.0"
        ],
        "X-Envoy-Expected-Rq-Timeout-Ms": [
          "15000"
        ],
        "X-Forwarded-Proto": [
          "http"
        ],
        "X-Request-Id": [
          "5b14c790-3870-4f73-a12e-4cba9a7eccd7"
        ]
      }
    }
  2. Set up a header modifier that removes the User-Agent header when requests are sent to the headers.example domain. Choose between the HTTPRoute for a Gateway API-native way, or TrafficPolicy for more flexible attachment options such as a gateway-level policy.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: httpbin-headers
      namespace: httpbin
    spec:
      parentRefs:
      - name: http
        namespace: kgateway-system
      hostnames:
        - headers.example
      rules:
        - filters:
            - type: RequestHeaderModifier
              requestHeaderModifier:
                remove: 
                  - User-Agent
          backendRefs:
            - name: httpbin
              port: 8000
    EOF
    Setting Description
    spec.parentRefs The name and namespace of the gateway that serves this HTTPRoute. In this example, you use the http Gateway that was created as part of the get started guide.
    spec.rules.filters.type The type of filter that you want to apply to incoming requests. In this example, the RequestHeaderModifier filter is used.
    spec.rules.filters.requestHeaderModifier.remove The name of the request header that you want to remove.
    spec.rules.backendRefs The backend destination you want to forward traffic to. In this example, all traffic is forwarded to the httpbin app that you set up as part of the get started guide.

    Note: The steps in this section use the Envoy-based kgateway proxy. The steps do not work with the agentgateway proxy.

    1. Create an HTTPRoute resource for the route that you want to modify. Note that the example selects the http Gateway that you created before you began.

      kubectl apply -f- <<EOF
      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: httpbin-headers
        namespace: httpbin
      spec:
        parentRefs:
        - name: http
          namespace: kgateway-system
        hostnames:
          - headers.example
        rules:
          - backendRefs:
              - name: httpbin
                port: 8000
      EOF
    2. Create a TrafficPolicy that removes the User-Agent header from a request. The following example attaches the TrafficPolicy to the http Gateway.

      kubectl apply -f- <<EOF
      apiVersion: gateway.kgateway.dev/v1alpha1
      kind: TrafficPolicy
      metadata:
        name: httpbin-headers
        namespace: kgateway-system
      spec:
        targetRefs:
        - group: gateway.networking.k8s.io
          kind: Gateway
          name: http
        headerModifiers:
          request:
            remove:
            - User-Agent
      EOF

  3. Send a request to the httpbin app on the headers.example domain . Verify that the User-Agent request header is removed.

    curl -vi http://$INGRESS_GW_ADDRESS:8080/headers -H "host: headers.example:8080"
    curl -vi localhost:8080/headers -H "host: headers.example"

    Example output:

    {
      "headers": {
        "Accept": [
          "*/*"
        ],
        "Host": [
          "headers.example:8080"
        ],
        "X-Envoy-Expected-Rq-Timeout-Ms": [
          "15000"
        ],
        "X-Forwarded-Proto": [
          "http"
        ],
        "X-Request-Id": [
          "f83bb750-67f7-47dc-8c79-4a582892034c"
        ]
      }
    }
  4. Optional: Clean up the resources that you created.

    kubectl delete httproute httpbin-headers -n httpbin
    kubectl delete httproute httpbin-headers -n httpbin
    kubectl delete TrafficPolicy httpbin-headers -n kgateway-system

Dynamic request headers

You can return dynamic information about the request in the request header. For more information, see the Envoy docs for Custom request/response headers.

Keep in mind that some variables are available only at certain times. For example, response codes (%RESPONSE_CODE%) are only available after the response has been sent to the client. If you set a response code in a request header, the value is empty.

You might use some of the following common values in your request or response headers.

Request and response information:

  • %REQ(:METHOD)% - HTTP method
  • %REQ(:PATH)% - Request path
  • %REQ(:AUTHORITY)% - Host header
  • %REQ(HEADER_NAME)% - Any request header
  • %RESP(HEADER_NAME)% - Any response header
  • %RESPONSE_CODE% - HTTP response code
  • %RESPONSE_FLAGS% - Response flags

Connection information:

  • %DOWNSTREAM_REMOTE_ADDRESS% - Client IP address with port
  • %DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT% - Client IP address without port
  • %DOWNSTREAM_LOCAL_ADDRESS% - Local address
  • %DOWNSTREAM_CONNECTION_ID% - Connection ID

Timing information:

  • %START_TIME% - Request start time
  • %DURATION% - Request duration

Upstream information:

  • %UPSTREAM_HOST% - Upstream host
  • %UPSTREAM_CLUSTER% - Upstream Envoy cluster
  • %UPSTREAM_LOCAL_ADDRESS% - Upstream local address

Data transfer:

  • %BYTES_RECEIVED% - Bytes received
  • %BYTES_SENT% - Bytes sent

For more potential values, see Command operators in the Envoy docs.

The steps in this section use the Envoy-based kgateway proxy. The steps do not work with the agentgateway proxy.
  1. Set up a header modifier that sets the X-Client-Ip header with the value of the downstream remote address. Choose between the HTTPRoute for a Gateway API-native way, or TrafficPolicy for more flexible attachment options such as a gateway-level policy.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: httpbin-headers
      namespace: httpbin
    spec:
      parentRefs:
      - name: http
        namespace: kgateway-system
      hostnames:
        - headers.example
      rules:
        - filters:
            - type: RequestHeaderModifier
              requestHeaderModifier:
                set: 
                  - name: x-client-ip
                    value: "%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%"
          backendRefs:
            - name: httpbin
              port: 8000
    EOF
    Setting Description
    spec.parentRefs The name and namespace of the gateway that serves this HTTPRoute. In this example, you use the http Gateway that was created as part of the get started guide.
    spec.rules.filters.type The type of filter that you want to apply to incoming requests. In this example, the RequestHeaderModifier filter is used.
    spec.rules.filters.requestHeaderModifier.set The request header that you want to set. In this example, the x-client-ip header is set to the downstream remote address without the port. For more potential values, see Command operators in the Envoy docs.
    spec.rules.backendRefs The backend destination you want to forward traffic to. In this example, all traffic is forwarded to the httpbin app that you set up as part of the get started guide.
    1. Create an HTTPRoute resource for the route that you want to modify. Note that the example selects the http Gateway that you created before you began.

      kubectl apply -f- <<EOF
      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: httpbin-headers
        namespace: httpbin
      spec:
        parentRefs:
        - name: http
          namespace: kgateway-system
        hostnames:
          - headers.example
        rules:
          - backendRefs:
              - name: httpbin
                port: 8000
      EOF
    2. Create a TrafficPolicy that sets the x-client-ip header to the downstream remote address without the port for a request. For more potential values, see Command operators in the Envoy docs. The following example attaches the TrafficPolicy to the http Gateway.

      kubectl apply -f- <<EOF
      apiVersion: gateway.kgateway.dev/v1alpha1
      kind: TrafficPolicy
      metadata:
        name: httpbin-headers
        namespace: kgateway-system
      spec:
        targetRefs:
        - group: gateway.networking.k8s.io
          kind: Gateway
          name: http
        headerModifiers:
          request:
            set:
            - name: x-client-ip
              value: "%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%"
      EOF

  2. Send a request to the httpbin app on the headers.example domain. Verify that the X-Client-Ip request header is set to the downstream remote address without the port.

    curl -vi http://$INGRESS_GW_ADDRESS:8080/headers -H "host: headers.example:8080"
    curl -vi localhost:8080/headers -H "host: headers.example"

    Example output:

    {
      "headers": {
        "Accept": [
          "*/*"
        ],
        "Host": [
          "headers.example:8080"
        ],
        "X-Client-Ip": [
          "127.0.0.1"
        ],
        "X-Envoy-Expected-Rq-Timeout-Ms": [
          "15000"
        ],
        "X-Forwarded-Proto": [
          "http"
        ],
        "X-Request-Id": [
          "f83bb750-67f7-47dc-8c79-4a582892034c"
        ]
      }
    }
  3. Optional: Clean up the resources that you created.

    kubectl delete httproute httpbin-headers -n httpbin
    kubectl delete httproute httpbin-headers -n httpbin
    kubectl delete TrafficPolicy httpbin-headers -n kgateway-system