-
Notifications
You must be signed in to change notification settings - Fork 124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: API response-headers compatibility with origin #131 #142
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -314,15 +314,26 @@ func (h *HTTPBin) Unstable(w http.ResponseWriter, r *http.Request) { | |
// ResponseHeaders responds with a map of header values | ||
func (h *HTTPBin) ResponseHeaders(w http.ResponseWriter, r *http.Request) { | ||
args := r.URL.Query() | ||
body := make(map[string]interface{}) | ||
for k, vs := range args { | ||
for _, v := range vs { | ||
w.Header().Add(k, v) | ||
} | ||
if len(vs) == 1 { | ||
body[k] = vs[0] | ||
} else { | ||
body[k] = vs | ||
} | ||
Comment on lines
+322
to
+326
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please drop this logic. Per my comment here
That might not be very clear. To restate it, what I mean is that go-httpbin returns all header values as JSON arrays, even if only one header is given. I know that is not actually backwards-compatible with the original httpbin, but for now I've decided that I prefer the consistency (and implementation simplicity) of this approach and I'm okay with the incompatibility. (See #37 and #15 for related discussion.) |
||
} | ||
if contentType := w.Header().Get("Content-Type"); contentType == "" { | ||
w.Header().Set("Content-Type", jsonContentType) | ||
} | ||
mustMarshalJSON(w, args) | ||
body["Content-Type"] = w.Header().Get("Content-Type") | ||
body["Content-Length"] = 0 | ||
buf := &bytes.Buffer{} | ||
json.NewEncoder(buf).Encode(body) | ||
body["Content-Length"] = buf.Len() | ||
mustMarshalJSON(w, body) | ||
Comment on lines
+331
to
+336
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a bit of a strange approach, double-encoding the body just to get the content length. Please rewrite it to do the encoding once. The existing |
||
} | ||
|
||
func redirectLocation(r *http.Request, relative bool, n int) string { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1163,16 +1163,32 @@ func TestResponseHeaders(t *testing.T) { | |
|
||
req, _ := http.NewRequest("GET", fmt.Sprintf("%s/response-headers?%s", srv.URL, wantHeaders.Encode()), nil) | ||
resp := must.DoReq(t, client, req) | ||
result := mustParseResponse[http.Header](t, resp) | ||
|
||
type bodyResponse struct { | ||
Foo string `json:"Foo"` | ||
Bar []string `json:"Bar"` | ||
ContentType string `json:"Content-Type"` | ||
ContentLength int `json:"Content-Length"` | ||
} | ||
|
||
result := mustParseResponse[bodyResponse](t, resp) | ||
|
||
assert.ContentType(t, resp, result.ContentType) | ||
assert.Equal[bool](t, result.ContentLength > 0, true, "JSON response Content-Length mismatch") | ||
Comment on lines
-1166
to
+1177
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can do away with most of this specialization if we simplify the response as requested above. |
||
|
||
for k, expectedValues := range wantHeaders { | ||
// expected headers should be present in the HTTP response itself | ||
respValues := resp.Header[k] | ||
assert.DeepEqual(t, respValues, expectedValues, "HTTP response headers mismatch") | ||
|
||
// they should also be reflected in the decoded JSON resposne | ||
resultValues := result[k] | ||
assert.DeepEqual(t, resultValues, expectedValues, "JSON response headers mismatch") | ||
if len(expectedValues) == 1 { | ||
value := reflect.ValueOf(result).FieldByName(k).String() | ||
assert.Equal[string](t, value, expectedValues[0], "JSON response headers mismatch") | ||
} else { | ||
value := reflect.ValueOf(result).FieldByName(k).Interface().([]string) | ||
assert.DeepEqual(t, value, expectedValues, "JSON response headers mismatch") | ||
} | ||
} | ||
}) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With my comment below, I don't think we need anything more than
args
here.