Header Matching
The route rules in a Virtual Service can use header matching rules to match requests to routes based on the contents of the headers. When configuring the matcher on a route, you may want to specify one or more Header Matchers to require headers with matching values be present on the request. Each header matcher has three attributes:
name
- the name of the request header. Note: Gloo Gateway/Envoy use HTTP/2 so if you want to match against HTTP/1Host
, use:authority
(HTTP/2) as the name instead.regex
- boolean (true|false) defaults tofalse
. Indicates how to interpret thevalue
attribute:false
(default) - treatvalue
field as an Envoy exact_matchtrue
- treatvalue
field as a regular expression as defined by Envoy regex_match
value
- If no value is specified, then the presence of the header in the request with any value will match (Envoy present_match)
- If present, then field value interpreted based on the value of
regex
field invertMatch
- inverts the matching logic. A request matches if it does not match the above criteria. Note that Gloo Gateway 0.20.9 or later is required to use this setting.
When you use header matchers, you must also specify a prefix matcher. Note that the path you define in prefix matcher cannot contain any hyphens (-
).
In this guide, we’re going to take a closer look at an example Virtual Service that uses multiple headers to match requests. We’ll begin by creating an Upstream and then creating the Virtual Service to route requests to that Upstream based on the headers submitted as part of the request.
Setup
If you have not yet deployed Gloo Gateway, you can start by following the directions contained within the guide Installing Gloo Gateway on Kubernetes.
This guide also assumes that you are running Gloo Gateway in a Kubernetes cluster. Each example can be adapted to alternative deployments, such as using the HashiCorp stack of Nomad, Consul, and Vault.
This guide assumes that you have deployed Gloo to the gloo-system
namespace and that the glooctl
command line utility
is installed on your machine. glooctl
provides several convenient functions to view, manipulate, and debug Gloo resources;
in particular, it is worth mentioning the following command, which we will use each time we need to retrieve the URL of
the Gloo Gateway that is running inside your cluster:
glooctl proxy url
Create an Upstream
First we are going to create a simple Upstream for testing called json-upstream
, that routes to a static site.
apiVersion: gloo.solo.io/v1
kind: Upstream
metadata:
name: json-upstream
namespace: gloo-system
spec:
static:
hosts:
- addr: jsonplaceholder.typicode.com
port: 80
glooctl create upstream static --static-hosts jsonplaceholder.typicode.com:80 --name json-upstream
Create a Virtual Service
Let’s create a Virtual Service with several header match rules. For simplicity, we’ll set the path matcher to prefix on /
to match all request paths. Note that when you use header matchers, you must also specify a prefix matcher, and the path you define in prefix matcher cannot contain any hyphens (-
).
apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
name: test-header
namespace: gloo-system
spec:
virtualHost:
domains:
- 'foo'
routes:
- matchers:
- headers:
- name: header1
value: value1
- name: header2
- name: header3
regex: true
value: "[a-z]{1}"
- name: header4
invertMatch: true
- name: header5
value: value5
invertMatch: true
prefix: /
routeAction:
single:
upstream:
name: json-upstream
namespace: gloo-system
options:
autoHostRewrite: true
We can now make a curl request to the new Virtual Service and set valid values for each header. In this case,
header1
must be present and equal value1,header2
must be present and can equal any value,header3
must be present and can equal any value that is a single lowercase letterheader4
must not be presentheader5
must be present and must not equalvalue5
Let’s send a request that satisfies all these criteria.
curl -v -H "Host: foo" -H "header1: value1" -H "header2: value2" -H "header3: v" \
-H "header5: x" $(glooctl proxy url)/posts
This returns a json
list of posts.
If we use an incorrect value for header1
, we’ll see a 404.
curl -v -H "Host: foo" -H "header1: othervalue" -H "header2: value2" -H "header3: v" \
-H "header5: x" $(glooctl proxy url)/posts
If we use a different value for header2
, we’ll see all the posts.
curl -v -H "Host: foo" -H "header1: value1" -H "header2: othervalue" -H "header3: v" \
-H "header5: x" $(glooctl proxy url)/posts
If we use an invalid value for header3
, we’ll get a 404.
curl -v -H "Host: foo" -H "header1: value1" -H "header2: value2" -H "header3: value3" \
-H "header5: x" $(glooctl proxy url)/posts
The invertMatch
attribute for header4
causes request to be matched only if it does not include a header named header4
. If we send a request with that header, we’ll get a 404 response.
curl -v -H "Host: foo" -H "header1: value1" -H "header2: value2" -H "header3: v" \
-H "header4: value4" -H "header5: x" $(glooctl proxy url)/posts
The invertMatch
attribute can be combined with value match specifications. Where header4
had no value spec, the inversion invalidated all possible values. The match constraints on header5
, on the other hand, mean that the request will only match if the value is not equal to value5
. If we send a request with that value, we’ll get a 404 response.
curl -v -H "Host: foo" -H "header1: value1" -H "header2: value2" -H "header3: v" \
-H "header5: value5" $(glooctl proxy url)/posts
Summary
In this guide, we added header matchers to a Virtual Service route. We used exact match and regex matchers for a header value, and also showed how to match on a header without any specific value.
Let’s cleanup the Virtual Service and Upstream we used.
kubectl delete vs -n gloo-system test-header
kubectl delete upstream -n gloo-system json-upstream
glooctl delete vs test-header
glooctl delete upstream json-upstream
Next Steps
Header matching rules are not the only rules available for routing decisions. We recommend checking out any of the following guides next: