From a31e64923f33075467062212bcae8420526fabd5 Mon Sep 17 00:00:00 2001 From: Klaus Ita Date: Mon, 18 Dec 2017 09:03:38 +0100 Subject: [PATCH 1/3] Allow multiple HTTP-Headers in Server --- transport/http/server.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/transport/http/server.go b/transport/http/server.go index 311f76c81..13a27d958 100644 --- a/transport/http/server.go +++ b/transport/http/server.go @@ -144,8 +144,10 @@ type ServerFinalizerFunc func(ctx context.Context, code int, r *http.Request) func EncodeJSONResponse(_ context.Context, w http.ResponseWriter, response interface{}) error { w.Header().Set("Content-Type", "application/json; charset=utf-8") if headerer, ok := response.(Headerer); ok { - for k := range headerer.Headers() { - w.Header().Set(k, headerer.Headers().Get(k)) + for k, values := range headerer.Headers() { + for _, v := range values { + w.Header().Add(k, v) + } } } code := http.StatusOK @@ -175,8 +177,10 @@ func DefaultErrorEncoder(_ context.Context, err error, w http.ResponseWriter) { } w.Header().Set("Content-Type", contentType) if headerer, ok := err.(Headerer); ok { - for k := range headerer.Headers() { - w.Header().Set(k, headerer.Headers().Get(k)) + for k, values := range headerer.Headers() { + for _, v := range values { + w.Header().Add(k, v) + } } } code := http.StatusInternalServerError From ee4af7b1e6476e0d2970227db2026d11a037e72e Mon Sep 17 00:00:00 2001 From: Fabian Ruff Date: Mon, 18 Dec 2017 22:10:10 +0100 Subject: [PATCH 2/3] fix typo --- log/level/level.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/log/level/level.go b/log/level/level.go index 6833b0dca..dd4ef60e0 100644 --- a/log/level/level.go +++ b/log/level/level.go @@ -177,7 +177,7 @@ func DebugValue() Value { return debugValue } var ( // key is of type interfae{} so that it allocates once during package - // initialization and avoids allocating every type the value is added to a + // initialization and avoids allocating every time the value is added to a // []interface{} later. key interface{} = "level" From 7b55f9a9a1309e009856c1348072938449e6d9a3 Mon Sep 17 00:00:00 2001 From: Klaus Ita Date: Tue, 30 Jan 2018 16:36:31 +0100 Subject: [PATCH 3/3] Add tests for Allow multiple HTTP-Headers --- transport/http/server_test.go | 71 +++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/transport/http/server_test.go b/transport/http/server_test.go index ddc40c97f..20a077811 100644 --- a/transport/http/server_test.go +++ b/transport/http/server_test.go @@ -261,6 +261,77 @@ func TestEncodeJSONResponse(t *testing.T) { } } +type multiHeaderResponse struct{} + +func (_ multiHeaderResponse) Headers() http.Header { + return http.Header{"Vary": []string{"Origin", "User-Agent"}} +} + +func TestAddMultipleHeaders(t *testing.T) { + handler := httptransport.NewServer( + func(context.Context, interface{}) (interface{}, error) { return multiHeaderResponse{}, nil }, + func(context.Context, *http.Request) (interface{}, error) { return struct{}{}, nil }, + httptransport.EncodeJSONResponse, + ) + + server := httptest.NewServer(handler) + defer server.Close() + + resp, err := http.Get(server.URL) + if err != nil { + t.Fatal(err) + } + expect := map[string]map[string]struct{}{"Vary": map[string]struct{}{"Origin": struct{}{}, "User-Agent": struct{}{}}} + for k, vls := range resp.Header { + for _, v := range vls { + delete((expect[k]), v) + } + if len(expect[k]) != 0 { + t.Errorf("Header: unexpected header %s: %v", k, expect[k]) + } + } +} + +type multiHeaderResponseError struct { + multiHeaderResponse + msg string +} + +func (m multiHeaderResponseError) Error() string { + return m.msg +} + +func TestAddMultipleHeadersErrorEncoder(t *testing.T) { + errStr := "oh no" + handler := httptransport.NewServer( + func(context.Context, interface{}) (interface{}, error) { + return nil, multiHeaderResponseError{msg: errStr} + }, + func(context.Context, *http.Request) (interface{}, error) { return struct{}{}, nil }, + httptransport.EncodeJSONResponse, + ) + + server := httptest.NewServer(handler) + defer server.Close() + + resp, err := http.Get(server.URL) + if err != nil { + t.Fatal(err) + } + expect := map[string]map[string]struct{}{"Vary": map[string]struct{}{"Origin": struct{}{}, "User-Agent": struct{}{}}} + for k, vls := range resp.Header { + for _, v := range vls { + delete((expect[k]), v) + } + if len(expect[k]) != 0 { + t.Errorf("Header: unexpected header %s: %v", k, expect[k]) + } + } + if b, _ := ioutil.ReadAll(resp.Body); errStr != string(b) { + t.Errorf("ErrorEncoder: got: %q, expected: %q", b, errStr) + } +} + type noContentResponse struct{} func (e noContentResponse) StatusCode() int { return http.StatusNoContent }