Skip to content

Commit f5c79ea

Browse files
committed
Use Docker Desktop proxy when Desktop is running
Signed-off-by: Guillaume Tardif <guillaume.tardif@gmail.com>
1 parent 53a35dc commit f5c79ea

8 files changed

Lines changed: 66 additions & 1 deletion

File tree

pkg/desktop/paths.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import "sync"
44

55
type DockerDesktopPaths struct {
66
BackendSocket string
7+
ProxySocket string
78
}
89

910
var Paths = sync.OnceValue(func() DockerDesktopPaths {

pkg/desktop/socket/dial.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package socket
2+
3+
import (
4+
"strings"
5+
)
6+
7+
func stripUnixScheme(path string) string {
8+
return strings.TrimPrefix(path, "unix://")
9+
}

pkg/desktop/socket/dial_unix.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//go:build !windows
2+
3+
package socket
4+
5+
import (
6+
"net"
7+
)
8+
9+
// DialUnix is a simple wrapper for `net.Dial("unix")`.
10+
func DialUnix(path string) (net.Conn, error) {
11+
return net.DialUnix("unix", nil, &net.UnixAddr{Name: stripUnixScheme(path), Net: "unix"})
12+
}

pkg/desktop/socket/dial_windows.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package socket
2+
3+
import (
4+
"context"
5+
"net"
6+
"strings"
7+
"time"
8+
9+
"github.com/Microsoft/go-winio"
10+
)
11+
12+
// DialUnix is a simple wrapper for `winio.DialPipe(path, 10s)`.
13+
// It provides API compatibility for named pipes with the Unix domain socket API.
14+
func DialUnix(path string) (net.Conn, error) {
15+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
16+
defer cancel()
17+
18+
if strings.HasPrefix(path, "unix://") {
19+
// windows supports AF_UNIX
20+
d := &net.Dialer{}
21+
return d.DialContext(ctx, "unix", stripUnixScheme(path))
22+
}
23+
return winio.DialPipeContext(ctx, path)
24+
}

pkg/desktop/sockets_darwin.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ func getDockerDesktopPaths() (DockerDesktopPaths, error) {
1515

1616
return DockerDesktopPaths{
1717
BackendSocket: filepath.Join(data, "backend.sock"),
18+
ProxySocket: filepath.Join(data, "httpproxy.sock"),
1819
}, nil
1920
}

pkg/desktop/sockets_linux.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ func getDockerDesktopPaths() (DockerDesktopPaths, error) {
1212
// Inside LinuxKit
1313
return DockerDesktopPaths{
1414
BackendSocket: "/run/host-services/backend.sock",
15+
ProxySocket: "/run/host-services/httpproxy.sock",
1516
}, nil
1617
}
1718

pkg/desktop/sockets_windows.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ func getDockerDesktopPaths() (DockerDesktopPaths, error) {
1313

1414
return DockerDesktopPaths{
1515
BackendSocket: `\\.\pipe\dockerBackendApiServer`,
16+
ProxySocket: `\\.\pipe\dockerHTTPProxy`,
1617
}, nil
1718
}

pkg/httpclient/client.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package httpclient
22

33
import (
4+
"context"
45
"fmt"
56
"maps"
7+
"net"
68
"net/http"
79
"net/url"
810
"runtime"
911

12+
"github.com/docker/docker-agent/pkg/desktop"
13+
socket "github.com/docker/docker-agent/pkg/desktop/socket"
1014
"github.com/docker/docker-agent/pkg/version"
1115
)
1216

@@ -95,13 +99,25 @@ func WithQuery(query url.Values) Opt {
9599
}
96100
}
97101

98-
// newTransport returns an HTTP transport with automatic gzip compression disabled.
102+
// newTransport returns an HTTP transport with automatic gzip compression disabled and using Docker Desktop proxy if available.
99103
func newTransport() http.RoundTripper {
100104
t, ok := http.DefaultTransport.(*http.Transport)
101105
if !ok {
102106
return http.DefaultTransport
103107
}
104108
transport := t.Clone()
109+
110+
if desktop.IsDockerDesktopRunning(context.Background()) {
111+
// Route all traffic through Docker Desktop's HTTP proxy socket
112+
// Set a dummy proxy URL - the actual connection happens via DialContext
113+
transport.Proxy = http.ProxyURL(&url.URL{
114+
Scheme: "http",
115+
})
116+
// Override the dialer to connect to the Unix socket for the proxy
117+
transport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
118+
return socket.DialUnix(desktop.Paths().ProxySocket)
119+
}
120+
}
105121
transport.DisableCompression = true
106122
return transport
107123
}

0 commit comments

Comments
 (0)