copy http.ProxyFromEnvironment so we can put our own unique git spin on it

This commit is contained in:
risk danger olson 2016-07-08 14:48:42 -06:00
parent f3f32b07c0
commit 9cc130f964
4 changed files with 164 additions and 16 deletions

@ -85,6 +85,7 @@ func NewConfig() *Configuration {
func NewFromValues(gitconfig map[string]string) *Configuration {
config := &Configuration{
gitConfig: make(map[string]string, 0),
envVars: make(map[string]string, 0),
}
buf := bytes.NewBuffer([]byte{})

@ -12,7 +12,6 @@ import (
"net"
"net/http"
"net/http/httputil"
"net/url"
"os"
"path/filepath"
"strings"
@ -146,21 +145,6 @@ func NewHttpClient(c *config.Configuration, host string) *HttpClient {
return client
}
func ProxyFromGitConfigOrEnvironment(c *config.Configuration) func(req *http.Request) (*url.URL, error) {
return func(req *http.Request) (*url.URL, error) {
proxyURL, err := http.ProxyFromEnvironment(req)
if proxyURL != nil || err != nil {
return proxyURL, err
}
if proxy, ok := c.GitConfig("http.proxy"); ok {
return url.Parse(proxy)
}
return nil, nil
}
}
func CheckRedirect(req *http.Request, via []*http.Request) error {
if len(via) >= 3 {
return errors.New("stopped after 3 redirects")

139
httputil/proxy.go Normal file

@ -0,0 +1,139 @@
package httputil
import (
"net"
"net/http"
"net/url"
"strings"
"fmt"
"github.com/github/git-lfs/config"
)
func ProxyFromGitConfigOrEnvironment(c *config.Configuration) func(req *http.Request) (*url.URL, error) {
https_proxy := c.Getenv("HTTPS_PROXY")
if len(https_proxy) == 0 {
https_proxy = c.Getenv("https_proxy")
}
http_proxy := c.Getenv("HTTP_PROXY")
if len(http_proxy) == 0 {
http_proxy = c.Getenv("http_proxy")
}
if len(http_proxy) == 0 {
http_proxy, _ = c.GitConfig("http.proxy")
}
no_proxy := c.Getenv("NO_PROXY")
if len(no_proxy) == 0 {
no_proxy = c.Getenv("no_proxy")
}
return func(req *http.Request) (*url.URL, error) {
var proxy string
if req.URL.Scheme == "https" {
proxy = https_proxy
}
if len(proxy) == 0 {
proxy = http_proxy
}
if len(proxy) == 0 {
return nil, nil
}
if !useProxy(no_proxy, canonicalAddr(req.URL)) {
return nil, nil
}
proxyURL, err := url.Parse(proxy)
if err != nil || !strings.HasPrefix(proxyURL.Scheme, "http") {
// proxy was bogus. Try prepending "http://" to it and
// see if that parses correctly. If not, we fall
// through and complain about the original one.
if proxyURL, err := url.Parse("http://" + proxy); err == nil {
return proxyURL, nil
}
}
if err != nil {
return nil, fmt.Errorf("invalid proxy address: %q: %v", proxy, err)
}
return proxyURL, nil
}
}
// canonicalAddr returns url.Host but always with a ":port" suffix
func canonicalAddr(url *url.URL) string {
addr := url.Host
if !hasPort(addr) {
return addr + ":" + portMap[url.Scheme]
}
return addr
}
// useProxy reports whether requests to addr should use a proxy,
// according to the NO_PROXY or no_proxy environment variable.
// addr is always a canonicalAddr with a host and port.
func useProxy(no_proxy, addr string) bool {
if len(addr) == 0 {
return true
}
if no_proxy == "*" {
return false
}
host, _, err := net.SplitHostPort(addr)
if err != nil {
return false
}
if host == "localhost" {
return false
}
if ip := net.ParseIP(host); ip != nil {
if ip.IsLoopback() {
return false
}
}
addr = strings.ToLower(strings.TrimSpace(addr))
if hasPort(addr) {
addr = addr[:strings.LastIndex(addr, ":")]
}
for _, p := range strings.Split(no_proxy, ",") {
p = strings.ToLower(strings.TrimSpace(p))
if len(p) == 0 {
continue
}
if hasPort(p) {
p = p[:strings.LastIndex(p, ":")]
}
if addr == p {
return false
}
if p[0] == '.' && (strings.HasSuffix(addr, p) || addr == p[1:]) {
// no_proxy ".foo.com" matches "bar.foo.com" or "foo.com"
return false
}
if p[0] != '.' && strings.HasSuffix(addr, p) && addr[len(addr)-len(p)-1] == '.' {
// no_proxy "foo.com" matches "bar.foo.com"
return false
}
}
return true
}
// Given a string of the form "host", "host:port", or "[ipv6::address]:port",
// return true if the string includes a port.
func hasPort(s string) bool { return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") }
var (
portMap = map[string]string{
"http": "80",
"https": "443",
}
)

@ -10,6 +10,30 @@ import (
"github.com/stretchr/testify/assert"
)
func TestProxyFromEnvironment(t *testing.T) {
cfg := config.NewFromValues(map[string]string{
"http.proxy": "https://proxy-from-git-config:8080",
})
cfg.SetAllEnv(map[string]string{
"HTTPS_PROXY": "https://proxy-from-env:8080",
})
u, err := url.Parse("https://some-host.com:123/foo/bar")
if err != nil {
t.Fatal(err)
}
req := &http.Request{
URL: u,
Header: http.Header{},
}
proxyURL, err := httputil.ProxyFromGitConfigOrEnvironment(cfg)(req)
assert.Equal(t, "proxy-from-env:8080", proxyURL.Host)
assert.Equal(t, nil, err)
}
func TestProxyFromGitConfig(t *testing.T) {
cfg := config.NewFromValues(map[string]string{
"http.proxy": "https://proxy-from-git-config:8080",