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, h2 *Server) Config {
29 conf := Config{
30 MaxConcurrentStreams: int(h2.MaxConcurrentStreams),
31 MaxEncoderHeaderTableSize: int(h2.MaxEncoderHeaderTableSize),
32 MaxDecoderHeaderTableSize: int(h2.MaxDecoderHeaderTableSize),
33 MaxReadFrameSize: int(h2.MaxReadFrameSize),
34 MaxReceiveBufferPerConnection: int(h2.MaxUploadBufferPerConnection),
35 MaxReceiveBufferPerStream: int(h2.MaxUploadBufferPerStream),
36 SendPingTimeout: h2.ReadIdleTimeout,
37 PingTimeout: h2.PingTimeout,
38 WriteByteTimeout: h2.WriteByteTimeout,
39 PermitProhibitedCipherSuites: h2.PermitProhibitedCipherSuites,
40 CountError: h2.CountError,
41 }
42 fillNetHTTPConfig(&conf, h1.HTTP2Config())
43 setConfigDefaults(&conf, true)
44 return conf
45 }
46
47 func configFromTransport(h2 *Transport) Config {
48 conf := Config{
49 MaxEncoderHeaderTableSize: int(h2.MaxEncoderHeaderTableSize),
50 MaxDecoderHeaderTableSize: int(h2.MaxDecoderHeaderTableSize),
51 MaxReadFrameSize: int(h2.MaxReadFrameSize),
52 SendPingTimeout: h2.ReadIdleTimeout,
53 PingTimeout: h2.PingTimeout,
54 WriteByteTimeout: h2.WriteByteTimeout,
55 }
56
57
58
59 if conf.MaxReadFrameSize < minMaxFrameSize {
60 conf.MaxReadFrameSize = minMaxFrameSize
61 } else if conf.MaxReadFrameSize > maxFrameSize {
62 conf.MaxReadFrameSize = maxFrameSize
63 }
64
65 if h2.t1 != nil {
66 fillNetHTTPConfig(&conf, h2.t1.HTTP2Config())
67 }
68
69 setConfigDefaults(&conf, false)
70 return conf
71 }
72
73 func setDefault[T ~int | ~int32 | ~uint32 | ~int64](v *T, minval, maxval, defval T) {
74 if *v < minval || *v > maxval {
75 *v = defval
76 }
77 }
78
79 func setConfigDefaults(conf *Config, server bool) {
80 setDefault(&conf.MaxConcurrentStreams, 1, math.MaxInt32, defaultMaxStreams)
81 setDefault(&conf.MaxEncoderHeaderTableSize, 1, math.MaxInt32, initialHeaderTableSize)
82 setDefault(&conf.MaxDecoderHeaderTableSize, 1, math.MaxInt32, initialHeaderTableSize)
83 if server {
84 setDefault(&conf.MaxReceiveBufferPerConnection, initialWindowSize, math.MaxInt32, 1<<20)
85 } else {
86 setDefault(&conf.MaxReceiveBufferPerConnection, initialWindowSize, math.MaxInt32, transportDefaultConnFlow)
87 }
88 if server {
89 setDefault(&conf.MaxReceiveBufferPerStream, 1, math.MaxInt32, 1<<20)
90 } else {
91 setDefault(&conf.MaxReceiveBufferPerStream, 1, math.MaxInt32, transportDefaultStreamFlow)
92 }
93 setDefault(&conf.MaxReadFrameSize, minMaxFrameSize, maxFrameSize, defaultMaxReadFrameSize)
94 setDefault(&conf.PingTimeout, 1, math.MaxInt64, 15*time.Second)
95 }
96
97
98
99 func adjustHTTP1MaxHeaderSize(n int64) int64 {
100
101
102 const perFieldOverhead = 32
103 const typicalHeaders = 10
104 return n + typicalHeaders*perFieldOverhead
105 }
106
107 func fillNetHTTPConfig(conf *Config, h2 Config) {
108 if h2.MaxConcurrentStreams != 0 {
109 conf.MaxConcurrentStreams = h2.MaxConcurrentStreams
110 }
111 if h2.StrictMaxConcurrentRequests {
112 conf.StrictMaxConcurrentRequests = true
113 }
114 if h2.MaxEncoderHeaderTableSize != 0 {
115 conf.MaxEncoderHeaderTableSize = h2.MaxEncoderHeaderTableSize
116 }
117 if h2.MaxDecoderHeaderTableSize != 0 {
118 conf.MaxDecoderHeaderTableSize = h2.MaxDecoderHeaderTableSize
119 }
120 if h2.MaxConcurrentStreams != 0 {
121 conf.MaxConcurrentStreams = h2.MaxConcurrentStreams
122 }
123 if h2.MaxReadFrameSize != 0 {
124 conf.MaxReadFrameSize = h2.MaxReadFrameSize
125 }
126 if h2.MaxReceiveBufferPerConnection != 0 {
127 conf.MaxReceiveBufferPerConnection = h2.MaxReceiveBufferPerConnection
128 }
129 if h2.MaxReceiveBufferPerStream != 0 {
130 conf.MaxReceiveBufferPerStream = h2.MaxReceiveBufferPerStream
131 }
132 if h2.SendPingTimeout != 0 {
133 conf.SendPingTimeout = h2.SendPingTimeout
134 }
135 if h2.PingTimeout != 0 {
136 conf.PingTimeout = h2.PingTimeout
137 }
138 if h2.WriteByteTimeout != 0 {
139 conf.WriteByteTimeout = h2.WriteByteTimeout
140 }
141 if h2.PermitProhibitedCipherSuites {
142 conf.PermitProhibitedCipherSuites = true
143 }
144 if h2.CountError != nil {
145 conf.CountError = h2.CountError
146 }
147 }
148
View as plain text