Browse Source

Merge pull request #14304 from vieux/http_proxy_support

add support for base path in docker cli -H
Jessie Frazelle 10 years ago
parent
commit
4e9280ffdb
6 changed files with 32 additions and 9 deletions
  1. 12 0
      api/client/cli.go
  2. 1 1
      api/client/hijack.go
  3. 1 1
      api/client/utils.go
  4. 3 1
      docs/articles/basics.md
  5. 7 2
      pkg/parsers/parsers.go
  6. 8 4
      pkg/parsers/parsers_test.go

+ 12 - 0
api/client/cli.go

@@ -7,6 +7,7 @@ import (
 	"fmt"
 	"io"
 	"net/http"
+	"net/url"
 	"reflect"
 	"strings"
 	"text/template"
@@ -24,6 +25,8 @@ type DockerCli struct {
 	proto string
 	// addr holds the client address.
 	addr string
+	// basePath holds the path to prepend to the requests
+	basePath string
 
 	// configFile has the client configuration file
 	configFile *cliconfig.ConfigFile
@@ -187,6 +190,7 @@ func NewDockerCli(in io.ReadCloser, out, err io.Writer, keyFile string, proto, a
 		isTerminalIn  = false
 		isTerminalOut = false
 		scheme        = "http"
+		basePath      = ""
 	)
 
 	if tlsConfig != nil {
@@ -215,9 +219,17 @@ func NewDockerCli(in io.ReadCloser, out, err io.Writer, keyFile string, proto, a
 		fmt.Fprintf(err, "WARNING: Error loading config file:%v\n", e)
 	}
 
+	if proto == "tcp" {
+		// error is checked in pkg/parsers already
+		parsed, _ := url.Parse("tcp://" + addr)
+		addr = parsed.Host
+		basePath = parsed.Path
+	}
+
 	return &DockerCli{
 		proto:         proto,
 		addr:          addr,
+		basePath:      basePath,
 		configFile:    configFile,
 		in:            in,
 		out:           out,

+ 1 - 1
api/client/hijack.go

@@ -138,7 +138,7 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in io.Rea
 	if err != nil {
 		return err
 	}
-	req, err := http.NewRequest(method, fmt.Sprintf("/v%s%s", api.Version, path), params)
+	req, err := http.NewRequest(method, fmt.Sprintf("%s/v%s%s", cli.basePath, api.Version, path), params)
 	if err != nil {
 		return err
 	}

+ 1 - 1
api/client/utils.go

@@ -65,7 +65,7 @@ func (cli *DockerCli) clientRequest(method, path string, in io.Reader, headers m
 	if expectedPayload && in == nil {
 		in = bytes.NewReader([]byte{})
 	}
-	req, err := http.NewRequest(method, fmt.Sprintf("/v%s%s", api.Version, path), in)
+	req, err := http.NewRequest(method, fmt.Sprintf("%s/v%s%s", cli.basePath, api.Version, path), in)
 	if err != nil {
 		return serverResp, err
 	}

+ 3 - 1
docs/articles/basics.md

@@ -83,12 +83,14 @@ Similarly, the Docker client can use `-H` to connect to a custom port.
 
 `-H` accepts host and port assignment in the following format:
 
-    tcp://[host][:port] or unix://path
+    tcp://[host][:port][path] or unix://path
 
 For example:
 
 -   `tcp://host:2375` -> TCP connection on
     host:2375
+-   `tcp://host:2375/path` -> TCP connection on
+    host:2375 and prepend path to all requests
 -   `unix://path/to/socket` -> Unix socket located
     at `path/to/socket`
 

+ 7 - 2
pkg/parsers/parsers.go

@@ -2,6 +2,7 @@ package parsers
 
 import (
 	"fmt"
+	"net/url"
 	"runtime"
 	"strconv"
 	"strings"
@@ -52,7 +53,11 @@ func ParseTCPAddr(addr string, defaultAddr string) (string, error) {
 		return "", fmt.Errorf("Invalid proto, expected tcp: %s", addr)
 	}
 
-	hostParts := strings.Split(addr, ":")
+	u, err := url.Parse("tcp://" + addr)
+	if err != nil {
+		return "", err
+	}
+	hostParts := strings.Split(u.Host, ":")
 	if len(hostParts) != 2 {
 		return "", fmt.Errorf("Invalid bind address format: %s", addr)
 	}
@@ -65,7 +70,7 @@ func ParseTCPAddr(addr string, defaultAddr string) (string, error) {
 	if err != nil && p == 0 {
 		return "", fmt.Errorf("Invalid bind address format: %s", addr)
 	}
-	return fmt.Sprintf("tcp://%s:%d", host, p), nil
+	return fmt.Sprintf("tcp://%s:%d%s", host, p, u.Path), nil
 }
 
 // Get a repos name and returns the right reposName + tag|digest

+ 8 - 4
pkg/parsers/parsers_test.go

@@ -14,14 +14,18 @@ func TestParseHost(t *testing.T) {
 		"0.0.0.0":              "Invalid bind address format: 0.0.0.0",
 		"tcp://":               "Invalid proto, expected tcp: ",
 		"tcp:a.b.c.d":          "Invalid bind address format: tcp:a.b.c.d",
+		"tcp:a.b.c.d/path":     "Invalid bind address format: tcp:a.b.c.d/path",
 		"udp://127.0.0.1":      "Invalid bind address format: udp://127.0.0.1",
 		"udp://127.0.0.1:2375": "Invalid bind address format: udp://127.0.0.1:2375",
 	}
 	valids := map[string]string{
-		"0.0.0.1:5555": "tcp://0.0.0.1:5555",
-		":6666":        "tcp://127.0.0.1:6666",
-		"tcp://:7777":  "tcp://127.0.0.1:7777",
-		"":             "unix:///var/run/docker.sock",
+		"0.0.0.1:5555":      "tcp://0.0.0.1:5555",
+		"0.0.0.1:5555/path": "tcp://0.0.0.1:5555/path",
+		":6666":             "tcp://127.0.0.1:6666",
+		":6666/path":        "tcp://127.0.0.1:6666/path",
+		"tcp://:7777":       "tcp://127.0.0.1:7777",
+		"tcp://:7777/path":  "tcp://127.0.0.1:7777/path",
+		"":                  "unix:///var/run/docker.sock",
 		"unix:///run/docker.sock": "unix:///run/docker.sock",
 		"unix://":                 "unix:///var/run/docker.sock",
 		"fd://":                   "fd://",