Fix HTTP status-code when loading invalid tar#34425
Fix HTTP status-code when loading invalid tar#34425thaJeztah wants to merge 1 commit intomoby:masterfrom
Conversation
|
ping @cpuguy83 could you have a look if this direction is ok or not? |
cpuguy83
left a comment
There was a problem hiding this comment.
Importing HTTP in the backend is not what we want.
In the attach code we pass a function to get the write streams rather than passing the actual writers, which allows the backend to return early due to an error without having sent a 200 response header already.
api/types/backend/backend.go
Outdated
There was a problem hiding this comment.
I ended up changing it due to
Lines 41 to 47 in 22472c8
(also a reason I opened this for discussion)
6a24b31 to
0004b18
Compare
0004b18 to
1f59db5
Compare
|
ping @cpuguy83 @tonistiigi PTAL |
1f59db5 to
99e7612
Compare
There was a problem hiding this comment.
Does this work? Would LoadImage have already written to the stream and thus already have sent a 200 OK?
We could check output.Flushed(), although I would pretty much expect LoadImage to handle all things on the stream by this point.
There was a problem hiding this comment.
OK, can we gate this with a check for !output.Flushed()?
Testing other situations: valid tar, but wrong format (export <--> load) With this PR: $ cat exported.tar | curl -v --unix-socket /var/run/docker.sock -H "Content-Type: application/x-tar" --data-binary @- -X POST http://localhost/v1.29/images/load
* Trying /var/run/docker.sock...
* Connected to localhost (/var/run/docker.sock) port 80 (#0)
> POST /v1.29/images/load HTTP/1.1
> Host: localhost
> User-Agent: curl/7.52.1
> Accept: */*
> Content-Type: application/x-tar
> Content-Length: 1359872
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
* We are completely uploaded and fine
< HTTP/1.1 400 Bad Request
< Api-Version: 1.36
< Content-Type: application/json
< Docker-Experimental: false
< Ostype: linux
< Server: Docker/dev (linux)
< Date: Fri, 19 Jan 2018 16:25:33 GMT
< Transfer-Encoding: chunked
<
Api-Version: 1.36
Content-Type: application/json
Docker-Experimental: false
Ostype: linux
Server: Docker/dev (linux)
{"errorDetail":{"message":"open /var/lib/docker/tmp/docker-import-641132035/bin/json: no such file or directory"},"error":"open /var/lib/docker/tmp/docker-import-641132035/bin/json: no such file or directory"}
* Curl_http_done: called premature == 0
* Connection #0 to host localhost left intactDoing the same on Docker 18.01: $ cat exported.tar | curl -v --unix-socket /var/run/docker.sock -H "Content-Type: application/x-tar" --data-binary @- -X POST http://localhost/v1.29/images/load
* Trying /var/run/docker.sock...
* Connected to localhost (/var/run/docker.sock) port 80 (#0)
> POST /v1.29/images/load HTTP/1.1
> Host: localhost
> User-Agent: curl/7.57.0
> Accept: */*
> Content-Type: application/x-tar
> Content-Length: 1359872
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
* We are completely uploaded and fine
< HTTP/1.1 200 OK
< Api-Version: 1.35
< Content-Type: application/json
< Docker-Experimental: false
< Ostype: linux
< Server: Docker/18.01.0-ce (linux)
< Date: Fri, 19 Jan 2018 16:43:37 GMT
< Transfer-Encoding: chunked
<
{"errorDetail":{"message":"open /var/lib/docker/tmp/docker-import-640654783/bin/json: no such file or directory"},"error":"open /var/lib/docker/tmp/docker-import-640654783/bin/json: no such file or directory"}
* Connection #0 to host localhost left intact |
image/tarexport/load.go
Outdated
99e7612 to
fa8fbbe
Compare
|
ping @cpuguy83 updated 👍 |
fa8fbbe to
a09c1c5
Compare
|
For some reason, the CLI doesn't print the error message with this change; only difference between before/after is the status code: diff --git a/before b/after
index 0493ca6..149e900 100644
--- a/before
+++ b/after
@@ -1,13 +1,14 @@
* upload completely sent off: 28 out of 28 bytes
-< HTTP/1.1 200 OK
+< HTTP/1.1 400 Bad Request
< Api-Version: 1.36
< Content-Type: application/json
-< Date: Fri, 16 Feb 2018 16:51:16 GMT
-< Docker-Experimental: true
+< Docker-Experimental: false
< Ostype: linux
-< Server: Docker/18.02.0-ce (linux)
+< Server: Docker/dev (linux)
+< Date: Fri, 16 Feb 2018 16:50:38 GMT
< Transfer-Encoding: chunked
<
{"errorDetail":{"message":"Error processing tar file(exit status 1): unexpected EOF"},"error":"Error processing tar file(exit status 1): unexpected EOF"}
+* Curl_http_done: called premature == 0
* Connection #0 to host localhost left intactBut with this change, the actual error is not printed: echo "fooasdsddsdas" | docker load
Error response from daemon: Wondering if it's an issue in the CLI and it stops early on a 400 status? |
Is it safer to keep the current behavior for ensuring compatibility? |
a09c1c5 to
924450d
Compare
|
@thaJeztah CI looks failing to: |
2cacd95 to
a06ba87
Compare
Before this change:
echo "hello world, I am not a tar" | curl -v --unix-socket /var/run/docker.sock -H "Content-Type: application/x-tar" --data-binary @- -X POST http://localhost/v1.29/images/load
* Trying /var/run/docker.sock...
* Connected to localhost (/Users/sebastiaan/Library/Containers/com.dock) port 80 (#0)
> POST /v1.29/images/load HTTP/1.1
> Host: localhost
> User-Agent: curl/7.51.0
> Accept: */*
> Content-Type: application/x-tar
> Content-Length: 28
>
* upload completely sent off: 28 out of 28 bytes
< HTTP/1.1 200 OK
< Api-Version: 1.31
< Content-Type: application/json
< Date: Mon, 07 Aug 2017 15:11:35 GMT
< Docker-Experimental: true
< Ostype: linux
< Server: Docker/17.07.0-ce-rc1 (linux)
< Transfer-Encoding: chunked
<
{"errorDetail":{"message":"Error processing tar file(exit status 1): unexpected EOF"},"error":"Error processing tar file(exit status 1): unexpected EOF"}
* Curl_http_done: called premature == 0
* Connection #0 to host localhost left intact
After this change:
echo "hello world, I am not a tar" | curl -v --unix-socket /var/run/docker.sock -H "Content-Type: application/x-tar" --data-binary @- http://localhost/v1.29/images/load
* Trying /var/run/docker.sock...
* Connected to localhost (/var/run/docker.sock) port 80 (#0)
> POST /v1.29/images/load HTTP/1.1
> Host: localhost
> User-Agent: curl/7.55.0
> Accept: */*
> Content-Type: application/x-tar
> Content-Length: 28
>
* upload completely sent off: 28 out of 28 bytes
< HTTP/1.1 400 Bad Request
< Api-Version: 1.32
< Content-Type: application/json
< Docker-Experimental: false
< Ostype: linux
< Server: Docker/17.06.0-dev (linux)
< Date: Thu, 17 Aug 2017 11:14:55 GMT
< Transfer-Encoding: chunked
<
Api-Version: 1.32
Content-Type: application/json
Docker-Experimental: false
Ostype: linux
Server: Docker/17.06.0-dev (linux)
{"errorDetail":{"message":"Error processing tar file(exit status 1): unexpected EOF"},"error":"Error processing tar file(exit status 1): unexpected EOF"}
Attempting to import an "export" image using "docker load":
docker export somecontainer > foo.tar
cat foo.tar | curl -v --unix-socket /var/run/docker.sock -H "Content-Type: application/x-tar" --data-binary @- http://localhost/v1.29/images/load
* Trying /var/run/docker.sock...
* Connected to localhost (/var/run/docker.sock) port 80 (#0)
> POST /v1.29/images/load HTTP/1.1
> Host: localhost
> User-Agent: curl/7.55.0
> Accept: */*
> Content-Type: application/x-tar
> Content-Length: 5910528
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
* We are completely uploaded and fine
< HTTP/1.1 400 Bad Request
< Api-Version: 1.32
< Content-Type: application/json
< Docker-Experimental: false
< Ostype: linux
< Server: Docker/17.06.0-dev (linux)
< Date: Thu, 17 Aug 2017 12:34:02 GMT
< Transfer-Encoding: chunked
<
Api-Version: 1.32
Content-Type: application/json
Docker-Experimental: false
Ostype: linux
Server: Docker/17.06.0-dev (linux)
{"errorDetail":{"message":"open /var/lib/docker/tmp/docker-import-708284929/bin/json: no such file or directory"},"error":"open /var/lib/docker/tmp/docker-import-708284929/bin/json: no such file or directory"}
Signed-off-by: Sebastiaan van Stijn <[email protected]>
a06ba87 to
7518ec9
Compare
|
Hmm.. good call; looks like we have some fixing to do with the ppc64le and s390x builds (they're disabled by default now, but were started on this) ppc64le s390x |
fixes #34416
Opening for discussion, because this changes the
WriteFlusherinterface, which is used in various places; also the error-code may need to be more specific based on the actual error.Before this change:
After this change: