瀏覽代碼

Fix the create API when fromSrc has a bad URL

When sending a bad URL in the fromSrc parameter using cURL
the response will have status code 200 while it should have 404
or 500 (depends on the error).

This commit addresses this problem in the following ways:
 * Before, `src` was parsed using url.Parse and if the
   returned `url.Scheme` was empty it was set to 'http'
   and `url.Host` was set to `src`.
   This is bad because if `src` was 'web.com/tars/image1.tar'
   The `url.String()` returns 'web.com%2Ftars%2Fimage1.tar`
   which will cause the daemon to fail downloading the file
 * Before writing the "Downloading" message, the image
   is attempted to be downloaded and if there is no error
   the "Downloading" message is sent.

Signed-off-by: Boaz Shuster <ripcurld.github@gmail.com>
Boaz Shuster 8 年之前
父節點
當前提交
e050f1760d
共有 2 個文件被更改,包括 29 次插入6 次删除
  1. 6 6
      daemon/import.go
  2. 23 0
      integration-cli/docker_api_images_test.go

+ 6 - 6
daemon/import.go

@@ -6,6 +6,7 @@ import (
 	"net/http"
 	"net/url"
 	"runtime"
+	"strings"
 	"time"
 
 	"github.com/docker/distribution/reference"
@@ -59,20 +60,19 @@ func (daemon *Daemon) ImportImage(src string, repository, tag string, msg string
 		rc = inConfig
 	} else {
 		inConfig.Close()
+		if len(strings.Split(src, "://")) == 1 {
+			src = "http://" + src
+		}
 		u, err := url.Parse(src)
 		if err != nil {
 			return err
 		}
-		if u.Scheme == "" {
-			u.Scheme = "http"
-			u.Host = src
-			u.Path = ""
-		}
-		outStream.Write(sf.FormatStatus("", "Downloading from %s", u))
+
 		resp, err = httputils.Download(u.String())
 		if err != nil {
 			return err
 		}
+		outStream.Write(sf.FormatStatus("", "Downloading from %s", u))
 		progressOutput := sf.NewProgressOutput(outStream, true)
 		rc = progress.NewProgressReader(resp.Body, progressOutput, resp.ContentLength, "", "Importing")
 	}

+ 23 - 0
integration-cli/docker_api_images_test.go

@@ -115,6 +115,29 @@ func (s *DockerSuite) TestAPIImagesHistory(c *check.C) {
 	c.Assert(historydata[0].Tags[0], checker.Equals, "test-api-images-history:latest")
 }
 
+func (s *DockerSuite) TestAPIImagesImportBadSrc(c *check.C) {
+	testRequires(c, Network)
+
+	tt := []struct {
+		statusExp int
+		fromSrc   string
+	}{
+		{http.StatusNotFound, "http://example.com/nofile.tar"},
+		{http.StatusNotFound, "example.com/nofile.tar"},
+		{http.StatusNotFound, "example.com%2Fdata%2Ffile.tar"},
+		{http.StatusInternalServerError, "%2Fdata%2Ffile.tar"},
+	}
+
+	for _, te := range tt {
+		res, b, err := request.SockRequestRaw("POST", strings.Join([]string{"/images/create?fromSrc=", te.fromSrc}, ""), nil, "application/json", daemonHost())
+		c.Assert(err, check.IsNil)
+		b.Close()
+		c.Assert(res.StatusCode, checker.Equals, te.statusExp)
+		c.Assert(res.Header.Get("Content-Type"), checker.Equals, "application/json")
+	}
+
+}
+
 // #14846
 func (s *DockerSuite) TestAPIImagesSearchJSONContentType(c *check.C) {
 	testRequires(c, Network)