diff --git a/api.go b/api.go index 2be209438f..8984d00cd9 100644 --- a/api.go +++ b/api.go @@ -34,6 +34,8 @@ func parseForm(r *http.Request) error { func httpError(w http.ResponseWriter, err error) { if strings.HasPrefix(err.Error(), "No such") { http.Error(w, err.Error(), http.StatusNotFound) + } else if strings.HasPrefix(err.Error(), "Bad parameter") { + http.Error(w, err.Error(), http.StatusBadRequest) } else { http.Error(w, err.Error(), http.StatusInternalServerError) } @@ -44,6 +46,16 @@ func writeJson(w http.ResponseWriter, b []byte) { w.Write(b) } +func getBoolParam(value string) (bool, error) { + if value == "1" || strings.ToLower(value) == "true" { + return true, nil + } + if value == "" || value == "0" || strings.ToLower(value) == "false" { + return false, nil + } + return false, fmt.Errorf("Bad parameter") +} + func getAuth(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error { b, err := json.Marshal(srv.registry.GetAuthConfig()) if err != nil { @@ -122,7 +134,10 @@ func getImagesJson(srv *Server, w http.ResponseWriter, r *http.Request, vars map return err } - all := r.Form.Get("all") == "1" + all, err := getBoolParam(r.Form.Get("all")) + if err != nil { + return err + } filter := r.Form.Get("filter") outs, err := srv.Images(all, filter) @@ -192,7 +207,10 @@ func getContainersPs(srv *Server, w http.ResponseWriter, r *http.Request, vars m if err := parseForm(r); err != nil { return err } - all := r.Form.Get("all") == "1" + all, err := getBoolParam(r.Form.Get("all")) + if err != nil { + return err + } since := r.Form.Get("since") before := r.Form.Get("before") n, err := strconv.Atoi(r.Form.Get("limit")) @@ -219,7 +237,10 @@ func postImagesTag(srv *Server, w http.ResponseWriter, r *http.Request, vars map return fmt.Errorf("Missing parameter") } name := vars["name"] - force := r.Form.Get("force") == "1" + force, err := getBoolParam(r.Form.Get("force")) + if err != nil { + return err + } if err := srv.ContainerTag(name, repo, tag, force); err != nil { return err @@ -419,7 +440,10 @@ func deleteContainers(srv *Server, w http.ResponseWriter, r *http.Request, vars return fmt.Errorf("Missing parameter") } name := vars["name"] - removeVolume := r.Form.Get("v") == "1" + removeVolume, err := getBoolParam(r.Form.Get("v")) + if err != nil { + return err + } if err := srv.ContainerDestroy(name, removeVolume); err != nil { return err @@ -494,11 +518,27 @@ func postContainersAttach(srv *Server, w http.ResponseWriter, r *http.Request, v if err := parseForm(r); err != nil { return err } - logs := r.Form.Get("logs") == "1" - stream := r.Form.Get("stream") == "1" - stdin := r.Form.Get("stdin") == "1" - stdout := r.Form.Get("stdout") == "1" - stderr := r.Form.Get("stderr") == "1" + logs, err := getBoolParam(r.Form.Get("logs")) + if err != nil { + return err + } + stream, err := getBoolParam(r.Form.Get("stream")) + if err != nil { + return err + } + stdin, err := getBoolParam(r.Form.Get("stdin")) + if err != nil { + return err + } + stdout, err := getBoolParam(r.Form.Get("stdout")) + if err != nil { + return err + } + stderr, err := getBoolParam(r.Form.Get("stderr")) + if err != nil { + return err + } + if vars == nil { return fmt.Errorf("Missing parameter") } diff --git a/api_test.go b/api_test.go index 219c39a18f..07ecc6d0bf 100644 --- a/api_test.go +++ b/api_test.go @@ -149,7 +149,7 @@ func TestGetImagesJson(t *testing.T) { r2 := httptest.NewRecorder() // all=1 - req2, err := http.NewRequest("GET", "/images/json?all=1", nil) + req2, err := http.NewRequest("GET", "/images/json?all=true", nil) if err != nil { t.Fatal(err) } @@ -191,6 +191,24 @@ func TestGetImagesJson(t *testing.T) { if len(images3) != 0 { t.Errorf("Excepted 1 image, %d found", len(images3)) } + + r4 := httptest.NewRecorder() + + // all=foobar + req4, err := http.NewRequest("GET", "/images/json?all=foobar", nil) + if err != nil { + t.Fatal(err) + } + + err = getImagesJson(srv, r4, req4, nil) + if err == nil { + t.Fatalf("Error expected, received none") + } + + httpError(r4, err) + if r4.Code != http.StatusBadRequest { + t.Fatalf("%d Bad Request expected, received %d\n", http.StatusBadRequest, r4.Code) + } } func TestGetImagesViz(t *testing.T) { diff --git a/docs/sources/api/docker_remote_api.rst b/docs/sources/api/docker_remote_api.rst index b29fd65d02..03f1d4b9cf 100644 --- a/docs/sources/api/docker_remote_api.rst +++ b/docs/sources/api/docker_remote_api.rst @@ -68,11 +68,12 @@ List containers } ] - :query all: 1 or 0, Show all containers. Only running containers are shown by default + :query all: 1/True/true or 0/False/false, Show all containers. Only running containers are shown by default :query limit: Show ``limit`` last created containers, include non-running ones. :query since: Show only containers created since Id, include non-running ones. :query before: Show only containers created before Id, include non-running ones. :statuscode 200: no error + :statuscode 400: bad parameter :statuscode 500: server error @@ -389,12 +390,13 @@ Attach to a container {{ STREAM }} - :query logs: 1 or 0, return logs. Default 0 - :query stream: 1 or 0, return stream. Default 0 - :query stdin: 1 or 0, if stream=1, attach to stdin. Default 0 - :query stdout: 1 or 0, if logs=1, return stdout log, if stream=1, attach to stdout. Default 0 - :query stderr: 1 or 0, if logs=1, return stderr log, if stream=1, attach to stderr. Default 0 + :query logs: 1/True/true or 0/False/false, return logs. Default false + :query stream: 1/True/true or 0/False/false, return stream. Default false + :query stdin: 1/True/true or 0/False/false, if stream=true, attach to stdin. Default false + :query stdout: 1/True/true or 0/False/false, if logs=true, return stdout log, if stream=true, attach to stdout. Default false + :query stderr: 1/True/true or 0/False/false, if logs=true, return stderr log, if stream=true, attach to stderr. Default false :statuscode 200: no error + :statuscode 400: bad parameter :statuscode 404: no such container :statuscode 500: server error @@ -445,8 +447,9 @@ Remove a container HTTP/1.1 204 OK - :query v: 1 or 0, Remove the volumes associated to the container. Default 0 + :query v: 1/True/true or 0/False/false, Remove the volumes associated to the container. Default false :statuscode 204: no error + :statuscode 400: bad parameter :statuscode 404: no such container :statuscode 500: server error @@ -521,8 +524,9 @@ List Images base [style=invisible] } - :query all: 1 or 0, Show all containers. Only running containers are shown by default + :query all: 1/True/true or 0/False/false, Show all containers. Only running containers are shown by default :statuscode 200: no error + :statuscode 400: bad parameter :statuscode 500: server error @@ -720,8 +724,9 @@ Tag an image into a repository HTTP/1.1 200 OK :query repo: The repository to tag in - :query force: 1 or 0, default 0 + :query force: 1/True/true or 0/False/false, default false :statuscode 200: no error + :statuscode 400: bad parameter :statuscode 404: no such image :statuscode 500: server error