Ver Fonte

Merge pull request #9652 from yadutaf/master

Set HTTP upgrade headers when hijacking connection
Alexander Morozov há 10 anos atrás
pai
commit
f538e4be6b

+ 2 - 0
api/client/hijack.go

@@ -135,6 +135,8 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in io.Rea
 	}
 	}
 	req.Header.Set("User-Agent", "Docker-Client/"+dockerversion.VERSION)
 	req.Header.Set("User-Agent", "Docker-Client/"+dockerversion.VERSION)
 	req.Header.Set("Content-Type", "plain/text")
 	req.Header.Set("Content-Type", "plain/text")
+	req.Header.Set("Connection", "Upgrade")
+	req.Header.Set("Upgrade", "tcp")
 	req.Host = cli.addr
 	req.Host = cli.addr
 
 
 	dial, err := cli.dial()
 	dial, err := cli.dial()

+ 11 - 2
api/server/server.go

@@ -887,7 +887,11 @@ func postContainersAttach(eng *engine.Engine, version version.Version, w http.Re
 
 
 	var errStream io.Writer
 	var errStream io.Writer
 
 
-	fmt.Fprintf(outStream, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n")
+	if _, ok := r.Header["Upgrade"]; ok {
+		fmt.Fprintf(outStream, "HTTP/1.1 101 UPGRADED\r\nContent-Type: application/vnd.docker.raw-stream\r\nConnection: Upgrade\r\nUpgrade: tcp\r\n\r\n")
+	} else {
+		fmt.Fprintf(outStream, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n")
+	}
 
 
 	if c.GetSubEnv("Config") != nil && !c.GetSubEnv("Config").GetBool("Tty") && version.GreaterThanOrEqualTo("1.6") {
 	if c.GetSubEnv("Config") != nil && !c.GetSubEnv("Config").GetBool("Tty") && version.GreaterThanOrEqualTo("1.6") {
 		errStream = stdcopy.NewStdWriter(outStream, stdcopy.Stderr)
 		errStream = stdcopy.NewStdWriter(outStream, stdcopy.Stderr)
@@ -1137,7 +1141,12 @@ func postContainerExecStart(eng *engine.Engine, version version.Version, w http.
 
 
 		var errStream io.Writer
 		var errStream io.Writer
 
 
-		fmt.Fprintf(outStream, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n")
+		if _, ok := r.Header["Upgrade"]; ok {
+			fmt.Fprintf(outStream, "HTTP/1.1 101 UPGRADED\r\nContent-Type: application/vnd.docker.raw-stream\r\nConnection: Upgrade\r\nUpgrade: tcp\r\n\r\n")
+		} else {
+			fmt.Fprintf(outStream, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n")
+		}
+
 		if !job.GetenvBool("Tty") && version.GreaterThanOrEqualTo("1.6") {
 		if !job.GetenvBool("Tty") && version.GreaterThanOrEqualTo("1.6") {
 			errStream = stdcopy.NewStdWriter(outStream, stdcopy.Stderr)
 			errStream = stdcopy.NewStdWriter(outStream, stdcopy.Stderr)
 			outStream = stdcopy.NewStdWriter(outStream, stdcopy.Stdout)
 			outStream = stdcopy.NewStdWriter(outStream, stdcopy.Stdout)

+ 22 - 5
docs/sources/reference/api/docker_remote_api_v1.16.md

@@ -393,8 +393,10 @@ Get stdout and stderr logs from the container ``id``
 
 
 **Example response**:
 **Example response**:
 
 
-       HTTP/1.1 200 OK
+       HTTP/1.1 101 UPGRADED
        Content-Type: application/vnd.docker.raw-stream
        Content-Type: application/vnd.docker.raw-stream
+       Connection: Upgrade
+       Upgrade: tcp
 
 
        {{ STREAM }}
        {{ STREAM }}
 
 
@@ -409,7 +411,8 @@ Query Parameters:
 
 
 Status Codes:
 Status Codes:
 
 
--   **200** – no error
+-   **101** – no error, hints proxy about hijacking
+-   **200** – no error, no upgrade header found
 -   **404** – no such container
 -   **404** – no such container
 -   **500** – server error
 -   **500** – server error
 
 
@@ -644,8 +647,10 @@ Attach to the container `id`
 
 
 **Example response**:
 **Example response**:
 
 
-        HTTP/1.1 200 OK
+        HTTP/1.1 101 UPGRADED
         Content-Type: application/vnd.docker.raw-stream
         Content-Type: application/vnd.docker.raw-stream
+        Connection: Upgrade
+        Upgrade: tcp
 
 
         {{ STREAM }}
         {{ STREAM }}
 
 
@@ -663,7 +668,8 @@ Query Parameters:
 
 
 Status Codes:
 Status Codes:
 
 
--   **200** – no error
+-   **101** – no error, hints proxy about hijacking
+-   **200** – no error, no upgrade header found
 -   **400** – bad parameter
 -   **400** – bad parameter
 -   **404** – no such container
 -   **404** – no such container
 -   **500** – server error
 -   **500** – server error
@@ -1746,7 +1752,18 @@ As an example, the `docker run` command line makes the following API calls:
 ## 3.2 Hijacking
 ## 3.2 Hijacking
 
 
 In this version of the API, /attach, uses hijacking to transport stdin,
 In this version of the API, /attach, uses hijacking to transport stdin,
-stdout and stderr on the same socket. This might change in the future.
+stdout and stderr on the same socket.
+
+To hint potential proxies about connection hijacking, Docker client sends
+connection upgrade headers similarly to websocket.
+
+    Upgrade: tcp
+    Connection: Upgrade
+
+When Docker daemon detects the `Upgrade` header, it will switch its status code
+from **200 OK** to **101 UPGRADED** and resend the same headers.
+
+This might change in the future.
 
 
 ## 3.3 CORS Requests
 ## 3.3 CORS Requests