acd77c36f9
Currently, our proxy support has some limitations. Notably, we don't handle wildcards in the no_proxy environment variable. Unfortunately for us, there's no standard as to how these environment variables are supposed to be handled, so any attempt we made to handle this ourselves would likely be incomplete. However, fortunately for us, our needs are simple: we need standard behavior except that a user can use a proxy for localhost, and we need to be able to read from a source other than the environment. The solution is to use the Go extension httpproxy module along with a little bit of custom configuration and URL rewriting, which means we don't have to worry about maintaining the complexity of parsing proxy support. This also means we can drop a large amount of complex (and subtly wrong) code.
88 lines
1.9 KiB
Go
88 lines
1.9 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
|
|
}
|
|
|
|
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 strings.HasPrefix(gitProxy, "https://") {
|
|
httpsProxy = gitProxy
|
|
}
|
|
httpProxy = gitProxy
|
|
}
|
|
}
|
|
|
|
noProxy, _ = osEnv.Get("NO_PROXY")
|
|
if len(noProxy) == 0 {
|
|
noProxy, _ = osEnv.Get("no_proxy")
|
|
}
|
|
|
|
return
|
|
}
|