Client 根据地址获取客户端
(req *HTTPRequest, origin *serverconfigs.OriginConfig, originAddr string, proxyProtocol *serverconfigs.ProxyProtocolConfig, followRedirects bool)
| 50 | |
| 51 | // Client 根据地址获取客户端 |
| 52 | func (this *HTTPClientPool) Client(req *HTTPRequest, |
| 53 | origin *serverconfigs.OriginConfig, |
| 54 | originAddr string, |
| 55 | proxyProtocol *serverconfigs.ProxyProtocolConfig, |
| 56 | followRedirects bool) (rawClient *http.Client, err error) { |
| 57 | if origin.Addr == nil { |
| 58 | return nil, errors.New("origin addr should not be empty (originId:" + strconv.FormatInt(origin.Id, 10) + ")") |
| 59 | } |
| 60 | |
| 61 | if req == nil || req.RawReq == nil || req.RawReq.URL == nil { |
| 62 | err = errors.New("invalid request url") |
| 63 | return |
| 64 | } |
| 65 | var originHost = req.RawReq.URL.Host |
| 66 | var urlPort = req.RawReq.URL.Port() |
| 67 | if len(urlPort) == 0 { |
| 68 | if req.RawReq.URL.Scheme == "http" { |
| 69 | urlPort = "80" |
| 70 | } else { |
| 71 | urlPort = "443" |
| 72 | } |
| 73 | |
| 74 | originHost += ":" + urlPort |
| 75 | } |
| 76 | |
| 77 | var rawKey = origin.UniqueKey() + "@" + originAddr + "@" + originHost |
| 78 | |
| 79 | // if we are under available ProxyProtocol, we add client ip to key to make every client unique |
| 80 | var isProxyProtocol = false |
| 81 | if proxyProtocol != nil && proxyProtocol.IsOn { |
| 82 | rawKey += httpClientProxyProtocolTag + req.requestRemoteAddr(true) |
| 83 | isProxyProtocol = true |
| 84 | } |
| 85 | |
| 86 | // follow redirects |
| 87 | if followRedirects { |
| 88 | rawKey += "@follow" |
| 89 | } |
| 90 | |
| 91 | var key = xxhash.Sum64String(rawKey) |
| 92 | |
| 93 | var isLnRequest = origin.Id == 0 |
| 94 | |
| 95 | this.locker.RLock() |
| 96 | client, found := this.clientsMap[key] |
| 97 | this.locker.RUnlock() |
| 98 | if found { |
| 99 | client.UpdateAccessTime() |
| 100 | return client.RawClient(), nil |
| 101 | } |
| 102 | |
| 103 | // 这里不能使用RLock,避免因为并发生成多个同样的client实例 |
| 104 | this.locker.Lock() |
| 105 | defer this.locker.Unlock() |
| 106 | |
| 107 | // 再次查找 |
| 108 | client, found = this.clientsMap[key] |
| 109 | if found { |