Source file
src/net/http/http2.go
1
2
3
4
5
6
7 package http
8
9 import (
10 "context"
11 "crypto/tls"
12 "errors"
13 "io"
14 "log"
15 "net"
16 "net/http/internal/http2"
17 "time"
18
19 _ "unsafe"
20 )
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 func init() {
38
39
40
41
42
43
44
45 http2.LocalAddrContextKey = LocalAddrContextKey
46 http2.NoBody = NoBody
47 }
48
49 type http2Server = http2.Server
50
51 func (s *Server) configureHTTP2() {
52 h2srv := &http2.Server{}
53
54
55
56 if s.IdleTimeout != 0 {
57 h2srv.IdleTimeout = s.IdleTimeout
58 } else {
59 h2srv.IdleTimeout = s.ReadTimeout
60 }
61
62 if s.TLSConfig == nil {
63 s.TLSConfig = &tls.Config{}
64 }
65 s.nextProtoErr = h2srv.Configure(http2ServerConfig{s}, s.TLSConfig)
66 if s.nextProtoErr != nil {
67 return
68 }
69
70 s.RegisterOnShutdown(h2srv.GracefulShutdown)
71
72 if s.TLSNextProto == nil {
73 s.TLSNextProto = make(map[string]func(*Server, *tls.Conn, Handler))
74 }
75 type baseContexter interface {
76 BaseContext() context.Context
77 }
78 s.TLSNextProto["h2"] = func(hs *Server, c *tls.Conn, h Handler) {
79 h2srv.ServeConn(c, &http2.ServeConnOpts{
80 Context: h.(baseContexter).BaseContext(),
81 Handler: http2Handler{h},
82 BaseConfig: http2ServerConfig{hs},
83 })
84 }
85 s.TLSNextProto[nextProtoUnencryptedHTTP2] = func(hs *Server, c *tls.Conn, h Handler) {
86 nc := c.NetConn().(interface {
87 UnencryptedNetConn() net.Conn
88 }).UnencryptedNetConn()
89 h2srv.ServeConn(nc, &http2.ServeConnOpts{
90 Context: h.(baseContexter).BaseContext(),
91 Handler: http2Handler{h},
92 BaseConfig: http2ServerConfig{hs},
93 SawClientPreface: true,
94 })
95 }
96
97 s.h2 = h2srv
98 }
99
100 func serveHTTP2Conn(ctx context.Context, c *conn, h Handler) bool {
101 if c.server.h2 == nil {
102 return false
103 }
104 c.server.h2.ServeConn(c.rwc, &http2.ServeConnOpts{
105 Context: ctx,
106 Handler: http2Handler{h},
107 BaseConfig: http2ServerConfig{c.server},
108 SawClientPreface: true,
109 })
110 return true
111 }
112
113 type http2Handler struct {
114 h Handler
115 }
116
117 func (h http2Handler) ServeHTTP(w *http2.ResponseWriter, req *http2.ServerRequest) {
118 h.h.ServeHTTP(http2ResponseWriter{w}, &Request{
119 ctx: req.Context,
120 Proto: "HTTP/2.0",
121 ProtoMajor: 2,
122 ProtoMinor: 0,
123 Method: req.Method,
124 URL: req.URL,
125 Header: Header(req.Header),
126 RequestURI: req.RequestURI,
127 Trailer: Header(req.Trailer),
128 Body: req.Body,
129 Host: req.Host,
130 ContentLength: req.ContentLength,
131 RemoteAddr: req.RemoteAddr,
132 TLS: req.TLS,
133 MultipartForm: req.MultipartForm,
134 })
135 }
136
137 type http2ResponseWriter struct {
138 *http2.ResponseWriter
139 }
140
141
142 var (
143 _ CloseNotifier = http2ResponseWriter{}
144 _ Flusher = http2ResponseWriter{}
145 _ io.StringWriter = http2ResponseWriter{}
146 )
147
148 func (w http2ResponseWriter) Flush() { w.ResponseWriter.FlushError() }
149 func (w http2ResponseWriter) FlushError() error { return w.ResponseWriter.FlushError() }
150
151 func (w http2ResponseWriter) Header() Header { return Header(w.ResponseWriter.Header()) }
152
153 func (w http2ResponseWriter) Push(target string, opts *PushOptions) error {
154 var (
155 method string
156 header http2.Header
157 )
158 if opts != nil {
159 method = opts.Method
160 header = http2.Header(opts.Header)
161 }
162 err := w.ResponseWriter.Push(target, method, header)
163 if err == http2.ErrNotSupported {
164 err = ErrNotSupported
165 }
166 return err
167 }
168
169 type http2ServerConfig struct {
170 s *Server
171 }
172
173 func (s http2ServerConfig) MaxHeaderBytes() int { return s.s.MaxHeaderBytes }
174 func (s http2ServerConfig) ConnState(c net.Conn, st http2.ConnState) {
175 if s.s.ConnState != nil {
176 s.s.ConnState(c, ConnState(st))
177 }
178 }
179 func (s http2ServerConfig) DoKeepAlives() bool { return s.s.doKeepAlives() }
180 func (s http2ServerConfig) WriteTimeout() time.Duration { return s.s.WriteTimeout }
181 func (s http2ServerConfig) SendPingTimeout() time.Duration { return s.s.ReadTimeout }
182 func (s http2ServerConfig) ErrorLog() *log.Logger { return s.s.ErrorLog }
183 func (s http2ServerConfig) IdleTimeout() time.Duration { return s.s.IdleTimeout }
184 func (s http2ServerConfig) ReadTimeout() time.Duration { return s.s.ReadTimeout }
185 func (s http2ServerConfig) DisableClientPriority() bool { return s.s.DisableClientPriority }
186 func (s http2ServerConfig) HTTP2Config() http2.Config {
187 if s.s.HTTP2 == nil {
188 return http2.Config{}
189 }
190 return (http2.Config)(*s.s.HTTP2)
191 }
192
193 func (t *Transport) configureHTTP2(protocols Protocols) {
194 if t.TLSClientConfig == nil {
195 t.TLSClientConfig = &tls.Config{}
196 }
197 if t.HTTP2 == nil {
198 t.HTTP2 = &HTTP2Config{}
199 }
200 t2 := http2.NewTransport(transportConfig{t})
201 t2.AllowHTTP = true
202 t.h2transport = t2
203
204 t.registerProtocol("https", http2RoundTripper{t2, true})
205 if t.TLSNextProto == nil {
206 t.TLSNextProto = make(map[string]func(authority string, c *tls.Conn) RoundTripper)
207 }
208 t.TLSNextProto["h2"] = func(authority string, c *tls.Conn) RoundTripper {
209 err := t2.AddConn("https", authority, c)
210 if err != nil {
211 return http2ErringRoundTripper{err}
212 }
213 return http2RoundTripper{t2, false}
214 }
215 t.TLSNextProto[nextProtoUnencryptedHTTP2] = func(authority string, c *tls.Conn) RoundTripper {
216 unencrypted, ok := c.NetConn().(unencryptedNetConnInTLSConn)
217 if !ok {
218 return http2ErringRoundTripper{errors.New("http: *tls.Conn expected to wrap an unencrypted conn, but does not (BUG)")}
219 }
220 err := t2.AddConn("http", authority, unencrypted.conn)
221 if err != nil {
222 return http2ErringRoundTripper{err}
223 }
224 return http2RoundTripper{t2, false}
225 }
226
227
228
229
230 if limit1 := t.MaxResponseHeaderBytes; limit1 != 0 && t2.MaxHeaderListSize == 0 {
231 const h2max = 1<<32 - 1
232 if limit1 >= h2max {
233 t2.MaxHeaderListSize = h2max
234 } else {
235 t2.MaxHeaderListSize = uint32(limit1)
236 }
237 }
238
239
240
241
242
243
244 t.TLSClientConfig.NextProtos = adjustNextProtos(t.TLSClientConfig.NextProtos, protocols)
245 }
246
247 type http2ErringRoundTripper struct{ err error }
248
249 func (rt http2ErringRoundTripper) RoundTripErr() error { return rt.err }
250 func (rt http2ErringRoundTripper) RoundTrip(*Request) (*Response, error) { return nil, rt.err }
251
252 func http2RoundTrip(req *Request, rt func(*http2.ClientRequest) (*http2.ClientResponse, error)) (*Response, error) {
253 resp := &Response{}
254 cresp, err := rt(&http2.ClientRequest{
255 Context: req.Context(),
256 Method: req.Method,
257 URL: req.URL,
258 Header: http2.Header(req.Header),
259 Trailer: http2.Header(req.Trailer),
260 Body: req.Body,
261 Host: req.Host,
262 GetBody: req.GetBody,
263 ContentLength: req.ContentLength,
264 Cancel: req.Cancel,
265 Close: req.Close,
266 ResTrailer: (*http2.Header)(&resp.Trailer),
267 })
268 if err != nil {
269 return nil, err
270 }
271 resp.Status = cresp.Status + " " + StatusText(cresp.StatusCode)
272 resp.StatusCode = cresp.StatusCode
273 resp.Proto = "HTTP/2.0"
274 resp.ProtoMajor = 2
275 resp.ProtoMinor = 0
276 resp.ContentLength = cresp.ContentLength
277 resp.Uncompressed = cresp.Uncompressed
278 resp.Header = Header(cresp.Header)
279 resp.Trailer = Header(cresp.Trailer)
280 resp.Body = cresp.Body
281 resp.TLS = cresp.TLS
282 resp.Request = req
283 return resp, nil
284 }
285
286 type http2RoundTripper struct {
287 t *http2.Transport
288 mapCachedConnErr bool
289 }
290
291 func (rt http2RoundTripper) RoundTrip(req *Request) (*Response, error) {
292 resp, err := http2RoundTrip(req, rt.t.RoundTrip)
293 if err != nil {
294 if rt.mapCachedConnErr && http2isNoCachedConnError(err) {
295 err = ErrSkipAltProtocol
296 }
297 return nil, err
298 }
299 return resp, nil
300 }
301
302 func (rt http2RoundTripper) NewClientConn(nc net.Conn, internalStateHook func()) (RoundTripper, error) {
303 cc, err := rt.t.NewClientConn(nc, internalStateHook)
304 if err != nil {
305 return nil, err
306 }
307 return http2ClientConn{cc}, nil
308 }
309
310 type http2ClientConn struct {
311 http2.NetHTTPClientConn
312 }
313
314 func (cc http2ClientConn) RoundTrip(req *Request) (*Response, error) {
315 return http2RoundTrip(req, cc.NetHTTPClientConn.RoundTrip)
316 }
317
318 type transportConfig struct {
319 t *Transport
320 }
321
322 func (t transportConfig) MaxResponseHeaderBytes() int64 { return t.t.MaxResponseHeaderBytes }
323 func (t transportConfig) DisableCompression() bool { return t.t.DisableCompression }
324 func (t transportConfig) DisableKeepAlives() bool { return t.t.DisableKeepAlives }
325 func (t transportConfig) ExpectContinueTimeout() time.Duration { return t.t.ExpectContinueTimeout }
326 func (t transportConfig) ResponseHeaderTimeout() time.Duration { return t.t.ResponseHeaderTimeout }
327 func (t transportConfig) IdleConnTimeout() time.Duration { return t.t.IdleConnTimeout }
328
329 func (t transportConfig) HTTP2Config() http2.Config {
330 return *(*http2.Config)(t.t.HTTP2)
331 }
332
333
334
335
336
337 func transportFromH1Transport(t *Transport) any {
338 t.nextProtoOnce.Do(t.onceSetNextProtoDefaults)
339 return t.h2transport
340 }
341
View as plain text