|
7 | 7 | // This is the low-level Transport implementation of RoundTripper. |
8 | 8 | // The high-level interface is in client.go. |
9 | 9 |
|
| 10 | +// +build !js |
| 11 | + |
10 | 12 | package http |
11 | 13 |
|
12 | 14 | import ( |
@@ -255,66 +257,6 @@ func (t *Transport) onceSetNextProtoDefaults() { |
255 | 257 | } |
256 | 258 | } |
257 | 259 |
|
258 | | -// ProxyFromEnvironment returns the URL of the proxy to use for a |
259 | | -// given request, as indicated by the environment variables |
260 | | -// HTTP_PROXY, HTTPS_PROXY and NO_PROXY (or the lowercase versions |
261 | | -// thereof). HTTPS_PROXY takes precedence over HTTP_PROXY for https |
262 | | -// requests. |
263 | | -// |
264 | | -// The environment values may be either a complete URL or a |
265 | | -// "host[:port]", in which case the "http" scheme is assumed. |
266 | | -// An error is returned if the value is a different form. |
267 | | -// |
268 | | -// A nil URL and nil error are returned if no proxy is defined in the |
269 | | -// environment, or a proxy should not be used for the given request, |
270 | | -// as defined by NO_PROXY. |
271 | | -// |
272 | | -// As a special case, if req.URL.Host is "localhost" (with or without |
273 | | -// a port number), then a nil URL and nil error will be returned. |
274 | | -func ProxyFromEnvironment(req *Request) (*url.URL, error) { |
275 | | - var proxy string |
276 | | - if req.URL.Scheme == "https" { |
277 | | - proxy = httpsProxyEnv.Get() |
278 | | - } |
279 | | - if proxy == "" { |
280 | | - proxy = httpProxyEnv.Get() |
281 | | - if proxy != "" && os.Getenv("REQUEST_METHOD") != "" { |
282 | | - return nil, errors.New("net/http: refusing to use HTTP_PROXY value in CGI environment; see golang.org/s/cgihttpproxy") |
283 | | - } |
284 | | - } |
285 | | - if proxy == "" { |
286 | | - return nil, nil |
287 | | - } |
288 | | - if !useProxy(canonicalAddr(req.URL)) { |
289 | | - return nil, nil |
290 | | - } |
291 | | - proxyURL, err := url.Parse(proxy) |
292 | | - if err != nil || |
293 | | - (proxyURL.Scheme != "http" && |
294 | | - proxyURL.Scheme != "https" && |
295 | | - proxyURL.Scheme != "socks5") { |
296 | | - // proxy was bogus. Try prepending "http://" to it and |
297 | | - // see if that parses correctly. If not, we fall |
298 | | - // through and complain about the original one. |
299 | | - if proxyURL, err := url.Parse("http://" + proxy); err == nil { |
300 | | - return proxyURL, nil |
301 | | - } |
302 | | - |
303 | | - } |
304 | | - if err != nil { |
305 | | - return nil, fmt.Errorf("invalid proxy address %q: %v", proxy, err) |
306 | | - } |
307 | | - return proxyURL, nil |
308 | | -} |
309 | | - |
310 | | -// ProxyURL returns a proxy function (for use in a Transport) |
311 | | -// that always returns the same URL. |
312 | | -func ProxyURL(fixedURL *url.URL) func(*Request) (*url.URL, error) { |
313 | | - return func(*Request) (*url.URL, error) { |
314 | | - return fixedURL, nil |
315 | | - } |
316 | | -} |
317 | | - |
318 | 260 | // transportRequest is a wrapper around a *Request that adds |
319 | 261 | // optional extra headers to write and stores any error to return |
320 | 262 | // from roundTrip. |
@@ -573,47 +515,6 @@ func (t *Transport) cancelRequest(req *Request, err error) { |
573 | 515 | // Private implementation past this point. |
574 | 516 | // |
575 | 517 |
|
576 | | -var ( |
577 | | - httpProxyEnv = &envOnce{ |
578 | | - names: []string{"HTTP_PROXY", "http_proxy"}, |
579 | | - } |
580 | | - httpsProxyEnv = &envOnce{ |
581 | | - names: []string{"HTTPS_PROXY", "https_proxy"}, |
582 | | - } |
583 | | - noProxyEnv = &envOnce{ |
584 | | - names: []string{"NO_PROXY", "no_proxy"}, |
585 | | - } |
586 | | -) |
587 | | - |
588 | | -// envOnce looks up an environment variable (optionally by multiple |
589 | | -// names) once. It mitigates expensive lookups on some platforms |
590 | | -// (e.g. Windows). |
591 | | -type envOnce struct { |
592 | | - names []string |
593 | | - once sync.Once |
594 | | - val string |
595 | | -} |
596 | | - |
597 | | -func (e *envOnce) Get() string { |
598 | | - e.once.Do(e.init) |
599 | | - return e.val |
600 | | -} |
601 | | - |
602 | | -func (e *envOnce) init() { |
603 | | - for _, n := range e.names { |
604 | | - e.val = os.Getenv(n) |
605 | | - if e.val != "" { |
606 | | - return |
607 | | - } |
608 | | - } |
609 | | -} |
610 | | - |
611 | | -// reset is used by tests |
612 | | -func (e *envOnce) reset() { |
613 | | - e.once = sync.Once{} |
614 | | - e.val = "" |
615 | | -} |
616 | | - |
617 | 518 | func (t *Transport) connectMethodForRequest(treq *transportRequest) (cm connectMethod, err error) { |
618 | 519 | if port := treq.URL.Port(); !validPort(port) { |
619 | 520 | return cm, fmt.Errorf("invalid URL port %q", port) |
@@ -1235,63 +1136,6 @@ func (w persistConnWriter) Write(p []byte) (n int, err error) { |
1235 | 1136 | return |
1236 | 1137 | } |
1237 | 1138 |
|
1238 | | -// useProxy reports whether requests to addr should use a proxy, |
1239 | | -// according to the NO_PROXY or no_proxy environment variable. |
1240 | | -// addr is always a canonicalAddr with a host and port. |
1241 | | -func useProxy(addr string) bool { |
1242 | | - if len(addr) == 0 { |
1243 | | - return true |
1244 | | - } |
1245 | | - host, _, err := net.SplitHostPort(addr) |
1246 | | - if err != nil { |
1247 | | - return false |
1248 | | - } |
1249 | | - if host == "localhost" { |
1250 | | - return false |
1251 | | - } |
1252 | | - if ip := net.ParseIP(host); ip != nil { |
1253 | | - if ip.IsLoopback() { |
1254 | | - return false |
1255 | | - } |
1256 | | - } |
1257 | | - |
1258 | | - noProxy := noProxyEnv.Get() |
1259 | | - if noProxy == "*" { |
1260 | | - return false |
1261 | | - } |
1262 | | - |
1263 | | - addr = strings.ToLower(strings.TrimSpace(addr)) |
1264 | | - if hasPort(addr) { |
1265 | | - addr = addr[:strings.LastIndex(addr, ":")] |
1266 | | - } |
1267 | | - |
1268 | | - for _, p := range strings.Split(noProxy, ",") { |
1269 | | - p = strings.ToLower(strings.TrimSpace(p)) |
1270 | | - if len(p) == 0 { |
1271 | | - continue |
1272 | | - } |
1273 | | - if hasPort(p) { |
1274 | | - p = p[:strings.LastIndex(p, ":")] |
1275 | | - } |
1276 | | - if addr == p { |
1277 | | - return false |
1278 | | - } |
1279 | | - if len(p) == 0 { |
1280 | | - // There is no host part, likely the entry is malformed; ignore. |
1281 | | - continue |
1282 | | - } |
1283 | | - if p[0] == '.' && (strings.HasSuffix(addr, p) || addr == p[1:]) { |
1284 | | - // no_proxy ".foo.com" matches "bar.foo.com" or "foo.com" |
1285 | | - return false |
1286 | | - } |
1287 | | - if p[0] != '.' && strings.HasSuffix(addr, p) && addr[len(addr)-len(p)-1] == '.' { |
1288 | | - // no_proxy "foo.com" matches "bar.foo.com" |
1289 | | - return false |
1290 | | - } |
1291 | | - } |
1292 | | - return true |
1293 | | -} |
1294 | | - |
1295 | 1139 | // connectMethod is the map key (in its String form) for keeping persistent |
1296 | 1140 | // TCP connections alive for subsequent HTTP requests. |
1297 | 1141 | // |
@@ -2118,19 +1962,6 @@ var portMap = map[string]string{ |
2118 | 1962 | "socks5": "1080", |
2119 | 1963 | } |
2120 | 1964 |
|
2121 | | -// canonicalAddr returns url.Host but always with a ":port" suffix |
2122 | | -func canonicalAddr(url *url.URL) string { |
2123 | | - addr := url.Hostname() |
2124 | | - if v, err := idnaASCII(addr); err == nil { |
2125 | | - addr = v |
2126 | | - } |
2127 | | - port := url.Port() |
2128 | | - if port == "" { |
2129 | | - port = portMap[url.Scheme] |
2130 | | - } |
2131 | | - return net.JoinHostPort(addr, port) |
2132 | | -} |
2133 | | - |
2134 | 1965 | // bodyEOFSignal is used by the HTTP/1 transport when reading response |
2135 | 1966 | // bodies to make sure we see the end of a response body before |
2136 | 1967 | // proceeding and reading on the connection again. |
|
0 commit comments