Golang http之transport源码详解

   使用golang net/http库发送http请求,最后都是调用 transport的 RoundTrip方法中。

type RoundTripper interface {
	RoundTrip(*Request) (*Response, error)
}

RoundTrip代表一个http事务,给一个请求返回一个响应。RoundTripper必须是并发安全的。RoundTripper接口的实现Transport结构体在源码包net/http/transport.go 中。

 

type Transport struct {
	idleMu     sync.Mutex
	wantIdle   bool                                // user has requested to close all idle conns  用户是否已关闭所有的空闲连接
	idleConn   map[connectMethodKey][]*persistConn // most recently used at end,保存从connectMethodKey(代表着不同的协议,不同的host,也就是不同的请求)到persistConn的映射
	/*
	idleConnCh 用来在并发http请求的时候在多个 goroutine 里面相互发送持久连接,也就是说,
	这些持久连接是可以重复利用的, 你的http请求用某个persistConn用完了,
	通过这个channel发送给其他http请求使用这个persistConn
	*/
	idleConnCh map[connectMethodKey]chan *persistConn
	idleLRU    connLRU

	reqMu       sync.Mutex
	reqCanceler map[*Request]func(error)   //请求取消器

	altMu    sync.Mutex   // guards changing altProto only
	altProto atomic.Value // of nil or map[string]RoundTripper, key is URI scheme  为空或者map[string]RoundTripper,key为URI  的scheme,用于自定义的协议及对应的处理请求的RoundTripper

	// Proxy specifies a function to return a proxy for a given
	// Request. If the function returns a non-nil error, the
	// request is aborted with the provided error.
	//
	// The proxy type is determined by the URL scheme. "http"
	// and "socks5" are supported. If the scheme is empty,
	// "http" is assumed.
	//
	// If Proxy is nil or returns a nil *URL, no proxy is used.
	Proxy func(*Request) (*url.URL, error)   //根据给定的Request返回一个代理,如果返回一个不为空的error,请求会终止

	// DialContext specifies the dial function for creating unencrypted TCP connections.
	// If DialContext is nil (and the deprecated Dial below is also nil),
	// then the transport dials using package net.
	/*
	DialContext用于指定创建未加密的TCP连接的dial功能,如果该函数为空,则使用net包下的dial函数
	*/
	DialContext func(ctx context.Context, network, addr string) (net.Conn, error)

	// Dial specifies the dial function for creating unencrypted TCP connections.
	//
	// Deprecated: Use DialContext instead, which allows the transport
	// to cancel dials as soon as they are no longer needed.
	// If both are set, DialContext takes priority.
	/*
	Dial获取一个tcp连接,也就是net.Conn结构,然后就可以写入request,从而获取到response
	DialContext比Dial函数的优先级高
	*/
	Dial func(network, addr string) (net.Conn, error)

	// DialTLS specifies an optional dial function for creating
	// TLS connections for non-proxied HTTPS requests.
	//
	// If DialTLS is nil, Dial and TLSClientConfig are used.
	//
	// If DialTLS is set, the Dial hook is not used for HTTPS
	// requests and the TLSClientConfig and TLSHandshakeTimeout
	// are ignored. The returned net.Conn is assumed to already be
	// past the TLS handshake.
	/*
	DialTLS  为创建非代理的HTTPS请求的TLS连接提供一个可选的dial功能
	如果DialTLS为空,则使用Dial和TLSClientConfig
	如果设置了DialTLS,则HTTPS的请求不使用Dial的钩子,并且TLSClientConfig 和 TLSHandshakeTimeout会被忽略
	返回的net.Conn假设已经通过了TLS握手
	*/
	DialTLS func(network, addr string) (net.Conn, error)

	// TLSClientConfig specifies the TLS configuration to use with
	// tls.Client.
	// If nil, the default configuration is used.
	// If non-nil, HTTP/2 support may not be enabled by default.
	/*
      TLSClientConfig指定tls.Client使用的TLS配置信息
	如果为空,则使用默认配置
	如果不为空,默认情况下未启动HTTP/2支持
	*/
	TLSClientConfig *tls.Config

	// TLSHandshakeTimeout specifies the maximum amount of time waiting to
	// wait for a TLS handshake. Zero means no timeout.
	/*
	指定TLS握手的超时时间
	*/
	TLSHandshakeTimeout time.Duration

	// DisableKeepAlives, if true, prevents re-use of TCP connections
	// between different HTTP requests.
	DisableKeepAlives bool   //如果为true,则阻止在不同http请求之间重用TCP连接

	// DisableCompression, if true, prevents the Transport from
	// requesting compression with an "Accept-Encoding: gzip"
	// request header when the Request contains no existing
	// Accept-Encoding value. If the Transport requests gzip on
	// its own and gets a gzipped response, it's transparently
	// decoded in the Response.Body. However, if the user
	// explicitly requested gzip it is not automatically
	// uncompressed.
	DisableCompression bool   //如果为true,则进制传输使用 Accept-Encoding: gzip

	// MaxIdleConns controls the maximum number of idle (keep-alive)
	// connections across all hosts. Zero means no limit.
	MaxIdleConns int   //指定最大的空闲连接数

	// MaxIdleConnsPerHost, if non-zero, controls the maximum idle
	// (keep-alive) connections to keep per-host. If zero,
	// DefaultMaxIdleConnsPerHost is used.
	MaxIdleConnsPerHost int  //用于控制某一个主机的连接的最大空闲数

	// IdleConnTimeout is the maximum amount of time an idle
	// (keep-alive) connection will remain idle before closing
	// itself.
	// Zero means no limit.
	IdleConnTimeout time.Duration   //指定空闲连接保持的最长时间,如果为0,则不受限制

	// ResponseHeaderTimeout, if non-zero, specifies the amount of
	// time to wait for a server's response headers after fully
	// writing the request (including its body, if any). This
	// time does not include the time to read the response body.
	/*
	ResponseHeaderTimeout,如果非零,则指定在完全写入请求(包括其正文,如果有)之后等待服务器响应头的最长时间。
	此时间不包括读响应体的时间。
	*/
	ResponseHeaderTimeout time.Duration

	// ExpectContinueTimeout, if non-zero, specifies the amount of
	// time to wait for a server's first response headers after fully
	// writing the request headers if the request has an
	// "Expect: 100-continue" header. Zero means no timeout and
	// causes the body to be sent immediately, without
	// waiting for the server to approve.
	// This time does not include the time to send the request header.
	/*
   如果请求头是"Expect:100-continue",ExpectContinueTimeout  如果不为0,它表示等待服务器第一次响应头的最大时间
	零表示没有超时并导致正文立即发送,无需等待服务器批准。
	此时间不包括发送请求标头的时间。
	*/
	ExpectContinueTimeout time.Duration

	// TLSNextProto specifies how the Transport switches to an
	// alternate protocol (such as HTTP/2) after a TLS NPN/ALPN
	// protocol negotiation. If Transport dials an TLS connection
	// with a non-empty protocol name and TLSNextProto contains a
	// map entry for that key (such as "h2"), then the func is
	// called with the request's authority (such as "example.com"
	// or "example.com:1234") and the TLS connection. The function
	// must return a RoundTripper that then handles the request.
	// If TLSNextProto is not nil, HTTP/2 support is not enabled
	// automatically.
	/*
TLSNextProto指定在TLS NPN / ALPN协议协商之后传输如何切换到备用协议(例如HTTP / 2)。
	如果传输使用非空协议名称拨打TLS连接并且TLSNextProto包含该密钥的映射条目(例如“h2”),则使用请求的权限调用func(例如“example.com”或“example” .com:1234“)和TLS连接。
	该函数必须返回一个RoundTripper,然后处理该请求。 如果TLSNextProto不是nil,则不会自动启用HTTP / 2支持。
	*/
	TLSNextProto map[string]func(authority string, c *tls.Conn) RoundTripper

	// ProxyConnectHeader optionally specifies headers to send to
	// proxies during CONNECT requests.
	/*
	ProxyConnectHeader可选地指定在CONNECT请求期间发送给代理的标头。
	*/
	ProxyConnectHea
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值