Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion connection/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ const (
lbProbeUserAgentPrefix = "Mozilla/5.0 (compatible; Cloudflare-Traffic-Manager/1.0; +https://www.cloudflare.com/traffic-manager/;"
LogFieldConnIndex = "connIndex"
MaxGracePeriod = time.Minute * 3
MaxConcurrentStreams = math.MaxUint32
// MaxConcurrentStreams is the HTTP/2 stream limit advertised to the edge.
// It must fit in an int32: http2.Server implementations backed by
// net/http (Go 1.27+) silently replace larger values with their default
// of 250 streams.
MaxConcurrentStreams = math.MaxInt32

contentTypeHeader = "content-type"
contentLengthHeader = "content-length"
Expand Down
37 changes: 37 additions & 0 deletions connection/http2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/rs/zerolog"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/net/http2"

"github.com/cloudflare/cloudflared/client"
"github.com/cloudflare/cloudflared/tracing"
Expand Down Expand Up @@ -101,6 +102,42 @@ func TestHTTP2ConfigurationSet(t *testing.T) {
wg.Wait()
}

// TestHTTP2AdvertisedMaxConcurrentStreams checks the SETTINGS frame the
// HTTP/2 server actually sends to the edge, not just the configured value.
// Some http2.Server implementations silently replace limits they cannot
// represent with their default of 250 streams.
func TestHTTP2AdvertisedMaxConcurrentStreams(t *testing.T) {
http2Conn, edgeConn := newTestHTTP2Connection()

ctx, cancel := context.WithCancel(t.Context())
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
_ = http2Conn.Serve(ctx)
}()
defer func() {
cancel()
wg.Wait()
}()

go func() {
_, _ = edgeConn.Write([]byte(http2.ClientPreface))
}()

require.NoError(t, edgeConn.SetReadDeadline(time.Now().Add(5*time.Second)))
framer := http2.NewFramer(nil, edgeConn)
frame, err := framer.ReadFrame()
require.NoError(t, err)
settings, ok := frame.(*http2.SettingsFrame)
require.True(t, ok, "expected the server to send SETTINGS first, got %T", frame)
require.False(t, settings.IsAck())

maxStreams, ok := settings.Value(http2.SettingMaxConcurrentStreams)
require.True(t, ok, "SETTINGS_MAX_CONCURRENT_STREAMS was not advertised")
assert.Equal(t, uint32(MaxConcurrentStreams), maxStreams)
}

func TestServeHTTP(t *testing.T) {
tests := []testRequest{
{
Expand Down