From 19ea19b75bebab843b06eebbe0d28feb0c3b4ab9 Mon Sep 17 00:00:00 2001
From: Will McCutchen <will@mccutch.org>
Date: Wed, 28 Jun 2017 23:47:56 -0700
Subject: [PATCH] Better handling of empty request bodies

---
 httpbin/handlers_test.go | 50 ++++++++++++++++++++++++++++------------
 httpbin/helpers.go       |  3 ++-
 2 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/httpbin/handlers_test.go b/httpbin/handlers_test.go
index 2b2decf..c341343 100644
--- a/httpbin/handlers_test.go
+++ b/httpbin/handlers_test.go
@@ -323,24 +323,44 @@ func TestHeaders(t *testing.T) {
 }
 
 func TestPost__EmptyBody(t *testing.T) {
-	r, _ := http.NewRequest("POST", "/post", nil)
-	w := httptest.NewRecorder()
-	handler.ServeHTTP(w, r)
+	var tests = []struct {
+		contentType string
+	}{
+		{""},
+		{"application/json; charset=utf-8"},
+		{"application/x-www-form-urlencoded"},
+		{"multipart/form-data; foo"},
+	}
+	for _, test := range tests {
+		t.Run("content type/"+test.contentType, func(t *testing.T) {
+			r, _ := http.NewRequest("POST", "/post", nil)
+			r.Header.Set("Content-Type", test.contentType)
+			w := httptest.NewRecorder()
+			handler.ServeHTTP(w, r)
 
-	assertStatusCode(t, w, http.StatusOK)
-	assertContentType(t, w, jsonContentType)
+			assertStatusCode(t, w, http.StatusOK)
+			assertContentType(t, w, jsonContentType)
 
-	var resp *bodyResponse
-	err := json.Unmarshal(w.Body.Bytes(), &resp)
-	if err != nil {
-		t.Fatalf("failed to unmarshal body %s from JSON: %s", w.Body, err)
-	}
+			var resp *bodyResponse
+			err := json.Unmarshal(w.Body.Bytes(), &resp)
+			if err != nil {
+				t.Fatalf("failed to unmarshal body %s from JSON: %s", w.Body, err)
+			}
 
-	if len(resp.Args) > 0 {
-		t.Fatalf("expected no query params, got %#v", resp.Args)
-	}
-	if len(resp.Form) > 0 {
-		t.Fatalf("expected no form data, got %#v", resp.Form)
+			if resp.Data != "" {
+				t.Fatalf("expected empty response data, got %#v", resp.Data)
+			}
+			if resp.JSON != nil {
+				t.Fatalf("expected nil response json, got %#v", resp.JSON)
+			}
+
+			if len(resp.Args) > 0 {
+				t.Fatalf("expected no query params, got %#v", resp.Args)
+			}
+			if len(resp.Form) > 0 {
+				t.Fatalf("expected no form data, got %#v", resp.Form)
+			}
+		})
 	}
 }
 
diff --git a/httpbin/helpers.go b/httpbin/helpers.go
index ba65116..889f40b 100644
--- a/httpbin/helpers.go
+++ b/httpbin/helpers.go
@@ -121,7 +121,8 @@ func parseBody(w http.ResponseWriter, r *http.Request, resp *bodyResponse) error
 		}
 		resp.Form = r.PostForm
 	case strings.HasPrefix(ct, "application/json"):
-		if err := json.NewDecoder(r.Body).Decode(&resp.JSON); err != nil {
+		err := json.NewDecoder(r.Body).Decode(&resp.JSON)
+		if err != nil && err != io.EOF {
 			return err
 		}
 	}
-- 
GitLab