1
2
3
4
5 package http2
6
7 import (
8 "math"
9 "time"
10 )
11
12
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
69
70 func adjustHTTP1MaxHeaderSize(n int64) int64 {
71
72
73 const perFieldOverhead = 32
74 const typicalHeaders = 10
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