From 1367b967b3a2af17df28f4062b29d7210e5f6003 Mon Sep 17 00:00:00 2001 From: chungthuang Date: Tue, 28 Oct 2025 08:41:42 -0500 Subject: [PATCH] TUN-9849: Add cf-proxy-* to control response headers These headers will not be returned to the eyeball --- connection/header.go | 3 ++- connection/header_test.go | 30 +++++++++++++++--------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/connection/header.go b/connection/header.go index 269e56a7..0b48e822 100644 --- a/connection/header.go +++ b/connection/header.go @@ -53,7 +53,8 @@ var headerEncoding = base64.RawStdEncoding func IsControlResponseHeader(headerName string) bool { return strings.HasPrefix(headerName, ":") || strings.HasPrefix(headerName, "cf-int-") || - strings.HasPrefix(headerName, "cf-cloudflared-") + strings.HasPrefix(headerName, "cf-cloudflared-") || + strings.HasPrefix(headerName, "cf-proxy-") } // isWebsocketClientHeader returns true if the header name is required by the client to upgrade properly diff --git a/connection/header_test.go b/connection/header_test.go index 1ca4b31b..4aa259c4 100644 --- a/connection/header_test.go +++ b/connection/header_test.go @@ -1,18 +1,17 @@ package connection import ( - "fmt" "net/http" "reflect" "sort" "testing" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestSerializeHeaders(t *testing.T) { request, err := http.NewRequest(http.MethodGet, "http://example.com", nil) - assert.NoError(t, err) + require.NoError(t, err) mockHeaders := http.Header{ "Mock-Header-One": {"Mock header one value", "three"}, @@ -39,22 +38,22 @@ func TestSerializeHeaders(t *testing.T) { serializedHeaders := SerializeHeaders(request.Header) // Sanity check: the headers serialized to something that's not an empty string - assert.NotEqual(t, "", serializedHeaders) + require.NotEqual(t, "", serializedHeaders) // Deserialize back, and ensure we get the same set of headers deserializedHeaders, err := DeserializeHeaders(serializedHeaders) - assert.NoError(t, err) + require.NoError(t, err) - assert.Equal(t, 13, len(deserializedHeaders)) + require.Len(t, deserializedHeaders, 13) expectedHeaders := headerToReqHeader(mockHeaders) sort.Sort(ByName(deserializedHeaders)) sort.Sort(ByName(expectedHeaders)) - assert.True( + require.True( t, reflect.DeepEqual(expectedHeaders, deserializedHeaders), - fmt.Sprintf("got = %#v, want = %#v\n", deserializedHeaders, expectedHeaders), + "got = %#v, want = %#v\n", deserializedHeaders, expectedHeaders, ) } @@ -82,12 +81,12 @@ func headerToReqHeader(headers http.Header) (reqHeaders []HTTPHeader) { func TestSerializeNoHeaders(t *testing.T) { request, err := http.NewRequest(http.MethodGet, "http://example.com", nil) - assert.NoError(t, err) + require.NoError(t, err) serializedHeaders := SerializeHeaders(request.Header) deserializedHeaders, err := DeserializeHeaders(serializedHeaders) - assert.NoError(t, err) - assert.Equal(t, 0, len(deserializedHeaders)) + require.NoError(t, err) + require.Empty(t, deserializedHeaders) } func TestDeserializeMalformed(t *testing.T) { @@ -102,21 +101,22 @@ func TestDeserializeMalformed(t *testing.T) { for _, malformedValue := range malformedData { _, err = DeserializeHeaders(malformedValue) - assert.Error(t, err) + require.Error(t, err) } } func TestIsControlResponseHeader(t *testing.T) { controlResponseHeaders := []string{ - // Anything that begins with cf-int- or cf-cloudflared- + // Anything that begins with cf-int-, cf-cloudflared- or cf-proxy- "cf-int-sample-header", "cf-cloudflared-sample-header", + "cf-proxy-sample-header", // Any http2 pseudoheader ":sample-pseudo-header", } for _, header := range controlResponseHeaders { - assert.True(t, IsControlResponseHeader(header)) + require.True(t, IsControlResponseHeader(header)) } } @@ -130,6 +130,6 @@ func TestIsNotControlResponseHeader(t *testing.T) { } for _, header := range notControlResponseHeaders { - assert.False(t, IsControlResponseHeader(header)) + require.False(t, IsControlResponseHeader(header)) } }