...

Source file src/golang.org/x/net/http2/config.go

Documentation: golang.org/x/net/http2

     1  // Copyright 2024 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package http2
     6  
     7  import (
     8  	"math"
     9  	"net/http"
    10  	"time"
    11  )
    12  
    13  // http2Config is a package-internal version of net/http.HTTP2Config.
    14  //
    15  // http.HTTP2Config was added in Go 1.24.
    16  // When running with a version of net/http that includes HTTP2Config,
    17  // we merge the configuration with the fields in Transport or Server
    18  // to produce an http2Config.
    19  //
    20  // Zero valued fields in http2Config are interpreted as in the
    21  // net/http.HTTPConfig documentation.
    22  //
    23  // Precedence order for reconciling configurations is:
    24  //
    25  //   - Use the net/http.{Server,Transport}.HTTP2Config value, when non-zero.
    26  //   - Otherwise use the http2.{Server.Transport} value.
    27  //   - If the resulting value is zero or out of range, use a default.
    28  type http2Config struct {
    29  	MaxConcurrentStreams         uint32
    30  	MaxDecoderHeaderTableSize    uint32
    31  	MaxEncoderHeaderTableSize    uint32
    32  	MaxReadFrameSize             uint32
    33  	MaxUploadBufferPerConnection int32
    34  	MaxUploadBufferPerStream     int32
    35  	SendPingTimeout              time.Duration
    36  	PingTimeout                  time.Duration
    37  	WriteByteTimeout             time.Duration
    38  	PermitProhibitedCipherSuites bool
    39  	CountError                   func(errType string)
    40  }
    41  
    42  // configFromServer merges configuration settings from
    43  // net/http.Server.HTTP2Config and http2.Server.
    44  func configFromServer(h1 *http.Server, h2 *Server) http2Config {
    45  	conf := http2Config{
    46  		MaxConcurrentStreams:         h2.MaxConcurrentStreams,
    47  		MaxEncoderHeaderTableSize:    h2.MaxEncoderHeaderTableSize,
    48  		MaxDecoderHeaderTableSize:    h2.MaxDecoderHeaderTableSize,
    49  		MaxReadFrameSize:             h2.MaxReadFrameSize,
    50  		MaxUploadBufferPerConnection: h2.MaxUploadBufferPerConnection,
    51  		MaxUploadBufferPerStream:     h2.MaxUploadBufferPerStream,
    52  		SendPingTimeout:              h2.ReadIdleTimeout,
    53  		PingTimeout:                  h2.PingTimeout,
    54  		WriteByteTimeout:             h2.WriteByteTimeout,
    55  		PermitProhibitedCipherSuites: h2.PermitProhibitedCipherSuites,
    56  		CountError:                   h2.CountError,
    57  	}
    58  	fillNetHTTPServerConfig(&conf, h1)
    59  	setConfigDefaults(&conf, true)
    60  	return conf
    61  }
    62  
    63  // configFromServer merges configuration settings from h2 and h2.t1.HTTP2
    64  // (the net/http Transport).
    65  func configFromTransport(h2 *Transport) http2Config {
    66  	conf := http2Config{
    67  		MaxEncoderHeaderTableSize: h2.MaxEncoderHeaderTableSize,
    68  		MaxDecoderHeaderTableSize: h2.MaxDecoderHeaderTableSize,
    69  		MaxReadFrameSize:          h2.MaxReadFrameSize,
    70  		SendPingTimeout:           h2.ReadIdleTimeout,
    71  		PingTimeout:               h2.PingTimeout,
    72  		WriteByteTimeout:          h2.WriteByteTimeout,
    73  	}
    74  
    75  	// Unlike most config fields, where out-of-range values revert to the default,
    76  	// Transport.MaxReadFrameSize clips.
    77  	if conf.MaxReadFrameSize < minMaxFrameSize {
    78  		conf.MaxReadFrameSize = minMaxFrameSize
    79  	} else if conf.MaxReadFrameSize > maxFrameSize {
    80  		conf.MaxReadFrameSize = maxFrameSize
    81  	}
    82  
    83  	if h2.t1 != nil {
    84  		fillNetHTTPTransportConfig(&conf, h2.t1)
    85  	}
    86  	setConfigDefaults(&conf, false)
    87  	return conf
    88  }
    89  
    90  func setDefault[T ~int | ~int32 | ~uint32 | ~int64](v *T, minval, maxval, defval T) {
    91  	if *v < minval || *v > maxval {
    92  		*v = defval
    93  	}
    94  }
    95  
    96  func setConfigDefaults(conf *http2Config, server bool) {
    97  	setDefault(&conf.MaxConcurrentStreams, 1, math.MaxUint32, defaultMaxStreams)
    98  	setDefault(&conf.MaxEncoderHeaderTableSize, 1, math.MaxUint32, initialHeaderTableSize)
    99  	setDefault(&conf.MaxDecoderHeaderTableSize, 1, math.MaxUint32, initialHeaderTableSize)
   100  	if server {
   101  		setDefault(&conf.MaxUploadBufferPerConnection, initialWindowSize, math.MaxInt32, 1<<20)
   102  	} else {
   103  		setDefault(&conf.MaxUploadBufferPerConnection, initialWindowSize, math.MaxInt32, transportDefaultConnFlow)
   104  	}
   105  	if server {
   106  		setDefault(&conf.MaxUploadBufferPerStream, 1, math.MaxInt32, 1<<20)
   107  	} else {
   108  		setDefault(&conf.MaxUploadBufferPerStream, 1, math.MaxInt32, transportDefaultStreamFlow)
   109  	}
   110  	setDefault(&conf.MaxReadFrameSize, minMaxFrameSize, maxFrameSize, defaultMaxReadFrameSize)
   111  	setDefault(&conf.PingTimeout, 1, math.MaxInt64, 15*time.Second)
   112  }
   113  
   114  // adjustHTTP1MaxHeaderSize converts a limit in bytes on the size of an HTTP/1 header
   115  // to an HTTP/2 MAX_HEADER_LIST_SIZE value.
   116  func adjustHTTP1MaxHeaderSize(n int64) int64 {
   117  	// http2's count is in a slightly different unit and includes 32 bytes per pair.
   118  	// So, take the net/http.Server value and pad it up a bit, assuming 10 headers.
   119  	const perFieldOverhead = 32 // per http2 spec
   120  	const typicalHeaders = 10   // conservative
   121  	return n + typicalHeaders*perFieldOverhead
   122  }
   123  

View as plain text