github.com/aldelo/common@v1.5.1/wrapper/aws/awscustomhttp2.go (about) 1 package aws 2 3 /* 4 * Copyright 2020-2023 Aldelo, LP 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 import ( 20 helper "github.com/aldelo/common" 21 "golang.org/x/net/http2" 22 "net" 23 "net/http" 24 "time" 25 ) 26 27 // HttpClientSettings based on aws documentation 28 type HttpClientSettings struct { 29 // Dialer.KeepAlive: negative value disables keep-alive; 0 enables keep-alive 30 // default = keep-alive enabled 31 ConnKeepAlive *time.Duration 32 33 // Dialer.Timeout: maximum amount of time a dial will wait for a connection to be created 34 // default = 30 seconds 35 Connect *time.Duration 36 37 // Transport.ExpectContinueTimeout: maximum amount of time to wait for a server's first response headers after fully writing the request headers, 38 // if the response has an "Expect: 100-continue" header, 39 // this time does not include the time to send the request header, 40 // the http client sends its payload after this timeout is exhausted 41 // default = 1 second; set to 0 for no timeout and send request payload without waiting 42 ExpectContinue *time.Duration 43 44 // Transport.IdleConnTimeout: maximum amount of time to keep an idle network connection alive between http requests 45 // default = 0 for no limit 46 IdleConn *time.Duration 47 48 // Transport.MaxIdleConns: maximum number of idle (keep-alive) connections across all hosts, 49 // use case: increasing this value when many connections in a short period from same clients 50 // default = 0 means no limit 51 MaxAllIdleConns *int 52 53 // Transport.MaxIdleConnsPerHost: maximum number of idle (keep-alive) connections to keep per-host, 54 // use case: increasing this value when many connections in a short period from same clients 55 // default = 0 means 2 idle connections per host 56 MaxHostIdleConns *int 57 58 // Transport.ResponseHeaderTimeout: maximum amount of time to wait for a client to read the response header, 59 // if the client isn't able to read the response's header within this duration, the request fails with a timeout error, 60 // warning: when using long-running lambda functions, as the operation does not return any response headers until the lambda has finished or timeout 61 // default = no timeout, waits forever 62 ResponseHeader *time.Duration 63 64 // Transport.TLSHandshakeTimeout: maximum amount of time waiting for a TLS handshake to be completed 65 // default = 10 seconds; 0 means no timeout 66 TlsHandshake *time.Duration 67 } 68 69 // AwsHttp2Client struct defines container for HttpClientSettings 70 type AwsHttp2Client struct { 71 Options *HttpClientSettings 72 } 73 74 func (h2 *AwsHttp2Client) setDefaults() { 75 if h2.Options == nil { 76 h2.Options = new(HttpClientSettings) 77 } 78 79 if h2.Options.ConnKeepAlive == nil { 80 h2.Options.ConnKeepAlive = helper.DurationPtr(0) 81 } 82 83 if h2.Options.Connect == nil { 84 h2.Options.Connect = helper.DurationPtr(5 * time.Second) 85 } 86 87 if h2.Options.ExpectContinue == nil { 88 h2.Options.ExpectContinue = helper.DurationPtr(1 * time.Second) 89 } 90 91 if h2.Options.IdleConn == nil { 92 h2.Options.IdleConn = helper.DurationPtr(300 * time.Second) 93 } 94 95 if h2.Options.MaxAllIdleConns == nil { 96 h2.Options.MaxAllIdleConns = helper.IntPtr(0) 97 } 98 99 if h2.Options.MaxHostIdleConns == nil { 100 h2.Options.MaxHostIdleConns = helper.IntPtr(100) 101 } 102 103 if h2.Options.ResponseHeader == nil { 104 h2.Options.ResponseHeader = helper.DurationPtr(5 * time.Second) 105 } 106 107 if h2.Options.TlsHandshake == nil { 108 h2.Options.TlsHandshake = helper.DurationPtr(5 * time.Second) 109 } 110 } 111 112 // ConnKeepAlive sets Dialer.KeepAlive: negative value disables keep-alive; 0 enables keep-alive 113 // default = keep-alive enabled 114 func (h2 *AwsHttp2Client) ConnKeepAlive(v time.Duration) { 115 h2.Options.ConnKeepAlive = &v 116 } 117 118 // ConnectTimeout sets Dialer.Timeout: maximum amount of time a dial will wait for a connection to be created 119 // default = 30 seconds 120 func (h2 *AwsHttp2Client) ConnectTimeout(v time.Duration) { 121 h2.Options.Connect = &v 122 } 123 124 // ExpectContinueTimeout sets Transport.ExpectContinueTimeout: maximum amount of time to wait for a server's first response headers after fully writing the request headers, 125 // 126 // if the response has an "Expect: 100-continue" header, 127 // this time does not include the time to send the request header, 128 // the http client sends its payload after this timeout is exhausted 129 // 130 // default = 1 second; set to 0 for no timeout and send request payload without waiting 131 func (h2 *AwsHttp2Client) ExpectContinueTimeout(v time.Duration) { 132 h2.Options.ExpectContinue = &v 133 } 134 135 // IdleConnTimeout sets Transport.IdleConnTimeout: maximum amount of time to keep an idle network connection alive between http requests 136 // default = 0 for no limit 137 func (h2 *AwsHttp2Client) IdleConnTimeout(v time.Duration) { 138 h2.Options.IdleConn = &v 139 } 140 141 // MaxAllIdleConns sets Transport.MaxIdleConns: maximum number of idle (keep-alive) connections across all hosts, 142 // 143 // use case: increasing this value when many connections in a short period from same clients 144 // 145 // default = 0 means no limit 146 func (h2 *AwsHttp2Client) MaxAllIdleConns(v int) { 147 h2.Options.MaxAllIdleConns = &v 148 } 149 150 // MaxHostIdleConns sets Transport.MaxIdleConnsPerHost: maximum number of idle (keep-alive) connections to keep per-host, 151 // 152 // use case: increasing this value when many connections in a short period from same clients 153 // 154 // default = 0 means 2 idle connections per host 155 func (h2 *AwsHttp2Client) MaxHostIdleConns(v int) { 156 h2.Options.MaxHostIdleConns = &v 157 } 158 159 // ResponseHeaderTimeout sets Transport.ResponseHeaderTimeout: maximum amount of time to wait for a client to read the response header, 160 // 161 // if the client isn't able to read the response's header within this duration, the request fails with a timeout error, 162 // warning: when using long-running lambda functions, as the operation does not return any response headers until the lambda has finished or timeout 163 // 164 // default = no timeout, waits forever 165 func (h2 *AwsHttp2Client) ResponseHeaderTimeout(v time.Duration) { 166 h2.Options.ResponseHeader = &v 167 } 168 169 // TlsHandshakeTimeout sets Transport.TLSHandshakeTimeout: maximum amount of time waiting for a TLS handshake to be completed 170 // default = 10 seconds; 0 means no timeout 171 func (h2 *AwsHttp2Client) TlsHandshakeTimeout(v time.Duration) { 172 h2.Options.TlsHandshake = &v 173 } 174 175 // NewHttp2Client returns custom http2 client for aws connection 176 func (h2 *AwsHttp2Client) NewHttp2Client() (*http.Client, error) { 177 h2.setDefaults() 178 179 var client http.Client 180 181 tr := &http.Transport{ 182 ResponseHeaderTimeout: *h2.Options.ResponseHeader, 183 Proxy: http.ProxyFromEnvironment, 184 DialContext: (&net.Dialer{ 185 KeepAlive: *h2.Options.ConnKeepAlive, 186 Timeout: *h2.Options.Connect, 187 }).DialContext, 188 MaxIdleConns: *h2.Options.MaxAllIdleConns, 189 IdleConnTimeout: *h2.Options.IdleConn, 190 TLSHandshakeTimeout: *h2.Options.TlsHandshake, 191 MaxIdleConnsPerHost: *h2.Options.MaxHostIdleConns, 192 ExpectContinueTimeout: *h2.Options.ExpectContinue, 193 } 194 195 // client makes HTTP/2 requests 196 err := http2.ConfigureTransport(tr) 197 198 if err != nil { 199 return &client, err 200 } 201 202 return &http.Client{ 203 Transport: tr, 204 }, nil 205 }