httpProxySocketEndpoint derives Docker Desktop's HTTP proxy socket endpoint from a Docker Desktop socket endpoint in the same directory. Returns "" when the input is not a recognized form or when the derived unix socket does not exist (older DD versions or non-DD installs). On macOS/Linux: unix:///
(endpoint string)
| 61 | // On macOS/Linux: unix:///path/to/Data/docker-cli.sock → unix:///path/to/Data/httpproxy.sock |
| 62 | // On Windows: npipe://\\.\pipe\docker_cli → npipe://\\.\pipe\dockerHttpProxy |
| 63 | func httpProxySocketEndpoint(endpoint string) string { |
| 64 | if sockPath, ok := strings.CutPrefix(endpoint, "unix://"); ok { |
| 65 | proxyPath := filepath.Join(filepath.Dir(sockPath), "httpproxy.sock") |
| 66 | if _, err := os.Stat(proxyPath); err != nil { |
| 67 | return "" |
| 68 | } |
| 69 | return "unix://" + proxyPath |
| 70 | } |
| 71 | if strings.HasPrefix(endpoint, "npipe://") { |
| 72 | // Named pipes all live in the same `\\.\pipe\` namespace, so only the |
| 73 | // trailing pipe name differs. Swap it in place rather than rebuilding |
| 74 | // the endpoint string: this preserves the engine endpoint's exact |
| 75 | // prefix (Docker Desktop reports the backslash form |
| 76 | // `npipe://\\.\pipe\docker_cli`), which winio can dial. Hardcoding |
| 77 | // `npipe://./pipe/...` instead would yield the relative path |
| 78 | // `./pipe/dockerHttpProxy`, which fails with "open |
| 79 | // ./pipe/dockerHttpProxy: The system cannot find the path specified." |
| 80 | // (docker/compose#13824). LastIndexAny handles both the backslash form |
| 81 | // above and the forward-slash form `npipe:////./pipe/...`. |
| 82 | if idx := strings.LastIndexAny(endpoint, `/\`); idx >= 0 { |
| 83 | return endpoint[:idx+1] + "dockerHttpProxy" |
| 84 | } |
| 85 | return "" |
| 86 | } |
| 87 | return "" |
| 88 | } |
| 89 | |
| 90 | // ProxyTransport returns an http.RoundTripper that routes traffic through |
| 91 | // Docker Desktop's PAC-aware HTTP proxy when DD exposes the proxy socket, |