mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Add checks for app/json - issue #2515
Signed-off-by: Doug Davis <dug@us.ibm.com>
This commit is contained in:
parent
4547b6d529
commit
e2b8d4bd4a
2 changed files with 84 additions and 8 deletions
|
@ -51,6 +51,24 @@ func hijackServer(w http.ResponseWriter) (io.ReadCloser, io.Writer, error) {
|
||||||
return conn, conn, nil
|
return conn, conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check to make sure request's Content-Type is application/json
|
||||||
|
func checkForJson(r *http.Request) error {
|
||||||
|
ct := r.Header.Get("Content-Type")
|
||||||
|
|
||||||
|
// No Content-Type header is ok as long as there's no Body
|
||||||
|
if ct == "" {
|
||||||
|
if r.Body == nil || r.ContentLength == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise it better be json
|
||||||
|
if api.MatchesContentType(ct, "application/json") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Content-Type specified (%s) must be 'application/json'", ct)
|
||||||
|
}
|
||||||
|
|
||||||
//If we don't do this, POST method without Content-type (even with empty body) will fail
|
//If we don't do this, POST method without Content-type (even with empty body) will fail
|
||||||
func parseForm(r *http.Request) error {
|
func parseForm(r *http.Request) error {
|
||||||
if r == nil {
|
if r == nil {
|
||||||
|
@ -445,6 +463,11 @@ func postCommit(eng *engine.Engine, version version.Version, w http.ResponseWrit
|
||||||
job = eng.Job("commit", r.Form.Get("container"))
|
job = eng.Job("commit", r.Form.Get("container"))
|
||||||
stdoutBuffer = bytes.NewBuffer(nil)
|
stdoutBuffer = bytes.NewBuffer(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if err := checkForJson(r); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := config.Decode(r.Body); err != nil {
|
if err := config.Decode(r.Body); err != nil {
|
||||||
log.Errorf("%s", err)
|
log.Errorf("%s", err)
|
||||||
}
|
}
|
||||||
|
@ -651,6 +674,11 @@ func postContainersCreate(eng *engine.Engine, version version.Version, w http.Re
|
||||||
stdoutBuffer = bytes.NewBuffer(nil)
|
stdoutBuffer = bytes.NewBuffer(nil)
|
||||||
warnings = bytes.NewBuffer(nil)
|
warnings = bytes.NewBuffer(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if err := checkForJson(r); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := job.DecodeEnv(r.Body); err != nil {
|
if err := job.DecodeEnv(r.Body); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -734,8 +762,8 @@ func postContainersStart(eng *engine.Engine, version version.Version, w http.Res
|
||||||
|
|
||||||
// allow a nil body for backwards compatibility
|
// allow a nil body for backwards compatibility
|
||||||
if r.Body != nil && r.ContentLength > 0 {
|
if r.Body != nil && r.ContentLength > 0 {
|
||||||
if !api.MatchesContentType(r.Header.Get("Content-Type"), "application/json") {
|
if err := checkForJson(r); err != nil {
|
||||||
return fmt.Errorf("Content-Type of application/json is required")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := job.DecodeEnv(r.Body); err != nil {
|
if err := job.DecodeEnv(r.Body); err != nil {
|
||||||
|
@ -1001,12 +1029,12 @@ func postContainersCopy(eng *engine.Engine, version version.Version, w http.Resp
|
||||||
|
|
||||||
var copyData engine.Env
|
var copyData engine.Env
|
||||||
|
|
||||||
if contentType := r.Header.Get("Content-Type"); api.MatchesContentType(contentType, "application/json") {
|
if err := checkForJson(r); err != nil {
|
||||||
if err := copyData.Decode(r.Body); err != nil {
|
return err
|
||||||
return err
|
}
|
||||||
}
|
|
||||||
} else {
|
if err := copyData.Decode(r.Body); err != nil {
|
||||||
return fmt.Errorf("Content-Type not supported: %s", contentType)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if copyData.Get("Resource") == "" {
|
if copyData.Get("Resource") == "" {
|
||||||
|
@ -1043,6 +1071,7 @@ func postContainerExecCreate(eng *engine.Engine, version version.Version, w http
|
||||||
job = eng.Job("execCreate", name)
|
job = eng.Job("execCreate", name)
|
||||||
stdoutBuffer = bytes.NewBuffer(nil)
|
stdoutBuffer = bytes.NewBuffer(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := job.DecodeEnv(r.Body); err != nil {
|
if err := job.DecodeEnv(r.Body); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1068,6 +1097,7 @@ func postContainerExecStart(eng *engine.Engine, version version.Version, w http.
|
||||||
job = eng.Job("execStart", name)
|
job = eng.Job("execStart", name)
|
||||||
errOut io.Writer = os.Stderr
|
errOut io.Writer = os.Stderr
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := job.DecodeEnv(r.Body); err != nil {
|
if err := job.DecodeEnv(r.Body); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -356,6 +357,8 @@ func TestPostContainersCreate(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
r := httptest.NewRecorder()
|
r := httptest.NewRecorder()
|
||||||
if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
|
if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -379,6 +382,49 @@ func TestPostContainersCreate(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPostJsonVerify(t *testing.T) {
|
||||||
|
eng := NewTestEngine(t)
|
||||||
|
defer mkDaemonFromEngine(eng, t).Nuke()
|
||||||
|
|
||||||
|
configJSON, err := json.Marshal(&runconfig.Config{
|
||||||
|
Image: unitTestImageID,
|
||||||
|
Memory: 33554432,
|
||||||
|
Cmd: []string{"touch", "/test"},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", "/containers/create", bytes.NewReader(configJSON))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
r := httptest.NewRecorder()
|
||||||
|
|
||||||
|
if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't add Content-Type header
|
||||||
|
// req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
err = server.ServeRequest(eng, api.APIVERSION, r, req)
|
||||||
|
if r.Code != http.StatusInternalServerError || !strings.Contains(((*r.Body).String()), "application/json") {
|
||||||
|
t.Fatal("Create should have failed due to no Content-Type header - got:", r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now add header but with wrong type and retest
|
||||||
|
req.Header.Set("Content-Type", "application/xml")
|
||||||
|
|
||||||
|
if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if r.Code != http.StatusInternalServerError || !strings.Contains(((*r.Body).String()), "application/json") {
|
||||||
|
t.Fatal("Create should have failed due to wrong Content-Type header - got:", r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPostContainersKill(t *testing.T) {
|
func TestPostContainersKill(t *testing.T) {
|
||||||
eng := NewTestEngine(t)
|
eng := NewTestEngine(t)
|
||||||
defer mkDaemonFromEngine(eng, t).Nuke()
|
defer mkDaemonFromEngine(eng, t).Nuke()
|
||||||
|
|
Loading…
Add table
Reference in a new issue