| // 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 | |
| } |