Change response status

Update the response status based on headers being present in a response.

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

Change the response status

  1. Create a TrafficPolicy resource with your transformation rules. In this example, you change the value of the :status pseudo response header to 401 if the response header foo:bar is present. If the foo:bar response header is not present, you return a 403 HTTP response code.

    kubectl apply -f- <<EOF
    apiVersion: gateway.kgateway.dev/v1alpha1
    kind: TrafficPolicy
    metadata:
      name: transformation
      namespace: httpbin
    spec:
      transformation:
        response:
          set:
          - name: ":status"
            value: '{% if header("foo") == "bar" %}401{% else %}403{% endif %}'
    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 foo:bar query parameter. This query parameter automatically gets added as a response header and therefore triggers the transformation rule that you set up. Verify that you get back a 401 HTTP response code.

    curl -vi http://$INGRESS_GW_ADDRESS:8080/response-headers?foo=bar \
     -H "host: www.example.com:8080" 
    curl -vi localhost:8080/response-headers?foo=bar \
    -H "host: www.example.com" 

    Example output:

    < HTTP/1.1 401 Unauthorized
    HTTP/1.1 401 Unauthorized
    < 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
    < foo: bar
    foo: bar
    < content-length: 29
    content-length: 29
    < x-envoy-upstream-service-time: 4
    x-envoy-upstream-service-time: 4
    < server: envoy
    server: envoy
    < 
    
    {
      "foo": [
        "bar"
      ]
    }
    
  4. Send another request to the httpbin app. This time, you include the foo:bar2 query parameter. Verify that you get back a 403 HTTP response code.

    curl -vi http://$INGRESS_GW_ADDRESS:8080/response-headers?foo=bar2 \
     -H "host: www.example.com:8080" 
    curl -vi localhost:8080/response-headers?foo=bar2 \
    -H "host: www.example.com" 

    Example output:

    < HTTP/1.1 403 Forbidden
    HTTP/1.1 403 Forbidden
    < 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
    < foo: bar
    foo: bar
    < content-length: 29
    content-length: 29
    < x-envoy-upstream-service-time: 4
    x-envoy-upstream-service-time: 4
    < server: envoy
    server: envoy
    < 
    
    {
      "foo": [
        "bar2"
      ]
    }
    

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