81352f33fc
If a user has a proxy using HTTP but a URL using HTTPS, we fail to honor the http.proxy configuration setting because we check the scheme of the proxy URL, not the scheme of the request URL. Let's fix this by deciding which proxy variable to set based on the request URL, as was probably intended, rather than the proxy URL. Add some tests for this case, as well as the case that we correctly ignore the HTTPS_PROXY environment variable if the scheme of the request URL is HTTP, which we were previously lacking.
92 lines
2.0 KiB
Go
92 lines
2.0 KiB
Go
package lfshttp
|
|
|
|
import (
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
|
|
"github.com/git-lfs/git-lfs/config"
|
|
"golang.org/x/net/http/httpproxy"
|
|
)
|
|
|
|
// Logic is copied, with small changes, from "net/http".ProxyFromEnvironment in the go std lib.
|
|
func proxyFromClient(c *Client) func(req *http.Request) (*url.URL, error) {
|
|
return func(req *http.Request) (*url.URL, error) {
|
|
httpsProxy, httpProxy, noProxy := getProxyServers(req.URL, c.uc, c.osEnv)
|
|
|
|
var proxy string
|
|
if req.URL.Scheme == "https" {
|
|
proxy = httpsProxy
|
|
}
|
|
|
|
if len(proxy) == 0 {
|
|
proxy = httpProxy
|
|
}
|
|
|
|
if len(proxy) == 0 {
|
|
return nil, nil
|
|
}
|
|
|
|
if strings.HasPrefix(proxy, "socks5h://") {
|
|
proxy = strings.Replace(proxy, "socks5h://", "socks5://", 1)
|
|
}
|
|
|
|
cfg := &httpproxy.Config{
|
|
HTTPProxy: proxy,
|
|
HTTPSProxy: proxy,
|
|
NoProxy: noProxy,
|
|
CGI: false,
|
|
}
|
|
|
|
// We want to use the standard logic except that we want to
|
|
// allow proxies for localhost, which the standard library does
|
|
// not. Since the proxy code looks only at the URL, we
|
|
// synthesize a fake URL except that we rewrite "localhost" to
|
|
// "127.0.0.1" for purposes of looking up the proxy.
|
|
u := *(req.URL)
|
|
if u.Host == "localhost" {
|
|
u.Host = "127.0.0.1"
|
|
}
|
|
return cfg.ProxyFunc()(&u)
|
|
}
|
|
}
|
|
|
|
func getProxyServers(u *url.URL, urlCfg *config.URLConfig, osEnv config.Environment) (httpsProxy string, httpProxy string, noProxy string) {
|
|
if osEnv == nil {
|
|
return
|
|
}
|
|
|
|
if len(httpsProxy) == 0 {
|
|
httpsProxy, _ = osEnv.Get("HTTPS_PROXY")
|
|
}
|
|
|
|
if len(httpsProxy) == 0 {
|
|
httpsProxy, _ = osEnv.Get("https_proxy")
|
|
}
|
|
|
|
if len(httpProxy) == 0 {
|
|
httpProxy, _ = osEnv.Get("HTTP_PROXY")
|
|
}
|
|
|
|
if len(httpProxy) == 0 {
|
|
httpProxy, _ = osEnv.Get("http_proxy")
|
|
}
|
|
|
|
if urlCfg != nil {
|
|
gitProxy, ok := urlCfg.Get("http", u.String(), "proxy")
|
|
if len(gitProxy) > 0 && ok {
|
|
if u.Scheme == "https" {
|
|
httpsProxy = gitProxy
|
|
}
|
|
httpProxy = gitProxy
|
|
}
|
|
}
|
|
|
|
noProxy, _ = osEnv.Get("NO_PROXY")
|
|
if len(noProxy) == 0 {
|
|
noProxy, _ = osEnv.Get("no_proxy")
|
|
}
|
|
|
|
return
|
|
}
|