Skip to content

Commit 233fb2e

Browse files
chore(): doc on http to https redirect
1 parent 08c35d8 commit 233fb2e

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# HTTP Redirection: Why 308 Matters for APIs
2+
3+
This document explains the technical details behind the HTTP redirection issue we fixed in the `ai-gateway-core` chart.
4+
5+
## 1. The Core Issue: 301 vs. 308
6+
7+
When a client (like `curl`) makes a request to `http://` and receives a redirect to `https://`, the status code tells the client exactly how to behave.
8+
9+
### HTTP 301 (Moved Permanently)
10+
* **Legacy Behavior**: Originally, the spec said the method should be preserved. In practice, however, most browsers and clients (including `curl`) **change the method to GET** and drop the request body when following a 301 redirect.
11+
* **The Symptom**: Your `POST` request became a `GET` request on the second leg, leading to "method not allowed" or missing body errors.
12+
13+
### HTTP 308 (Permanent Redirect)
14+
* **Modern Behavior**: This code was specifically created to solve the ambiguity of 301. It **requires** the client to preserve the original HTTP method and body.
15+
* **The Result**: A `POST` remains a `POST`. This is essential for REST APIs.
16+
17+
## 2. The Discovery
18+
We knew it was a redirection issue when your `curl -v` log showed:
19+
```text
20+
* Clear auth, redirects to port from 80 to 443
21+
* Switch from POST to GET
22+
```
23+
This "Switch from POST to GET" is the hallmark behavior of a client following a 301 redirect.
24+
25+
## 3. The Implementation (Envoy Gateway)
26+
27+
### The Constraint
28+
Envoy Gateway (EG) implements the Kubernetes Gateway API. While the spec allows `308`, the **Envoy Gateway controller (as of v1.7.0) only supports `301` and `302`** in its standard `RequestRedirect` filter.
29+
30+
### The Workaround: EnvoyPatchPolicy
31+
Since we couldn't set `308` in the `HTTPRoute`, we had to go "under the hood" of the Envoy configuration (xDS) using an `EnvoyPatchPolicy`.
32+
33+
1. **Inspection**: We used `kubectl port-forward` and a `config_dump` to see exactly how EG was configuring Envoy.
34+
2. **Mapping**: We found that the redirect routes were located in specific `virtual_hosts` indices (1 and 2).
35+
3. **Patching**: We applied a JSON Patch to override the generated Envoy configuration:
36+
```yaml
37+
operation:
38+
op: add
39+
path: /virtual_hosts/1/routes/0/redirect/response_code
40+
value: "PERMANENT_REDIRECT" # This is Envoy's internal name for 308
41+
```
42+
43+
## 4. The `curl` Security Behavior
44+
45+
Even with a 308, you noticed that the `Authorization` header was initially missing in the second request.
46+
47+
### Why `curl` drops headers
48+
By default, `curl` is highly protective of your credentials. When it follows a redirect that changes the **origin** (even just a protocol change from `http` to `https`), it strips sensitive headers like `Authorization` to prevent them from being sent to a potentially malicious redirected destination.
49+
50+
### The Fix: `--location-trusted`
51+
The `--location-trusted` flag tells `curl` that you trust the redirected destination and want it to reuse the original credentials and headers.
52+
53+
## Summary Checklist for API Redirects
54+
1. **Use 308**: Always use 308 for internal HTTP -> HTTPS redirects in APIs.
55+
2. **Avoid 80**: Ideally, API clients should talk directly to 443 (HTTPS) to avoid the redirect trip entirely.
56+
3. **HSTS**: Consider enabling strict-transport-security (HSTS) headers so the client's OS remembers to use HTTPS automatically for future requests.

0 commit comments

Comments
 (0)