TUN-9849: Add cf-proxy-* to control response headers

These headers will not be returned to the eyeball
This commit is contained in:
chungthuang 2025-10-28 08:41:42 -05:00
parent 114683f49e
commit 1367b967b3
2 changed files with 17 additions and 16 deletions

View File

@ -53,7 +53,8 @@ var headerEncoding = base64.RawStdEncoding
func IsControlResponseHeader(headerName string) bool { func IsControlResponseHeader(headerName string) bool {
return strings.HasPrefix(headerName, ":") || return strings.HasPrefix(headerName, ":") ||
strings.HasPrefix(headerName, "cf-int-") || 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 // isWebsocketClientHeader returns true if the header name is required by the client to upgrade properly

View File

@ -1,18 +1,17 @@
package connection package connection
import ( import (
"fmt"
"net/http" "net/http"
"reflect" "reflect"
"sort" "sort"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/require"
) )
func TestSerializeHeaders(t *testing.T) { func TestSerializeHeaders(t *testing.T) {
request, err := http.NewRequest(http.MethodGet, "http://example.com", nil) request, err := http.NewRequest(http.MethodGet, "http://example.com", nil)
assert.NoError(t, err) require.NoError(t, err)
mockHeaders := http.Header{ mockHeaders := http.Header{
"Mock-Header-One": {"Mock header one value", "three"}, "Mock-Header-One": {"Mock header one value", "three"},
@ -39,22 +38,22 @@ func TestSerializeHeaders(t *testing.T) {
serializedHeaders := SerializeHeaders(request.Header) serializedHeaders := SerializeHeaders(request.Header)
// Sanity check: the headers serialized to something that's not an empty string // 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 // Deserialize back, and ensure we get the same set of headers
deserializedHeaders, err := DeserializeHeaders(serializedHeaders) 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) expectedHeaders := headerToReqHeader(mockHeaders)
sort.Sort(ByName(deserializedHeaders)) sort.Sort(ByName(deserializedHeaders))
sort.Sort(ByName(expectedHeaders)) sort.Sort(ByName(expectedHeaders))
assert.True( require.True(
t, t,
reflect.DeepEqual(expectedHeaders, deserializedHeaders), 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) { func TestSerializeNoHeaders(t *testing.T) {
request, err := http.NewRequest(http.MethodGet, "http://example.com", nil) request, err := http.NewRequest(http.MethodGet, "http://example.com", nil)
assert.NoError(t, err) require.NoError(t, err)
serializedHeaders := SerializeHeaders(request.Header) serializedHeaders := SerializeHeaders(request.Header)
deserializedHeaders, err := DeserializeHeaders(serializedHeaders) deserializedHeaders, err := DeserializeHeaders(serializedHeaders)
assert.NoError(t, err) require.NoError(t, err)
assert.Equal(t, 0, len(deserializedHeaders)) require.Empty(t, deserializedHeaders)
} }
func TestDeserializeMalformed(t *testing.T) { func TestDeserializeMalformed(t *testing.T) {
@ -102,21 +101,22 @@ func TestDeserializeMalformed(t *testing.T) {
for _, malformedValue := range malformedData { for _, malformedValue := range malformedData {
_, err = DeserializeHeaders(malformedValue) _, err = DeserializeHeaders(malformedValue)
assert.Error(t, err) require.Error(t, err)
} }
} }
func TestIsControlResponseHeader(t *testing.T) { func TestIsControlResponseHeader(t *testing.T) {
controlResponseHeaders := []string{ 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-int-sample-header",
"cf-cloudflared-sample-header", "cf-cloudflared-sample-header",
"cf-proxy-sample-header",
// Any http2 pseudoheader // Any http2 pseudoheader
":sample-pseudo-header", ":sample-pseudo-header",
} }
for _, header := range controlResponseHeaders { 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 { for _, header := range notControlResponseHeaders {
assert.False(t, IsControlResponseHeader(header)) require.False(t, IsControlResponseHeader(header))
} }
} }