github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/net/http/transport.go (about) 1 // Copyright 2011 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 // HTTP client implementation. See RFC 7230 through 7235. 6 // 7 // This is the low-level Transport implementation of RoundTripper. 8 // The high-level interface is in client.go. 9 10 package http 11 12 import ( 13 "github.com/shogo82148/std/context" 14 "github.com/shogo82148/std/crypto/tls" 15 "github.com/shogo82148/std/errors" 16 "github.com/shogo82148/std/io" 17 "github.com/shogo82148/std/net" 18 "github.com/shogo82148/std/net/url" 19 "github.com/shogo82148/std/sync" 20 "github.com/shogo82148/std/sync/atomic" 21 "github.com/shogo82148/std/time" 22 ) 23 24 // DefaultTransportは [Transport] のデフォルト実装であり、[DefaultClient] によって使用されます。 25 // 必要に応じてネットワーク接続を確立し、後続の呼び出しで再利用するためにキャッシュします。 26 // 環境変数HTTP_PROXY、HTTPS_PROXY、およびNO_PROXY(またはその小文字バージョン)によって指示されたように、HTTPプロキシを使用します。 27 var DefaultTransport RoundTripper = &Transport{ 28 Proxy: ProxyFromEnvironment, 29 DialContext: defaultTransportDialContext(&net.Dialer{ 30 Timeout: 30 * time.Second, 31 KeepAlive: 30 * time.Second, 32 }), 33 ForceAttemptHTTP2: true, 34 MaxIdleConns: 100, 35 IdleConnTimeout: 90 * time.Second, 36 TLSHandshakeTimeout: 10 * time.Second, 37 ExpectContinueTimeout: 1 * time.Second, 38 } 39 40 // DefaultMaxIdleConnsPerHostは、[Transport] のMaxIdleConnsPerHostのデフォルト値です。 41 const DefaultMaxIdleConnsPerHost = 2 42 43 // Transportは、HTTP、HTTPS、およびHTTPプロキシ(HTTPまたはHTTPS with CONNECTのいずれか)をサポートする [RoundTripper] の実装です。 44 // 45 // デフォルトでは、Transportは将来の再利用のために接続をキャッシュします。 46 // これにより、多くのホストにアクセスする場合に多数のオープンな接続が残る可能性があります。 47 // この動作は、[Transport.CloseIdleConnections] メソッドと [Transport.MaxIdleConnsPerHost] および [Transport.DisableKeepAlives] フィールドを使用して管理できます。 48 // 49 // Transportは必要に応じて作成するのではなく、再利用する必要があります。 50 // Transportは、複数のgoroutineによる同時使用に対して安全です。 51 // 52 // Transportは、HTTPおよびHTTPSリクエストを行うための低レベルのプリミティブです。 53 // クッキーやリダイレクトなどの高レベルの機能については、[Client] を参照してください。 54 // 55 // Transportは、HTTP URLではHTTP/1.1を、HTTPS URLではHTTP/1.1またはHTTP/2を使用します。 56 // これは、サーバーがHTTP/2をサポートしているかどうか、およびTransportの構成によって異なります。 57 // [DefaultTransport] はHTTP/2をサポートしています。 58 // Transportで明示的にHTTP/2を有効にするには、golang.org/x/net/http2 を使用してConfigureTransportを呼び出します。 59 // HTTP/2についての詳細については、パッケージのドキュメントを参照してください。 60 // 61 // ステータスコードが1xx範囲にあるレスポンスは、自動的に処理されます(100 expect-continue)。 62 // ただし、HTTPステータスコード101(Switching Protocols)は、終端ステータスと見なされ、[Transport.RoundTrip] によって返されます。 63 // 無視された1xxレスポンスを表示するには、httptraceトレースパッケージのClientTrace.Got1xxResponseを使用します。 64 // 65 // Transportは、ネットワークエラーに遭遇した場合にのみ、接続がすでに正常に使用されており、 66 // リクエストが冪等であり、ボディがないか、または [Request.GetBody] が定義されている場合に、 67 // リクエストを再試行します。HTTPリクエストは、HTTPメソッドがGET、HEAD、OPTIONS、またはTRACEである場合、 68 // または [Header] マップに「Idempotency-Key」または「X-Idempotency-Key」エントリが含まれている場合、冪等と見なされます。 69 // 冪等性キーの値がゼロ長のスライスの場合、リクエストは冪等と見なされますが、ヘッダーはワイヤーに送信されません。 70 type Transport struct { 71 idleMu sync.Mutex 72 closeIdle bool 73 idleConn map[connectMethodKey][]*persistConn 74 idleConnWait map[connectMethodKey]wantConnQueue 75 idleLRU connLRU 76 77 reqMu sync.Mutex 78 reqCanceler map[cancelKey]func(error) 79 80 altMu sync.Mutex 81 altProto atomic.Value 82 83 connsPerHostMu sync.Mutex 84 connsPerHost map[connectMethodKey]int 85 connsPerHostWait map[connectMethodKey]wantConnQueue 86 87 // Proxyは、指定されたRequestに対するプロキシを返す関数を指定します。 88 // 関数が非nilのエラーを返す場合、リクエストは提供されたエラーで中止されます。 89 // 90 // プロキシのタイプは、URLスキームによって決定されます。 91 // "http"、"https"、"sock5"、および"socks5h"がサポートされています。 92 // スキームが空の場合、"http"が想定されます。 93 // "socks5"は"socks5h"と同じように扱われます。 94 // 95 // プロキシURLにuserinfoサブコンポーネントが含まれている場合、 96 // プロキシリクエストはProxy-Authorizationヘッダーでユーザー名とパスワードを渡します。 97 // 98 // Proxyがnilまたはnilの*URLを返す場合、プロキシは使用されません。 99 Proxy func(*Request) (*url.URL, error) 100 101 // OnProxyConnectResponseは、TransportがCONNECTリクエストのプロキシからHTTPレスポンスを受信したときに呼び出されます。 102 // これは、200 OKレスポンスのチェックの前に呼び出されます。 103 // エラーを返すと、リクエストはそのエラーで失敗します。 104 OnProxyConnectResponse func(ctx context.Context, proxyURL *url.URL, connectReq *Request, connectRes *Response) error 105 106 // DialContextは、暗号化されていないTCP接続を作成するためのダイアル関数を指定します。 107 // DialContextがnilである場合(および下記の非推奨のDialもnilである場合)、 108 // トランスポートはnetパッケージを使用してダイアルします。 109 // 110 // DialContextは、RoundTripの呼び出しと並行して実行されます。 111 // ダイアルを開始するRoundTrip呼び出しが、後のDialContextが完了する前に 112 // 以前にダイアルされた接続を使用する場合があります。 113 DialContext func(ctx context.Context, network, addr string) (net.Conn, error) 114 115 // Dialは、暗号化されていないTCP接続を作成するためのダイアル関数を指定します。 116 // 117 // Dialは、RoundTripの呼び出しと並行して実行されます。 118 // 以前にダイアルされた接続が後でアイドル状態になる場合、 119 // 後のDialが完了する前に、ダイアルを開始するRoundTrip呼び出しが以前にダイアルされた接続を使用する場合があります。 120 // 121 // Deprecated: 代わりにDialContextを使用してください。これにより、トランスポートはダイアルが不要になった直後にキャンセルできます。 122 // 両方が設定されている場合、DialContextが優先されます。 123 Dial func(network, addr string) (net.Conn, error) 124 125 // DialTLSContextは、プロキシを使用しないHTTPSリクエストのためのTLS接続を作成するためのオプションのダイアル関数を指定します。 126 // 127 // DialTLSContextがnilである場合(および下記の非推奨のDialTLSもnilである場合)、 128 // DialContextとTLSClientConfigが使用されます。 129 // 130 // DialTLSContextが設定されている場合、HTTPSリクエストに対してDialおよびDialContextフックは使用されず、 131 // TLSClientConfigおよびTLSHandshakeTimeoutは無視されます。 132 // 返されたnet.Connは、すでにTLSハンドシェイクを完了しているものと見なされます。 133 DialTLSContext func(ctx context.Context, network, addr string) (net.Conn, error) 134 135 // DialTLSは、プロキシを使用しないHTTPSリクエストのためのTLS接続を作成するためのオプションのダイアル関数を指定します。 136 // 137 // Deprecated: 代わりにDialTLSContextを使用してください。これにより、トランスポートはダイアルが不要になった直後にキャンセルできます。 138 // 両方が設定されている場合、DialTLSContextが優先されます。 139 DialTLS func(network, addr string) (net.Conn, error) 140 141 // TLSClientConfigは、tls.Clientで使用するTLS構成を指定します。 142 // nilの場合、デフォルトの構成が使用されます。 143 // nil以外の場合、HTTP/2サポートがデフォルトで有効になっていない場合があります。 144 TLSClientConfig *tls.Config 145 146 // TLSHandshakeTimeoutは、TLSハンドシェイクを待機する最大時間を指定します。 147 // ゼロの場合、タイムアウトはありません。 148 TLSHandshakeTimeout time.Duration 149 150 // DisableKeepAlivesがtrueの場合、HTTP keep-alivesが無効になり、 151 // サーバーへの接続は単一のHTTPリクエストにのみ使用されます。 152 // 153 // これは、同様に名前が付けられたTCP keep-alivesとは無関係です。 154 DisableKeepAlives bool 155 156 // DisableCompressionがtrueの場合、Transportは、Requestに既存のAccept-Encoding値がない場合に、 157 // "Accept-Encoding: gzip"リクエストヘッダーで圧縮を要求しません。 158 // Transportが自動的にgzipを要求し、gzipされたレスポンスを受け取った場合、Response.Bodyで透過的にデコードされます。 159 // ただし、ユーザーが明示的にgzipを要求した場合は、自動的に解凍されません。 160 DisableCompression bool 161 162 // MaxIdleConnsは、すべてのホストをまたいでアイドル(keep-alive)接続の最大数を制御します。 163 // ゼロの場合、制限はありません。 164 MaxIdleConns int 165 166 // MaxIdleConnsPerHostがゼロでない場合、ホストごとに保持する最大アイドル(keep-alive)接続数を制御します。 167 // ゼロの場合、DefaultMaxIdleConnsPerHostが使用されます。 168 MaxIdleConnsPerHost int 169 170 // MaxConnsPerHostは、ダイアル、アクティブ、およびアイドル状態の接続を含む、ホストごとの総接続数をオプションで制限します。 171 // 制限を超えると、ダイアルはブロックされます。 172 // 173 // ゼロは制限がないことを意味します。 174 MaxConnsPerHost int 175 176 // IdleConnTimeoutは、アイドル(keep-alive)接続が自己クローズする前にアイドル状態になる最大時間です。 177 // ゼロは制限がないことを意味します。 178 IdleConnTimeout time.Duration 179 180 // ResponseHeaderTimeoutがゼロでない場合、リクエスト(ボディがある場合はそれも含む)を完全に書き込んだ後、 181 // サーバーのレスポンスヘッダーを待機する時間を指定します。 182 // この時間には、レスポンスボディを読み取る時間は含まれません。 183 ResponseHeaderTimeout time.Duration 184 185 // ExpectContinueTimeoutがゼロでない場合、リクエストに"Expect: 100-continue"ヘッダーがある場合、 186 // リクエストヘッダーを完全に書き込んだ後、サーバーの最初のレスポンスヘッダーを待機する時間を指定します。 187 // ゼロはタイムアウトがないことを意味し、サーバーの承認を待たずに、すぐにボディを送信します。 188 // この時間には、リクエストヘッダーを送信する時間は含まれません。 189 ExpectContinueTimeout time.Duration 190 191 // TLSNextProtoは、TLS ALPNプロトコルネゴシエーション後にTransportが代替プロトコル(HTTP/2など)に切り替える方法を指定します。 192 // Transportがプロトコル名が空でないTLS接続をダイアルし、TLSNextProtoにそのキーのマップエントリが含まれている場合("h2"など)、 193 // リクエストの権限("example.com"または"example.com:1234"など)とTLS接続でfuncが呼び出されます。 194 // この関数は、その後リクエストを処理するRoundTripperを返さなければなりません。 195 // TLSNextProtoがnilでない場合、HTTP/2サポートは自動的に有効になりません。 196 TLSNextProto map[string]func(authority string, c *tls.Conn) RoundTripper 197 198 // ProxyConnectHeaderは、CONNECTリクエスト中にプロキシに送信するヘッダーをオプションで指定します。 199 // ヘッダーを動的に設定するには、GetProxyConnectHeaderを参照してください。 200 ProxyConnectHeader Header 201 202 // GetProxyConnectHeaderは、ip:portターゲットへのCONNECTリクエスト中にproxyURLに送信するヘッダーを返すためのオプションの関数を指定します。 203 // エラーを返すと、TransportのRoundTripはそのエラーで失敗します。 204 // ヘッダーを追加しない場合は、(nil, nil)を返すことができます。 205 // GetProxyConnectHeaderが非nilの場合、ProxyConnectHeaderは無視されます。 206 GetProxyConnectHeader func(ctx context.Context, proxyURL *url.URL, target string) (Header, error) 207 208 // MaxResponseHeaderBytesは、サーバーのレスポンスヘッダーに許可されるレスポンスバイト数の制限を指定します。 209 // 210 // ゼロは、デフォルトの制限を使用することを意味します。 211 MaxResponseHeaderBytes int64 212 213 // WriteBufferSizeは、トランスポートへの書き込み時に使用される書き込みバッファのサイズを指定します。 214 // ゼロの場合、デフォルト値(現在は4KB)が使用されます。 215 WriteBufferSize int 216 217 // ReadBufferSizeは、トランスポートから読み取るときに使用される読み取りバッファのサイズを指定します。 218 // ゼロの場合、デフォルト値(現在は4KB)が使用されます。 219 ReadBufferSize int 220 221 // nextProtoOnce guards initialization of TLSNextProto and 222 // h2transport (via onceSetNextProtoDefaults) 223 nextProtoOnce sync.Once 224 h2transport h2Transport 225 tlsNextProtoWasNil bool 226 227 // ForceAttemptHTTP2は、非ゼロの 228 // Dial, DialTLS, または DialContext 関数または TLSClientConfig が提供されたときに、 229 // HTTP/2が有効になるかどうかを制御します。 230 // デフォルトでは、これらのフィールドのいずれかの使用は、保守的にHTTP/2を無効にします。 231 // カスタムダイヤラーやTLS設定を使用しつつ、HTTP/2への 232 // アップグレードを試みるには、これをtrueに設定します。 233 ForceAttemptHTTP2 bool 234 } 235 236 // Cloneは、tのエクスポートされたフィールドのディープコピーを返します。 237 func (t *Transport) Clone() *Transport 238 239 // ProxyFromEnvironmentは、環境変数HTTP_PROXY、HTTPS_PROXY、およびNO_PROXY(またはそれらの小文字バージョン)によって示されるように、 240 // 指定されたリクエストに使用するプロキシのURLを返します。 241 // リクエストは、NO_PROXYによって除外されていない限り、スキームに一致する環境変数からプロキシを使用します。 242 // 243 // 環境値は、完全なURLまたは"host[:port]"のいずれかである場合があります。この場合、"http"スキームが想定されます。 244 // 値が異なる形式の場合は、エラーが返されます。 245 // 246 // 環境変数でプロキシが定義されていない場合、またはNO_PROXYによって指定されたリクエストにプロキシを使用しない場合、 247 // nilのURLとnilのエラーが返されます。 248 // 249 // 特別な場合として、req.URL.Hostが"localhost"(ポート番号ありまたはなし)の場合、nilのURLとnilのエラーが返されます。 250 func ProxyFromEnvironment(req *Request) (*url.URL, error) 251 252 // ProxyURLは、常に同じURLを返すプロキシ関数([Transport] で使用するため)を返します。 253 func ProxyURL(fixedURL *url.URL) func(*Request) (*url.URL, error) 254 255 // ErrSkipAltProtocolは、Transport.RegisterProtocolによって定義されたセンチネルエラー値です。 256 var ErrSkipAltProtocol = errors.New("net/http: skip alternate protocol") 257 258 // RegisterProtocolは、新しいプロトコルをスキームとともに登録します。 259 // [Transport] は、指定されたスキームを使用してリクエストをrtに渡します。 260 // HTTPリクエストのセマンティクスをシミュレートする責任は、rtにあります。 261 // 262 // RegisterProtocolは、他のパッケージが"ftp"や"file"などのプロトコルスキームの実装を提供するために使用できます。 263 // 264 // rt.RoundTripが [ErrSkipAltProtocol] を返す場合、Transportは、 265 // 登録されたプロトコルのように扱わずに、その1つのリクエストに対して自身で [Transport.RoundTrip] を処理します。 266 func (t *Transport) RegisterProtocol(scheme string, rt RoundTripper) 267 268 // CloseIdleConnectionsは、以前のリクエストから接続されていたが、現在はアイドル状態になっている"keep-alive"状態の接続を閉じます。 269 // 現在使用中の接続は中断しません。 270 func (t *Transport) CloseIdleConnections() 271 272 // CancelRequestは、その接続を閉じることにより、進行中のリクエストをキャンセルします。 273 // CancelRequestは、 [Transport.RoundTrip] が返された後にのみ呼び出す必要があります。 274 // 275 // Deprecated: 代わりに、キャンセル可能なコンテキストを持つリクエストを作成するために [Request.WithContext] を使用してください。 276 // CancelRequestは、HTTP/2リクエストをキャンセルできません。 277 func (t *Transport) CancelRequest(req *Request) 278 279 var _ io.ReaderFrom = (*persistConnWriter)(nil)