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 type http2Transport = http2.Transport
51
52 func (s *Server) configureHTTP2() {
53 h2srv := &http2.Server{}
54
55
56
57 if s.IdleTimeout != 0 {
58 s.h2IdleTimeout = s.IdleTimeout
59 } else {
60 s.h2IdleTimeout = s.ReadTimeout
61 }
62
63 if s.TLSConfig == nil {
64 s.TLSConfig = &tls.Config{}
65 }
66 s.nextProtoErr = h2srv.Configure(http2ServerConfig{s}, s.TLSConfig)
67 if s.nextProtoErr != nil {
68 return
69 }
70
71 s.RegisterOnShutdown(h2srv.GracefulShutdown)
72
73 if s.TLSNextProto == nil {
74 s.TLSNextProto = make(map[string]func(*Server, *tls.Conn, Handler))
75 }
76
77
78 s.TLSNextProto["h2"] = func(hs *Server, c *tls.Conn, h Handler) {
79 c.Close()
80 }
81
82 s.h2 = h2srv
83 }
84
85 func (s *Server) setHTTP2Config(conf http2ExternalServerConfig) {
86 if s.h2Config != nil {
87 panic("http: HTTP/2 Server already registered")
88 }
89 s.h2Config = conf
90 s.h2Config.ServeConnFunc(s.serveHTTP2Conn)
91 }
92
93 func (s *Server) serveHTTP2Conn(ctx context.Context, nc net.Conn, h Handler, sawClientPreface bool, upgradeReq *Request, settings []byte) {
94 s.setupHTTP2_ServeTLS()
95 var serverUpgradeReq *http2.ServerRequest
96 if upgradeReq != nil {
97 serverUpgradeReq = http2ServerRequestFromRequest(upgradeReq)
98 }
99 s.h2.ServeConn(nc, &http2.ServeConnOpts{
100 Context: ctx,
101 Handler: http2Handler{h},
102 BaseConfig: http2ServerConfig{s},
103 SawClientPreface: sawClientPreface,
104 UpgradeRequest: serverUpgradeReq,
105 Settings: settings,
106 })
107 }
108
109 func http2ServerRequestFromRequest(req *Request) *http2.ServerRequest {
110 return &http2.ServerRequest{
111 Context: req.Context(),
112 Proto: req.Proto,
113 ProtoMajor: req.ProtoMajor,
114 ProtoMinor: req.ProtoMinor,
115 Method: req.Method,
116 URL: req.URL,
117 Header: http2.Header(req.Header),
118 Trailer: http2.Header(req.Trailer),
119 Body: req.Body,
120 Host: req.Host,
121 ContentLength: req.ContentLength,
122 RemoteAddr: req.RemoteAddr,
123 RequestURI: req.RequestURI,
124 TLS: req.TLS,
125 MultipartForm: req.MultipartForm,
126 }
127 }
128
129 type http2Handler struct {
130 h Handler
131 }
132
133 func (h http2Handler) ServeHTTP(w *http2.ResponseWriter, req *http2.ServerRequest) {
134 h.h.ServeHTTP(http2ResponseWriter{w}, &Request{
135 ctx: req.Context,
136 Proto: "HTTP/2.0",
137 ProtoMajor: 2,
138 ProtoMinor: 0,
139 Method: req.Method,
140 URL: req.URL,
141 Header: Header(req.Header),
142 RequestURI: req.RequestURI,
143 Trailer: Header(req.Trailer),
144 Body: req.Body,
145 Host: req.Host,
146 ContentLength: req.ContentLength,
147 RemoteAddr: req.RemoteAddr,
148 TLS: req.TLS,
149 MultipartForm: req.MultipartForm,
150 })
151 }
152
153 type http2ResponseWriter struct {
154 *http2.ResponseWriter
155 }
156
157
158 var (
159 _ CloseNotifier = http2ResponseWriter{}
160 _ Flusher = http2ResponseWriter{}
161 _ io.StringWriter = http2ResponseWriter{}
162 )
163
164 func (w http2ResponseWriter) Flush() { w.ResponseWriter.FlushError() }
165 func (w http2ResponseWriter) FlushError() error { return w.ResponseWriter.FlushError() }
166
167 func (w http2ResponseWriter) Header() Header { return Header(w.ResponseWriter.Header()) }
168
169 func (w http2ResponseWriter) Push(target string, opts *PushOptions) error {
170 var (
171 method string
172 header http2.Header
173 )
174 if opts != nil {
175 method = opts.Method
176 header = http2.Header(opts.Header)
177 }
178 err := w.ResponseWriter.Push(target, method, header)
179 if err == http2.ErrNotSupported {
180 err = ErrNotSupported
181 }
182 return err
183 }
184
185 type http2ServerConfig struct {
186 s *Server
187 }
188
189 func (s http2ServerConfig) MaxHeaderBytes() int { return s.s.MaxHeaderBytes }
190 func (s http2ServerConfig) ConnState(c net.Conn, st http2.ConnState) {
191 if s.s.ConnState != nil {
192 s.s.ConnState(c, ConnState(st))
193 }
194 }
195 func (s http2ServerConfig) DoKeepAlives() bool { return s.s.doKeepAlives() }
196 func (s http2ServerConfig) WriteTimeout() time.Duration { return s.s.WriteTimeout }
197 func (s http2ServerConfig) SendPingTimeout() time.Duration { return s.s.ReadTimeout }
198 func (s http2ServerConfig) ErrorLog() *log.Logger { return s.s.ErrorLog }
199 func (s http2ServerConfig) ReadTimeout() time.Duration { return s.s.ReadTimeout }
200 func (s http2ServerConfig) DisableClientPriority() bool { return s.s.DisableClientPriority }
201
202 func (s http2ServerConfig) IdleTimeout() time.Duration {
203 if s.s.h2Config != nil {
204 return s.s.h2Config.IdleTimeout()
205 }
206 return s.s.h2IdleTimeout
207 }
208
209 func (s http2ServerConfig) HTTP2Config() http2.Config {
210 return mergeHTTP2Config(s.s.HTTP2, s.s.h2Config)
211 }
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227 type http2ExternalServerConfig interface {
228
229 HTTP2Config() HTTP2Config
230 IdleTimeout() time.Duration
231
232
233
234 ServeConnFunc(func(ctx context.Context, nc net.Conn, h Handler, sawClientPreface bool, upgradeReq *Request, settings []byte))
235 }
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250 type http2ExternalTransportConfig interface {
251
252 HTTP2Config() HTTP2Config
253 DisableCompression() bool
254 MaxHeaderListSize() int64
255 IdleConnTimeout() time.Duration
256
257
258
259 ConnFromContext(context.Context) net.Conn
260
261
262
263
264 DialFromContext(ctx context.Context, network, addr string) (net.Conn, error)
265
266
267
268
269
270 ExternalRoundTrip() bool
271
272
273
274 RoundTrip(*Request) (*Response, error)
275
276
277 Registered(*Transport)
278 }
279
280 func (t *Transport) configureHTTP2(protocols Protocols) {
281 if t.TLSClientConfig == nil {
282 t.TLSClientConfig = &tls.Config{}
283 }
284 if t.HTTP2 == nil {
285 t.HTTP2 = &HTTP2Config{}
286 }
287 t2 := http2.NewTransport(transportConfig{t})
288 t2.AllowHTTP = true
289 t.h2Transport = t2
290
291 t.registerProtocol("https", http2RoundTripper{t2, true})
292 if t.TLSNextProto == nil {
293 t.TLSNextProto = make(map[string]func(authority string, c *tls.Conn) RoundTripper)
294 }
295
296
297 t.TLSNextProto["h2"] = func(authority string, c *tls.Conn) RoundTripper {
298 return http2ErringRoundTripper{
299 errors.New("unexpected use of stub RoundTripper"),
300 }
301 }
302
303
304
305
306 if limit1 := t.MaxResponseHeaderBytes; limit1 != 0 && t2.MaxHeaderListSize == 0 {
307 const h2max = 1<<32 - 1
308 if limit1 >= h2max {
309 t2.MaxHeaderListSize = h2max
310 } else {
311 t2.MaxHeaderListSize = uint32(limit1)
312 }
313 }
314
315
316
317
318
319
320 t.TLSClientConfig.NextProtos = adjustNextProtos(t.TLSClientConfig.NextProtos, protocols)
321 }
322
323 type http2ErringRoundTripper struct{ err error }
324
325 func (rt http2ErringRoundTripper) RoundTripErr() error { return rt.err }
326 func (rt http2ErringRoundTripper) RoundTrip(*Request) (*Response, error) { return nil, rt.err }
327
328 func http2RoundTrip(req *Request, rt func(*http2.ClientRequest) (*http2.ClientResponse, error)) (*Response, error) {
329 resp := &Response{}
330 cresp, err := rt(&http2.ClientRequest{
331 Context: req.Context(),
332 Method: req.Method,
333 URL: req.URL,
334 Header: http2.Header(req.Header),
335 Trailer: http2.Header(req.Trailer),
336 Body: req.Body,
337 Host: req.Host,
338 GetBody: req.GetBody,
339 ContentLength: req.ContentLength,
340 Cancel: req.Cancel,
341 Close: req.Close,
342 ResTrailer: (*http2.Header)(&resp.Trailer),
343 })
344 if err != nil {
345 return nil, err
346 }
347 resp.Status = cresp.Status + " " + StatusText(cresp.StatusCode)
348 resp.StatusCode = cresp.StatusCode
349 resp.Proto = "HTTP/2.0"
350 resp.ProtoMajor = 2
351 resp.ProtoMinor = 0
352 resp.ContentLength = cresp.ContentLength
353 resp.Uncompressed = cresp.Uncompressed
354 resp.Header = Header(cresp.Header)
355 resp.Trailer = Header(cresp.Trailer)
356 resp.Body = cresp.Body
357 resp.TLS = cresp.TLS
358 resp.Request = req
359 return resp, nil
360 }
361
362
363 func (t *Transport) http2AddConn(scheme, authority string, nc net.Conn) (RoundTripper, error) {
364 if t.h2Transport == nil {
365 return nil, errors.ErrUnsupported
366 }
367 err := t.h2Transport.AddConn(scheme, authority, nc)
368 if err != nil {
369 return nil, err
370 }
371 return http2RoundTripper{t.h2Transport, false}, nil
372 }
373
374
375
376 func (t *Transport) http2NewClientConn(nc net.Conn, internalStateHook func()) (genericClientConn, error) {
377 if t.h2Transport == nil {
378 return nil, errors.ErrUnsupported
379 }
380 cc, err := t.h2Transport.NewClientConn(nc, internalStateHook)
381 if err != nil {
382 return nil, err
383 }
384 return http2ClientConn{cc}, nil
385 }
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400 func (t *Transport) http2NewClientConnFromContext(ctx context.Context) (*ClientConn, error) {
401 if t.h2Config == nil {
402 return nil, errors.ErrUnsupported
403 }
404 nc := t.h2Config.ConnFromContext(ctx)
405 if nc == nil {
406 return nil, errors.ErrUnsupported
407 }
408 if t.h2Transport == nil {
409 return nil, errors.New("http: Transport does not support HTTP/2")
410 }
411 cc := &ClientConn{}
412 gc, err := t.http2NewClientConn(nc, cc.maybeRunStateHook)
413 if err != nil {
414 return nil, err
415 }
416 cc.stateHookMu.Lock()
417 defer cc.stateHookMu.Unlock()
418 cc.cc = gc
419 cc.lastAvailable = gc.Available()
420 return cc, nil
421 }
422
423
424
425
426
427
428
429
430 func (t *Transport) http2ExternalDial(ctx context.Context, cm connectMethod) (RoundTripper, error) {
431 if t.h2Config == nil {
432 return nil, errors.ErrUnsupported
433 }
434 nc, err := t.h2Config.DialFromContext(ctx, "tcp", cm.targetAddr)
435 if err != nil {
436 return nil, err
437 }
438 return t.http2AddConn(cm.targetScheme, cm.targetAddr, nc)
439 }
440
441 type http2RoundTripper struct {
442 t *http2.Transport
443 mapCachedConnErr bool
444 }
445
446 func (rt http2RoundTripper) RoundTrip(req *Request) (*Response, error) {
447 resp, err := http2RoundTrip(req, rt.t.RoundTrip)
448 if err != nil {
449 if rt.mapCachedConnErr && http2isNoCachedConnError(err) {
450 err = ErrSkipAltProtocol
451 }
452 return nil, err
453 }
454 return resp, nil
455 }
456
457 type http2ClientConn struct {
458 http2.NetHTTPClientConn
459 }
460
461 func (cc http2ClientConn) RoundTrip(req *Request) (*Response, error) {
462 return http2RoundTrip(req, cc.NetHTTPClientConn.RoundTrip)
463 }
464
465
466
467
468
469
470 type transportConfig struct {
471 t *Transport
472 }
473
474 func (t transportConfig) MaxResponseHeaderBytes() int64 { return t.t.MaxResponseHeaderBytes }
475 func (t transportConfig) DisableKeepAlives() bool { return t.t.DisableKeepAlives }
476 func (t transportConfig) ExpectContinueTimeout() time.Duration { return t.t.ExpectContinueTimeout }
477 func (t transportConfig) ResponseHeaderTimeout() time.Duration { return t.t.ResponseHeaderTimeout }
478
479 func (t transportConfig) MaxHeaderListSize() int64 {
480 if t.t.h2Config != nil {
481 return t.t.h2Config.MaxHeaderListSize()
482 }
483 return 0
484 }
485
486 func (t transportConfig) DisableCompression() bool {
487 if t.t.h2Config != nil && t.t.h2Config.DisableCompression() {
488 return true
489 }
490 return t.t.DisableCompression
491 }
492
493 func (t transportConfig) IdleConnTimeout() time.Duration {
494
495
496 if t.t.h2Config != nil {
497 if timeout := t.t.h2Config.IdleConnTimeout(); timeout != 0 {
498 return timeout
499 }
500 }
501 return t.t.IdleConnTimeout
502 }
503
504 type http2Configer interface {
505 HTTP2Config() HTTP2Config
506 }
507
508 func mergeHTTP2Config(c1 *HTTP2Config, confer http2Configer) http2.Config {
509 if c1 == nil && confer == nil {
510 return http2.Config{}
511 }
512 var c http2.Config
513 if c1 != nil {
514 c = (http2.Config)(*c1)
515 }
516 var c2 HTTP2Config
517 if confer != nil {
518 c2 = confer.HTTP2Config()
519 }
520 if c.MaxConcurrentStreams == 0 {
521 c.MaxConcurrentStreams = c2.MaxConcurrentStreams
522 }
523 if c2.StrictMaxConcurrentRequests {
524 c.StrictMaxConcurrentRequests = true
525 }
526 if c.MaxDecoderHeaderTableSize == 0 {
527 c.MaxDecoderHeaderTableSize = c2.MaxDecoderHeaderTableSize
528 }
529 if c.MaxEncoderHeaderTableSize == 0 {
530 c.MaxEncoderHeaderTableSize = c2.MaxEncoderHeaderTableSize
531 }
532 if c.MaxReadFrameSize == 0 {
533 c.MaxReadFrameSize = c2.MaxReadFrameSize
534 }
535 if c.MaxReceiveBufferPerConnection == 0 {
536 c.MaxReceiveBufferPerConnection = c2.MaxReceiveBufferPerConnection
537 }
538 if c.MaxReceiveBufferPerStream == 0 {
539 c.MaxReceiveBufferPerStream = c2.MaxReceiveBufferPerStream
540 }
541 if c.SendPingTimeout == 0 {
542 c.SendPingTimeout = c2.SendPingTimeout
543 }
544 if c.PingTimeout == 0 {
545 c.PingTimeout = c2.PingTimeout
546 }
547 if c.WriteByteTimeout == 0 {
548 c.WriteByteTimeout = c2.WriteByteTimeout
549 }
550 if c2.PermitProhibitedCipherSuites {
551 c.PermitProhibitedCipherSuites = true
552 }
553 if c.CountError == nil {
554 c.CountError = c2.CountError
555 }
556 return c
557 }
558
559 func (t transportConfig) HTTP2Config() http2.Config {
560 return mergeHTTP2Config(t.t.HTTP2, t.t.h2Config)
561 }
562
563
564
565
566
567 func transportFromH1Transport(t *Transport) any {
568 t.nextProtoOnce.Do(t.onceSetNextProtoDefaults)
569 return t.h2Transport
570 }
571
View as plain text