Decode and modify base64 request headers
You can decode and modify incoming headers before sending the request to an upstream by using Gloo transformations.
Setup
This guide assumes that you installed the following components:
- Gloo Gateway in the
gloo-system
namespace in your cluster - The
glooctl
command line utility - The jq command line utility to format JSON strings
You also need an upstream service to serve as the target for the requests that you send to test the Gloo Gateway configurations in this tutorial. You can use the publicly available Postman Echo service. Postman Echo exposes a set of endpoints that are very useful for inspecting both the requests sent upstream and the resulting responses. For more information about this service, see the Postman Echo documentation.
Create a static upstream to represent the postman-echo.com remote service.
apiVersion: gloo.solo.io/v1
kind: Upstream
metadata:
name: postman-echo
namespace: gloo-system
spec:
static:
hosts:
- addr: postman-echo.com
port: 80
Next, create a simple Virtual Service that matches any path and routes all traffic to the Upstream.
apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
name: decode-and-modify-header
namespace: gloo-system
spec:
virtualHost:
domains:
- '*'
routes:
- matchers:
- prefix: /
routeAction:
single:
upstream:
name: postman-echo
namespace: gloo-system
Finally, test that Gloo Gateway picked up the configuration by sending a request with a base64-encoded header.
curl -v -H "x-test: $(echo -n 'testprefix.testsuffix' | base64)" $(glooctl proxy url)/get | jq
Review the JSON output similar to the following 200
status response. Note that the x-test
header in the payload response from postman-echo has the base64 representation of the string literal testprefix.testsuffix
that you passed in the request.
{
"args": {},
"headers": {
"x-forwarded-proto": "http",
"x-forwarded-port": "80",
"host": "localhost",
"x-amzn-trace-id": "Root=1-6336f537-6c0a1f3d6c6849b10f65409c",
"user-agent": "curl/7.64.1",
"accept": "*/*",
"x-test": "dGVzdHByZWZpeC50ZXN0c3VmZml4",
"x-request-id": "7b1e64fe-e30a-437f-a826-ca5e349f50d4",
"x-envoy-expected-rq-timeout-ms": "15000"
},
"url": "http://localhost/get"
}
Modifying the request header
As confirmed in the test request of the setup, the upstream service echoes the headers that you include in the request inside the headers
response body attribute. Now, you can configure Gloo Gateway to decode and modify the value of this header before sending it to the upstream.
Update the Virtual Service
To implement this behavior, add a responseTransformation
stanza to the original Virtual Service definition. Note that the request_header
, base64_decode
, and substring
functions are used in an Inja template to:
- Extract the value of the
x-test
header from the request - Decode the extracted value from base64
- Extract the substring beginning with the eleventh character of the input string
The output of this chain of events is injected into a new request header x-decoded-test
.
apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
name: decode-and-modify-header
namespace: gloo-system
spec:
virtualHost:
domains:
- '*'
routes:
- matchers:
- prefix: /
routeAction:
single:
upstream:
name: postman-echo
namespace: gloo-system
options:
transformations:
requestTransformation:
transformationTemplate:
headers:
x-decoded-test:
text: '{{substring(base64_decode(request_header("x-test")), 11)}}'
Test the modified configuration
Test the modified Virtual Service by issuing a curl request.
curl -v -H "x-test: $(echo -n 'testprefix.testsuffix' | base64)" $(glooctl proxy url)/get | jq
Review the output similar to the following JSON response. Note that the value of the inject header x-decoded-test
has a substring of the decoded base64 value that was sent in the x-test
header.
{
"args": {},
"headers": {
"x-forwarded-proto": "http",
"x-forwarded-port": "80",
"host": "localhost",
"x-amzn-trace-id": "Root=1-6336f482-164a3d207b026fe358de000f",
"user-agent": "curl/7.64.1",
"accept": "*/*",
"x-test": "dGVzdHByZWZpeC50ZXN0c3VmZml4",
"x-request-id": "1fbed7be-0089-4d19-a9c2-221ca088e40b",
"x-decoded-test": "testsuffix",
"x-envoy-expected-rq-timeout-ms": "15000"
},
"url": "http://localhost/get"
}
Congratulations! You successfully used a request transformation to decode and modify a request header!
Cleanup
You can clean up the resources that you created in this tutorial.
kubectl delete virtualservice -n gloo-system decode-and-modify-header
kubectl delete upstream -n gloo-system postman-echo