forked from docker/go-connections
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
sockets: add TCPProxyFromEnvironment to keep pre-go1.16 behavior
TCPProxyFromEnvironment wraps http.ProxyFromEnvironment, to preserve the pre-go1.16 behavior for URLs using the 'tcp://' scheme. For other schemes, golang's standard behavior is preserved (and depends on the Go version used). Prior to go1.16, `https://` schemes would use HTTPS_PROXY, and any other scheme would use HTTP_PROXY. However, golang/net@7b1cca2 (per a request in golang/go#40909) changed this behavior to only use HTTP_PROXY for `http://` schemes, no longer using a proxy for any other scheme. Docker uses the `tcp://` scheme as a default for API connections, to indicate that the API is not "purely" HTTP. Various parts in the code also *require* this scheme to be used. While we could change the default and allow http(s) schemes to be used, doing so will take time, taking into account that there are many installs in existence that have tcp:// configured as DOCKER_HOST. This function detects if the `tcp://` scheme is used; if it is, it creates a shallow copy of req, containing just the URL, and overrides the scheme with 'http', which should be sufficient to perform proxy detection. For other (non-'tcp://') schemes, http.ProxyFromEnvironment is called without altering the request. Signed-off-by: Sebastiaan van Stijn <[email protected]>
- Loading branch information
Showing
2 changed files
with
135 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package sockets | ||
|
||
import ( | ||
"net/http" | ||
"net/url" | ||
"os" | ||
"testing" | ||
) | ||
|
||
var ( | ||
httpProxy = "http://proxy.example.com" | ||
httpsProxy = "https://proxy.example.com" | ||
) | ||
|
||
func TestConfigureTransportProxy(t *testing.T) { | ||
// roughly based on defaultHTTPClient in the docker client | ||
u := &url.URL{ | ||
Scheme: "tcp", | ||
Host: "docker.acme.example.com", | ||
} | ||
transport := new(http.Transport) | ||
err := ConfigureTransport(transport, u.Scheme, u.Host) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
if err := os.Setenv("HTTP_PROXY", httpProxy); err != nil { | ||
t.Fatal(err) | ||
} | ||
if err := os.Setenv("HTTPS_PROXY", httpsProxy); err != nil { | ||
t.Fatal(err) | ||
} | ||
defer func() { | ||
_ = os.Unsetenv("HTTP_PROXY") | ||
_ = os.Unsetenv("HTTPS_PROXY") | ||
}() | ||
|
||
request, err := http.NewRequest(http.MethodGet, "tcp://docker.acme.example.com:2376", nil) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
proxyURL, err := transport.Proxy(request) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
if proxyURL.String() != httpProxy { | ||
t.Fatalf("expected %s, got %s", httpProxy, proxyURL) | ||
} | ||
} | ||
|
||
func TestTCPProxyFromEnvironment(t *testing.T) { | ||
if err := os.Setenv("HTTP_PROXY", httpProxy); err != nil { | ||
t.Fatal(err) | ||
} | ||
if err := os.Setenv("HTTPS_PROXY", httpsProxy); err != nil { | ||
t.Fatal(err) | ||
} | ||
defer func() { | ||
_ = os.Unsetenv("HTTP_PROXY") | ||
_ = os.Unsetenv("HTTPS_PROXY") | ||
}() | ||
|
||
tests := []struct { | ||
url string | ||
expected *string | ||
}{ | ||
{ | ||
url: "tcp://example.com:2376", | ||
expected: &httpProxy, | ||
}, | ||
{ | ||
url: "http://example.com:2375", | ||
expected: &httpProxy, | ||
}, | ||
{ | ||
url: "https://example.com:2376", | ||
expected: &httpsProxy, | ||
}, | ||
} | ||
|
||
for _, tc := range tests { | ||
tc := tc | ||
t.Run(tc.url, func(t *testing.T) { | ||
request, err := http.NewRequest(http.MethodGet, tc.url, nil) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
proxyURL, err := TCPProxyFromEnvironment(request) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
if tc.expected == nil { | ||
if proxyURL != nil { | ||
t.Fatalf("expected no proxy, got %s", proxyURL) | ||
} | ||
} else if proxyURL.String() != *tc.expected { | ||
t.Fatalf("expected %s, got %s", *tc.expected, proxyURL) | ||
} | ||
}) | ||
} | ||
} |