Verified Commit 458a6432 authored by Steve Xuereb's avatar Steve Xuereb
Browse files

fix(correlation): cf-ray header precedance

What
---
`X-Request-ID` takes precedence over `cf-ray` header for correlation.

Why
---
We can have two services communicating with each other that are behind Cloudflare
for example, HTTP Router and Topology Service. When the HTTP Router sends a
request to Topology Service `cf-ray` gets regenerated by Cloudflare, so
we can never correlate anything between the two services.

```
User
    ↓
Cloudflare Edge (DME/Moscow) → Ray ID: 9c40f4f908af1229
    ↓
HTTP Router (CF Worker)
    ↓
Cloudflare Zero Trust / Proxy () → NEW Ray ID: Random ID
    ↓
Topology Service (GCP)
    ↓
Topology Service (GCP) logs `Random ID` instead of 9c40f4f908af1229
```

If `X-Request-ID` takes precedence we can still use `cf-ray` as the correlation ID for
services that are the public entry point and don't specify
`X-Request-ID`.

reference: https://gitlab.com/gitlab-com/gl-infra/production-engineering/-/work_items/28225
parent 3618676e
Loading
Loading
Loading
Loading
Loading
+4 −6
Original line number Diff line number Diff line
@@ -13,8 +13,7 @@ const cfRayHeader = "Cf-Ray"
// Whether the Correlation-ID is generated or propagated, once inside this handler the request context
// will have a Correlation-ID associated with it.
//
// If WithAdoptCfRayHeader is enabled, we will try to grab Cf-Ray as the correlation id first and then fall
// back to X-Request-ID.
// If WithAdoptCfRayHeader is enabled and X-Request-ID is not present, we will use Cf-Ray as the correlation id.
func InjectCorrelationID(h http.Handler, opts ...InboundHandlerOption) http.Handler {
	config := applyInboundHandlerOptions(opts)

@@ -25,12 +24,11 @@ func InjectCorrelationID(h http.Handler, opts ...InboundHandlerOption) http.Hand
		clientName := ""

		if config.shouldPropagate(r) {
			if config.adoptCfRayHeader {
				correlationID = r.Header.Get(cfRayHeader)
			}
			if correlationID == "" {
			correlationID = r.Header.Get(propagationHeader)
			if correlationID == "" && config.adoptCfRayHeader {
				correlationID = r.Header.Get(cfRayHeader)
			}

			clientName = r.Header.Get(clientNameHeader)
		}

+2 −2
Original line number Diff line number Diff line
@@ -61,8 +61,8 @@ func WithSetResponseHeader() InboundHandlerOption {
// handler in the request path (i.e. workhorse).
//
// The logic will be as follows:
// - Adopt Cf-Ray if present.
// - Else, fall back to adopting Request-ID.
// - Use X-Request-ID
// - Else, fall back to Cf-Ray if present.
// - Else, generate fresh ULID.
//
// Requires WithPropagation to be enabled.
+3 −3
Original line number Diff line number Diff line
@@ -252,7 +252,7 @@ func TestInjectCorrelationID(t *testing.T) {
				cfRayHeader:       {"cf-ray-456"},
				propagationHeader: {"request-123"},
			},
			shouldMatch: "cf-ray-456",
			shouldMatch: "request-123",
		},
		{
			name: "with_adopt_cf_ray_header_only_cf_ray",
@@ -293,7 +293,7 @@ func TestInjectCorrelationID(t *testing.T) {
				cfRayHeader:       {"cf-ray-202"},
				propagationHeader: {"request-303"},
			},
			shouldMatch: "cf-ray-202",
			shouldMatch: "request-303",
		},
		{
			name: "with_adopt_cf_ray_header_untrusted_cidrs",
@@ -307,7 +307,7 @@ func TestInjectCorrelationID(t *testing.T) {
				cfRayHeader:       {"cf-ray-404"},
				propagationHeader: {"request-505"},
			},
			shouldNotMatch: "cf-ray-404",
			shouldNotMatch: "request-505",
		},
	}