blob: 755b77f27b31bb29ac2d15236455960ae5b5d2d6 [file]
// Copyright 2026 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !nethttpomithttp2 && !(nethttpomithttp2server && nethttpomithttp2client)
package http
import "net/http/internal/http2"
// net/http supports HTTP/2 by default, but this support is removed when
// the nethttpomithttp2 build tag is set. The nethttpomithttp2server and
// nethttpomithttp2client build tags remove only HTTP/2 server or client
// support, respectively. Setting both is equivalent to nethttpomithttp2.
//
// HTTP/2 support is provided by the net/http/internal/http2 package.
//
// This file (http2.go), along with http2server.go and http2client.go,
// connects net/http to the http2 package.
// Since http imports http2, to avoid an import cycle we need to
// translate http package types (e.g., Request) into the equivalent
// http2 package types (e.g., http2.ClientRequest).
//
// The golang.org/x/net/http2 package is the original source of truth for
// the HTTP/2 implementation. At this time, users may still import that
// package and register its implementation on a net/http Transport or Server.
// However, the x/net package is no longer synchronized with std.
func init() {
// NoBody and LocalAddrContextKey need to have the same value
// in the http and http2 packages.
//
// We can't define these values in net/http/internal,
// because their concrete types are part of the net/http API and
// moving them causes API checker failures.
// Override the http2 package versions at init time instead.
http2.LocalAddrContextKey = LocalAddrContextKey
http2.NoBody = NoBody
}
type http2Configer interface {
HTTP2Config() HTTP2Config
}
func mergeHTTP2Config(c1 *HTTP2Config, confer http2Configer) http2.Config {
if c1 == nil && confer == nil {
return http2.Config{}
}
var c http2.Config
if c1 != nil {
c = (http2.Config)(*c1)
}
var c2 HTTP2Config
if confer != nil {
c2 = confer.HTTP2Config()
}
if c.MaxConcurrentStreams == 0 {
c.MaxConcurrentStreams = c2.MaxConcurrentStreams
}
if c2.StrictMaxConcurrentRequests {
c.StrictMaxConcurrentRequests = true
}
if c.MaxDecoderHeaderTableSize == 0 {
c.MaxDecoderHeaderTableSize = c2.MaxDecoderHeaderTableSize
}
if c.MaxEncoderHeaderTableSize == 0 {
c.MaxEncoderHeaderTableSize = c2.MaxEncoderHeaderTableSize
}
if c.MaxReadFrameSize == 0 {
c.MaxReadFrameSize = c2.MaxReadFrameSize
}
if c.MaxReceiveBufferPerConnection == 0 {
c.MaxReceiveBufferPerConnection = c2.MaxReceiveBufferPerConnection
}
if c.MaxReceiveBufferPerStream == 0 {
c.MaxReceiveBufferPerStream = c2.MaxReceiveBufferPerStream
}
if c.SendPingTimeout == 0 {
c.SendPingTimeout = c2.SendPingTimeout
}
if c.PingTimeout == 0 {
c.PingTimeout = c2.PingTimeout
}
if c.WriteByteTimeout == 0 {
c.WriteByteTimeout = c2.WriteByteTimeout
}
if c2.PermitProhibitedCipherSuites {
c.PermitProhibitedCipherSuites = true
}
if c.CountError == nil {
c.CountError = c2.CountError
}
return c
}