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