Source file src/net/http/internal/http2/config.go

     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  	"time"
    10  )
    11  
    12  // Config must be kept in sync with net/http.HTTP2Config.
    13  type Config struct {
    14  	MaxConcurrentStreams          int
    15  	StrictMaxConcurrentRequests   bool
    16  	MaxDecoderHeaderTableSize     int
    17  	MaxEncoderHeaderTableSize     int
    18  	MaxReadFrameSize              int
    19  	MaxReceiveBufferPerConnection int
    20  	MaxReceiveBufferPerStream     int
    21  	SendPingTimeout               time.Duration
    22  	PingTimeout                   time.Duration
    23  	WriteByteTimeout              time.Duration
    24  	PermitProhibitedCipherSuites  bool
    25  	CountError                    func(errType string)
    26  }
    27  
    28  func configFromServer(h1 ServerConfig) Config {
    29  	conf := Config{}
    30  	fillNetHTTPConfig(&conf, h1.HTTP2Config())
    31  	setConfigDefaults(&conf, true)
    32  	return conf
    33  }
    34  
    35  func configFromTransport(h2 *Transport) Config {
    36  	conf := Config{}
    37  	if h2.t1 != nil {
    38  		fillNetHTTPConfig(&conf, h2.t1.HTTP2Config())
    39  	}
    40  	setConfigDefaults(&conf, false)
    41  	return conf
    42  }
    43  
    44  func setDefault[T ~int | ~int32 | ~uint32 | ~int64](v *T, minval, maxval, defval T) {
    45  	if *v < minval || *v > maxval {
    46  		*v = defval
    47  	}
    48  }
    49  
    50  func setConfigDefaults(conf *Config, server bool) {
    51  	setDefault(&conf.MaxConcurrentStreams, 1, math.MaxInt32, defaultMaxStreams)
    52  	setDefault(&conf.MaxEncoderHeaderTableSize, 1, math.MaxInt32, initialHeaderTableSize)
    53  	setDefault(&conf.MaxDecoderHeaderTableSize, 1, math.MaxInt32, initialHeaderTableSize)
    54  	if server {
    55  		setDefault(&conf.MaxReceiveBufferPerConnection, initialWindowSize, math.MaxInt32, 1<<20)
    56  	} else {
    57  		setDefault(&conf.MaxReceiveBufferPerConnection, initialWindowSize, math.MaxInt32, transportDefaultConnFlow)
    58  	}
    59  	if server {
    60  		setDefault(&conf.MaxReceiveBufferPerStream, 1, math.MaxInt32, 1<<20)
    61  	} else {
    62  		setDefault(&conf.MaxReceiveBufferPerStream, 1, math.MaxInt32, transportDefaultStreamFlow)
    63  	}
    64  	setDefault(&conf.MaxReadFrameSize, minMaxFrameSize, maxFrameSize, defaultMaxReadFrameSize)
    65  	setDefault(&conf.PingTimeout, 1, math.MaxInt64, 15*time.Second)
    66  }
    67  
    68  // adjustHTTP1MaxHeaderSize converts a limit in bytes on the size of an HTTP/1 header
    69  // to an HTTP/2 MAX_HEADER_LIST_SIZE value.
    70  func adjustHTTP1MaxHeaderSize(n int64) int64 {
    71  	// http2's count is in a slightly different unit and includes 32 bytes per pair.
    72  	// So, take the net/http.Server value and pad it up a bit, assuming 10 headers.
    73  	const perFieldOverhead = 32 // per http2 spec
    74  	const typicalHeaders = 10   // conservative
    75  	return n + typicalHeaders*perFieldOverhead
    76  }
    77  
    78  func fillNetHTTPConfig(conf *Config, h2 Config) {
    79  	if h2.MaxConcurrentStreams != 0 {
    80  		conf.MaxConcurrentStreams = h2.MaxConcurrentStreams
    81  	}
    82  	if h2.StrictMaxConcurrentRequests {
    83  		conf.StrictMaxConcurrentRequests = true
    84  	}
    85  	if h2.MaxEncoderHeaderTableSize != 0 {
    86  		conf.MaxEncoderHeaderTableSize = h2.MaxEncoderHeaderTableSize
    87  	}
    88  	if h2.MaxDecoderHeaderTableSize != 0 {
    89  		conf.MaxDecoderHeaderTableSize = h2.MaxDecoderHeaderTableSize
    90  	}
    91  	if h2.MaxConcurrentStreams != 0 {
    92  		conf.MaxConcurrentStreams = h2.MaxConcurrentStreams
    93  	}
    94  	if h2.MaxReadFrameSize != 0 {
    95  		conf.MaxReadFrameSize = h2.MaxReadFrameSize
    96  	}
    97  	if h2.MaxReceiveBufferPerConnection != 0 {
    98  		conf.MaxReceiveBufferPerConnection = h2.MaxReceiveBufferPerConnection
    99  	}
   100  	if h2.MaxReceiveBufferPerStream != 0 {
   101  		conf.MaxReceiveBufferPerStream = h2.MaxReceiveBufferPerStream
   102  	}
   103  	if h2.SendPingTimeout != 0 {
   104  		conf.SendPingTimeout = h2.SendPingTimeout
   105  	}
   106  	if h2.PingTimeout != 0 {
   107  		conf.PingTimeout = h2.PingTimeout
   108  	}
   109  	if h2.WriteByteTimeout != 0 {
   110  		conf.WriteByteTimeout = h2.WriteByteTimeout
   111  	}
   112  	if h2.PermitProhibitedCipherSuites {
   113  		conf.PermitProhibitedCipherSuites = true
   114  	}
   115  	if h2.CountError != nil {
   116  		conf.CountError = h2.CountError
   117  	}
   118  }
   119  

View as plain text