@@ -11,6 +11,7 @@ import (
1111 "fmt"
1212 "log"
1313 "net/http"
14+ "net/textproto"
1415 "net/url"
1516 "os"
1617 "strings"
@@ -170,7 +171,13 @@ func (r *RequestAccessorV2) EventToRequest(req events.APIGatewayV2HTTPRequest) (
170171 httpRequest .Header .Add ("Cookie" , cookie )
171172 }
172173
173- for headerKey , headerValue := range req .Headers {
174+ singletonHeaders , headers := splitSingletonHeaders (req .Headers )
175+
176+ for headerKey , headerValue := range singletonHeaders {
177+ httpRequest .Header .Add (headerKey , headerValue )
178+ }
179+
180+ for headerKey , headerValue := range headers {
174181 for _ , val := range strings .Split (headerValue , "," ) {
175182 httpRequest .Header .Add (headerKey , strings .Trim (val , " " ))
176183 }
@@ -227,3 +234,38 @@ type requestContextV2 struct {
227234 gatewayProxyContext events.APIGatewayV2HTTPRequestContext
228235 stageVars map [string ]string
229236}
237+
238+ // splitSingletonHeaders splits the headers into single-value headers and other,
239+ // multi-value capable, headers.
240+ // Returns (single-value headers, multi-value-capable headers)
241+ func splitSingletonHeaders (headers map [string ]string ) (map [string ]string , map [string ]string ) {
242+ singletons := make (map [string ]string )
243+ multitons := make (map [string ]string )
244+ for headerKey , headerValue := range headers {
245+ if ok := singletonHeaders [textproto .CanonicalMIMEHeaderKey (headerKey )]; ok {
246+ singletons [headerKey ] = headerValue
247+ } else {
248+ multitons [headerKey ] = headerValue
249+ }
250+ }
251+
252+ return singletons , multitons
253+ }
254+
255+ // singletonHeaders is a set of headers, that only accept a single
256+ // value which may be comma separated (according to RFC 7230)
257+ var singletonHeaders = map [string ]bool {
258+ "Content-Type" : true ,
259+ "Content-Disposition" : true ,
260+ "Content-Length" : true ,
261+ "User-Agent" : true ,
262+ "Referer" : true ,
263+ "Host" : true ,
264+ "Authorization" : true ,
265+ "Proxy-Authorization" : true ,
266+ "If-Modified-Since" : true ,
267+ "If-Unmodified-Since" : true ,
268+ "From" : true ,
269+ "Location" : true ,
270+ "Max-Forwards" : true ,
271+ }
0 commit comments