diff --git a/httpbin/handlers.go b/httpbin/handlers.go
index 4d8c7cfcb6fa2e7d47b1e958a9fc551370f25495..aef9ee4a89b90d1a7db206b182c491ce1745cba6 100644
--- a/httpbin/handlers.go
+++ b/httpbin/handlers.go
@@ -54,14 +54,14 @@ func (h *HTTPBin) Get(w http.ResponseWriter, r *http.Request) {
 		Origin:  getClientIP(r),
 		URL:     getURL(r).String(),
 	}
-	body, _ := json.Marshal(resp)
+	body, _ := jsonMarshalNoEscape(resp)
 	writeJSON(w, body, http.StatusOK)
 }
 
 // Anything returns anything that is passed to request.
 func (h *HTTPBin) Anything(w http.ResponseWriter, r *http.Request) {
 	switch r.Method {
-	case "GET", "HEAD":
+	case "HEAD":
 		h.Get(w, r)
 	default:
 		h.RequestWithBody(w, r)
@@ -83,7 +83,7 @@ func (h *HTTPBin) RequestWithBody(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	body, _ := json.Marshal(resp)
+	body, _ := jsonMarshalNoEscape(resp)
 	writeJSON(w, body, http.StatusOK)
 }
 
@@ -94,7 +94,7 @@ func (h *HTTPBin) Gzip(w http.ResponseWriter, r *http.Request) {
 		Origin:  getClientIP(r),
 		Gzipped: true,
 	}
-	body, _ := json.Marshal(resp)
+	body, _ := jsonMarshalNoEscape(resp)
 
 	buf := &bytes.Buffer{}
 	gzw := gzip.NewWriter(buf)
@@ -114,7 +114,7 @@ func (h *HTTPBin) Deflate(w http.ResponseWriter, r *http.Request) {
 		Origin:   getClientIP(r),
 		Deflated: true,
 	}
-	body, _ := json.Marshal(resp)
+	body, _ := jsonMarshalNoEscape(resp)
 
 	buf := &bytes.Buffer{}
 	w2 := zlib.NewWriter(buf)
@@ -129,7 +129,7 @@ func (h *HTTPBin) Deflate(w http.ResponseWriter, r *http.Request) {
 
 // IP echoes the IP address of the incoming request
 func (h *HTTPBin) IP(w http.ResponseWriter, r *http.Request) {
-	body, _ := json.Marshal(&ipResponse{
+	body, _ := jsonMarshalNoEscape(&ipResponse{
 		Origin: getClientIP(r),
 	})
 	writeJSON(w, body, http.StatusOK)
@@ -137,7 +137,7 @@ func (h *HTTPBin) IP(w http.ResponseWriter, r *http.Request) {
 
 // UserAgent echoes the incoming User-Agent header
 func (h *HTTPBin) UserAgent(w http.ResponseWriter, r *http.Request) {
-	body, _ := json.Marshal(&userAgentResponse{
+	body, _ := jsonMarshalNoEscape(&userAgentResponse{
 		UserAgent: r.Header.Get("User-Agent"),
 	})
 	writeJSON(w, body, http.StatusOK)
@@ -145,7 +145,7 @@ func (h *HTTPBin) UserAgent(w http.ResponseWriter, r *http.Request) {
 
 // Headers echoes the incoming request headers
 func (h *HTTPBin) Headers(w http.ResponseWriter, r *http.Request) {
-	body, _ := json.Marshal(&headersResponse{
+	body, _ := jsonMarshalNoEscape(&headersResponse{
 		Headers: getRequestHeaders(r),
 	})
 	writeJSON(w, body, http.StatusOK)
@@ -175,7 +175,7 @@ func (h *HTTPBin) Status(w http.ResponseWriter, r *http.Request) {
 			"Location": "/redirect/1",
 		},
 	}
-	notAcceptableBody, _ := json.Marshal(map[string]interface{}{
+	notAcceptableBody, _ := jsonMarshalNoEscape(map[string]interface{}{
 		"message": "Client did not request a supported media type",
 		"accept":  acceptedMediaTypes,
 	})
@@ -302,7 +302,7 @@ func (h *HTTPBin) ResponseHeaders(w http.ResponseWriter, r *http.Request) {
 			w.Header().Add(k, v)
 		}
 	}
-	body, _ := json.Marshal(args)
+	body, _ := jsonMarshalNoEscape(args)
 	if contentType := w.Header().Get("Content-Type"); contentType == "" {
 		w.Header().Set("Content-Type", jsonContentType)
 	}
@@ -400,7 +400,7 @@ func (h *HTTPBin) Cookies(w http.ResponseWriter, r *http.Request) {
 	for _, c := range r.Cookies() {
 		resp[c.Name] = c.Value
 	}
-	body, _ := json.Marshal(resp)
+	body, _ := jsonMarshalNoEscape(resp)
 	writeJSON(w, body, http.StatusOK)
 }
 
@@ -455,7 +455,7 @@ func (h *HTTPBin) BasicAuth(w http.ResponseWriter, r *http.Request) {
 		w.Header().Set("WWW-Authenticate", `Basic realm="Fake Realm"`)
 	}
 
-	body, _ := json.Marshal(&authResponse{
+	body, _ := jsonMarshalNoEscape(&authResponse{
 		Authorized: authorized,
 		User:       givenUser,
 	})
@@ -481,7 +481,7 @@ func (h *HTTPBin) HiddenBasicAuth(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	body, _ := json.Marshal(&authResponse{
+	body, _ := jsonMarshalNoEscape(&authResponse{
 		Authorized: authorized,
 		User:       givenUser,
 	})
@@ -517,9 +517,8 @@ func (h *HTTPBin) Stream(w http.ResponseWriter, r *http.Request) {
 	f := w.(http.Flusher)
 	for i := 0; i < n; i++ {
 		resp.ID = i
-		line, _ := json.Marshal(resp)
+		line, _ := jsonMarshalNoEscape(resp)
 		w.Write(line)
-		w.Write([]byte("\n"))
 		f.Flush()
 	}
 }
@@ -728,7 +727,7 @@ func (h *HTTPBin) ETag(w http.ResponseWriter, r *http.Request) {
 		Origin:  getClientIP(r),
 		URL:     getURL(r).String(),
 	}
-	body, _ := json.Marshal(resp)
+	body, _ := jsonMarshalNoEscape(resp)
 
 	// Let http.ServeContent deal with If-None-Match and If-Match headers:
 	// https://golang.org/pkg/net/http/#ServeContent
@@ -954,7 +953,7 @@ func (h *HTTPBin) DigestAuth(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	resp, _ := json.Marshal(&authResponse{
+	resp, _ := jsonMarshalNoEscape(&authResponse{
 		Authorized: true,
 		User:       user,
 	})
@@ -963,7 +962,7 @@ func (h *HTTPBin) DigestAuth(w http.ResponseWriter, r *http.Request) {
 
 // UUID - responds with a generated UUID
 func (h *HTTPBin) UUID(w http.ResponseWriter, r *http.Request) {
-	resp, _ := json.Marshal(&uuidResponse{
+	resp, _ := jsonMarshalNoEscape(&uuidResponse{
 		UUID: uuidv4(),
 	})
 	writeJSON(w, resp, http.StatusOK)
@@ -1007,7 +1006,7 @@ func (h *HTTPBin) Bearer(w http.ResponseWriter, r *http.Request) {
 		w.WriteHeader(http.StatusUnauthorized)
 		return
 	}
-	body, _ := json.Marshal(&bearerResponse{
+	body, _ := jsonMarshalNoEscape(&bearerResponse{
 		Authenticated: true,
 		Token:         tokenFields[1],
 	})
@@ -1016,8 +1015,18 @@ func (h *HTTPBin) Bearer(w http.ResponseWriter, r *http.Request) {
 
 // Hostname - returns the hostname.
 func (h *HTTPBin) Hostname(w http.ResponseWriter, r *http.Request) {
-	body, _ := json.Marshal(hostnameResponse{
+	body, _ := jsonMarshalNoEscape(hostnameResponse{
 		Hostname: h.hostname,
 	})
 	writeJSON(w, body, http.StatusOK)
 }
+
+// json.Marshal escapes HTML in strings while httpbin does not, so
+// we need to set up the encoder manually to reproduce that behavior.
+func jsonMarshalNoEscape(value interface{}) ([]byte, error) {
+	buffer := &bytes.Buffer{}
+	encoder := json.NewEncoder(buffer)
+	encoder.SetEscapeHTML(false)
+	err := encoder.Encode(value)
+	return buffer.Bytes(), err
+}
diff --git a/httpbin/handlers_test.go b/httpbin/handlers_test.go
index 89503c9146be286d7a41229af57725e2176d8996..366bccdc1a3123caba911258c1fa6834e0305ea7 100644
--- a/httpbin/handlers_test.go
+++ b/httpbin/handlers_test.go
@@ -480,6 +480,7 @@ func TestAnything(t *testing.T) {
 	t.Parallel()
 	var (
 		verbsWithReqBodies = []string{
+			"GET",
 			"DELETE",
 			"PATCH",
 			"POST",
@@ -494,10 +495,6 @@ func TestAnything(t *testing.T) {
 		for _, verb := range verbsWithReqBodies {
 			testRequestWithBody(t, verb, path)
 		}
-		// also test GET requests for each path
-		t.Run("GET "+path, func(t *testing.T) {
-			testRequestWithoutBody(t, path, nil, nil, http.StatusOK)
-		})
 	}
 }
 
@@ -527,6 +524,7 @@ func testRequestWithBody(t *testing.T, verb, path string) {
 		testRequestWithBodyInvalidFormEncodedBody,
 		testRequestWithBodyInvalidJSON,
 		testRequestWithBodyInvalidMultiPartBody,
+		testRequestWithBodyHTML,
 		testRequestWithBodyJSON,
 		testRequestWithBodyMultiPartBody,
 		testRequestWithBodyQueryParams,
@@ -623,6 +621,26 @@ func testRequestWithBodyFormEncodedBody(t *testing.T, verb, path string) {
 	}
 }
 
+func testRequestWithBodyHTML(t *testing.T, verb, path string) {
+	data := "<html><body><h1>hello world</h1></body></html>"
+
+	r, _ := http.NewRequest(verb, path, strings.NewReader(data))
+	r.Header.Set("Content-Type", htmlContentType)
+	w := httptest.NewRecorder()
+	handler.ServeHTTP(w, r)
+
+	assertStatusCode(t, w, http.StatusOK)
+	assertContentType(t, w, jsonContentType)
+
+	// We do not use json.Unmarshal here which would unescape any escaped characters.
+	// For httpbin compatibility, we need to verify the data is returned as-is without
+	// escaping.
+	respBody := w.Body.String()
+	if !strings.Contains(respBody, data) {
+		t.Fatalf("response data mismatch, %#v != %#v", respBody, data)
+	}
+}
+
 func testRequestWithBodyFormEncodedBodyNoContentType(t *testing.T, verb, path string) {
 	params := url.Values{}
 	params.Set("foo", "foo")
diff --git a/httpbin/helpers.go b/httpbin/helpers.go
index ef48f60ff7391ffdf02fdde0ee51976f5b506873..48c18c38b3020f7aaf20fb5cd6dbe65be6214dce 100644
--- a/httpbin/helpers.go
+++ b/httpbin/helpers.go
@@ -123,12 +123,13 @@ func parseBody(w http.ResponseWriter, r *http.Request, resp *bodyResponse) error
 	ct := r.Header.Get("Content-Type")
 	switch {
 	case strings.HasPrefix(ct, "application/x-www-form-urlencoded"):
-		// r.ParseForm() does not populate r.PostForm for DELETE requests, but
+		// r.ParseForm() does not populate r.PostForm for DELETE or GET requests, but
 		// we need it to for compatibility with the httpbin implementation, so
 		// we trick it with this ugly hack.
-		if r.Method == http.MethodDelete {
+		if r.Method == http.MethodDelete || r.Method == http.MethodGet {
+			originalMethod := r.Method
 			r.Method = http.MethodPost
-			defer func() { r.Method = http.MethodDelete }()
+			defer func() { r.Method = originalMethod }()
 		}
 		if err := r.ParseForm(); err != nil {
 			return err