# Headers

The Envoy HTTP connection manager allows HTTP header manipulations both when the request is being received and when the response is being sent. The official documentation can be found [here](https://www.envoyproxy.io/docs/envoy/v1.15.0/configuration/http/http_conn_man/headers). Grey Matter utilizes this to manipulate HTTP headers at several levels and also allows users to add their own custom headers.

The order of header precedence is:

1. Weighted cluster level headers
2. Route level headers
3. Virtual host level headers
4. Global level headers

## Header manipulations

In order to keep track of potential overwrites of header values, we will go over places we can add custom headers in the order of precedence. Envoy supports some variables mentioned [here](https://www.envoyproxy.io/docs/envoy/v1.15.0/configuration/http/http_conn_man/headers#custom-request-response-headers).

### 2. Virtual host level headers

You can append your custom headers by defining `custom_headers` at the Domain level:

```javascript
{
  ...,
  "custom_headers": [
    {
      "key": "My-Custom-Header",
      "value": "hello-world"
    }
  ]
}
```

ℹ️ The custom headers specified here will be added to Envoy virtual host's request.

### 4. Weighted cluster level headers

* 4.1 Edge Route `response_data`
* 4.2 Service Route `response_data`
* 4.3 Edge SharedRules `response_data`
* 4.4 ServiceSharedRules `response_data`

Routes and SharedRules both have `response_data`, and values from a Route take precedence over those from a [SharedRules](https://greymatter.gitbook.io/grey-matter-documentation/1.3/reference/api/fabric-api/shared_rules) object. Between Edge's Route/SharedRules and a service's (e.g. Fibonacci service), Edge's headers take precedence; while cookies get appended.

Cookies are attached via `Set-Cookie` header and we can use aforementioned Envoy variables by setting `value_is_literal` to `false`. On the other hand, by setting `value_is_literal` to `true`, the `%` literal can be used without escaping.

```javascript
{
  ...,
  "response_data": {
    "headers": [
      {
        "name": "My-Custom-Header",
        "value": "hello-world",
        "value_is_literal": true
      }
    ],
    "cookies": [
      {
        "name": "my_cookie",
        "value": "cookie-value",
        "value_is_literal": true,
        "expires_in_sec": 60000,
        "domain": "a5c047016227111ea9bff0295a6daf52-1281033796.us-west-2.elb.amazonaws.com",
        "path": "/",
        "secure": true,
        "http_only": true,
        "same_site": "Lax"
      }
    ]
  }
}
```

ℹ️ As the name suggests, headers specified here will be added to Envoy weighted cluster's response.

Here are naming pattern for Header and Cookie:

```
    HeaderNamePatternStr = "^[0-9A-Za-z-]+$"
    CookieNamePatternStr = "^[0-9A-Za-z_.-]+$"
```
