Skip to content
This repository was archived by the owner on May 21, 2025. It is now read-only.

Commit d7b2b4e

Browse files
committed
Added support for multi-value headers
1 parent 66a3fb5 commit d7b2b4e

File tree

2 files changed

+51
-23
lines changed

2 files changed

+51
-23
lines changed

core/response.go

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func (r *ProxyResponseWriter) WriteHeader(status int) {
6666

6767
// GetProxyResponse converts the data passed to the response writer into
6868
// an events.APIGatewayProxyResponse object.
69-
// Returns a populated proxy response object. If the reponse is invalid, for example
69+
// Returns a populated proxy response object. If the response is invalid, for example
7070
// has no headers or an invalid status code returns an error.
7171
func (r *ProxyResponseWriter) GetProxyResponse() (events.APIGatewayProxyResponse, error) {
7272
if r.status == defaultStatusCode {
@@ -85,16 +85,10 @@ func (r *ProxyResponseWriter) GetProxyResponse() (events.APIGatewayProxyResponse
8585
isBase64 = true
8686
}
8787

88-
proxyHeaders := make(map[string]string)
89-
90-
for h := range r.headers {
91-
proxyHeaders[h] = r.headers.Get(h)
92-
}
93-
9488
return events.APIGatewayProxyResponse{
95-
StatusCode: r.status,
96-
Headers: proxyHeaders,
97-
Body: output,
98-
IsBase64Encoded: isBase64,
89+
StatusCode: r.status,
90+
MultiValueHeaders: http.Header(r.headers),
91+
Body: output,
92+
IsBase64Encoded: isBase64,
9993
}, nil
10094
}

core/response_test.go

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,34 +62,34 @@ var _ = Describe("ResponseWriter tests", func() {
6262
Expect("application/json").To(Equal(resp.Header().Get("Content-Type")))
6363
proxyResp, err := resp.GetProxyResponse()
6464
Expect(err).To(BeNil())
65-
Expect(1).To(Equal(len(proxyResp.Headers)))
66-
Expect("application/json").To(Equal(proxyResp.Headers["Content-Type"]))
65+
Expect(1).To(Equal(len(proxyResp.MultiValueHeaders)))
66+
Expect("application/json").To(Equal(proxyResp.MultiValueHeaders["Content-Type"][0]))
6767
Expect(xmlBodyContent).To(Equal(proxyResp.Body))
6868
})
6969

70-
It("Sets the conte type to text/xml given the body", func() {
70+
It("Sets the content type to text/xml given the body", func() {
7171
resp := NewProxyResponseWriter()
7272
resp.Write([]byte(xmlBodyContent))
7373

7474
Expect("").ToNot(Equal(resp.Header().Get("Content-Type")))
7575
Expect(true).To(Equal(strings.HasPrefix(resp.Header().Get("Content-Type"), "text/xml;")))
7676
proxyResp, err := resp.GetProxyResponse()
7777
Expect(err).To(BeNil())
78-
Expect(1).To(Equal(len(proxyResp.Headers)))
79-
Expect(true).To(Equal(strings.HasPrefix(proxyResp.Headers["Content-Type"], "text/xml;")))
78+
Expect(1).To(Equal(len(proxyResp.MultiValueHeaders)))
79+
Expect(true).To(Equal(strings.HasPrefix(proxyResp.MultiValueHeaders["Content-Type"][0], "text/xml;")))
8080
Expect(xmlBodyContent).To(Equal(proxyResp.Body))
8181
})
8282

83-
It("Sets the conte type to text/html given the body", func() {
83+
It("Sets the content type to text/html given the body", func() {
8484
resp := NewProxyResponseWriter()
8585
resp.Write([]byte(htmlBodyContent))
8686

8787
Expect("").ToNot(Equal(resp.Header().Get("Content-Type")))
8888
Expect(true).To(Equal(strings.HasPrefix(resp.Header().Get("Content-Type"), "text/html;")))
8989
proxyResp, err := resp.GetProxyResponse()
9090
Expect(err).To(BeNil())
91-
Expect(1).To(Equal(len(proxyResp.Headers)))
92-
Expect(true).To(Equal(strings.HasPrefix(proxyResp.Headers["Content-Type"], "text/html;")))
91+
Expect(1).To(Equal(len(proxyResp.MultiValueHeaders)))
92+
Expect(true).To(Equal(strings.HasPrefix(proxyResp.MultiValueHeaders["Content-Type"][0], "text/html;")))
9393
Expect(htmlBodyContent).To(Equal(proxyResp.Body))
9494
})
9595
})
@@ -114,8 +114,8 @@ var _ = Describe("ResponseWriter tests", func() {
114114

115115
Expect("hello").To(Equal(proxyResponse.Body))
116116
Expect(http.StatusOK).To(Equal(proxyResponse.StatusCode))
117-
Expect(1).To(Equal(len(proxyResponse.Headers)))
118-
Expect(true).To(Equal(strings.HasPrefix(proxyResponse.Headers["Content-Type"], "text/plain")))
117+
Expect(1).To(Equal(len(proxyResponse.MultiValueHeaders)))
118+
Expect(true).To(Equal(strings.HasPrefix(proxyResponse.MultiValueHeaders["Content-Type"][0], "text/plain")))
119119
Expect(proxyResponse.IsBase64Encoded).To(BeFalse())
120120
})
121121

@@ -138,9 +138,43 @@ var _ = Describe("ResponseWriter tests", func() {
138138
Expect(base64.StdEncoding.EncodedLen(len(binaryBody))).To(Equal(len(proxyResponse.Body)))
139139

140140
Expect(base64.StdEncoding.EncodeToString(binaryBody)).To(Equal(proxyResponse.Body))
141-
Expect(1).To(Equal(len(proxyResponse.Headers)))
142-
Expect("application/octet-stream").To(Equal(proxyResponse.Headers["Content-Type"]))
141+
Expect(1).To(Equal(len(proxyResponse.MultiValueHeaders)))
142+
Expect("application/octet-stream").To(Equal(proxyResponse.MultiValueHeaders["Content-Type"][0]))
143143
Expect(http.StatusAccepted).To(Equal(proxyResponse.StatusCode))
144144
})
145145
})
146+
147+
Context("Handle multi-value headers", func() {
148+
149+
It("Writes single-value headers correctly", func() {
150+
response := NewProxyResponseWriter()
151+
response.Header().Add("Content-Type", "application/json")
152+
response.Write([]byte("hello"))
153+
proxyResponse, err := response.GetProxyResponse()
154+
Expect(err).To(BeNil())
155+
156+
// Headers are not written to `Headers` field
157+
Expect(0).To(Equal(len(proxyResponse.Headers)))
158+
Expect(1).To(Equal(len(proxyResponse.MultiValueHeaders["Content-Type"])))
159+
Expect("application/json").To(Equal(proxyResponse.MultiValueHeaders["Content-Type"][0]))
160+
})
161+
162+
It("Writes multi-value headers correctly", func() {
163+
response := NewProxyResponseWriter()
164+
response.Header().Add("Set-Cookie", "csrftoken=foobar")
165+
response.Header().Add("Set-Cookie", "session_id=barfoo")
166+
response.Write([]byte("hello"))
167+
proxyResponse, err := response.GetProxyResponse()
168+
Expect(err).To(BeNil())
169+
170+
// Headers are not written to `Headers` field
171+
Expect(0).To(Equal(len(proxyResponse.Headers)))
172+
173+
// There are two headers here because Content-Type is always written implicitly
174+
Expect(2).To(Equal(len(proxyResponse.MultiValueHeaders["Set-Cookie"])))
175+
Expect("csrftoken=foobar").To(Equal(proxyResponse.MultiValueHeaders["Set-Cookie"][0]))
176+
Expect("session_id=barfoo").To(Equal(proxyResponse.MultiValueHeaders["Set-Cookie"][1]))
177+
})
178+
})
179+
146180
})

0 commit comments

Comments
 (0)