@@ -91,8 +91,9 @@ func TestReverseProxy(t *testing.T) {
91
91
92
92
getReq , _ := http .NewRequest ("GET" , frontend .URL , nil )
93
93
getReq .Host = "some-name"
94
- getReq .Header .Set ("Connection" , "close" )
95
- getReq .Header .Set ("Te" , "trailers" )
94
+ getReq .Header .Set ("Connection" , "close, TE" )
95
+ getReq .Header .Add ("Te" , "foo" )
96
+ getReq .Header .Add ("Te" , "bar, trailers" )
96
97
getReq .Header .Set ("Proxy-Connection" , "should be deleted" )
97
98
getReq .Header .Set ("Upgrade" , "foo" )
98
99
getReq .Close = true
@@ -236,6 +237,64 @@ func TestReverseProxyStripHeadersPresentInConnection(t *testing.T) {
236
237
}
237
238
}
238
239
240
+ func TestReverseProxyStripEmptyConnection (t * testing.T ) {
241
+ // See Issue 46313.
242
+ const backendResponse = "I am the backend"
243
+
244
+ // someConnHeader is some arbitrary header to be declared as a hop-by-hop header
245
+ // in the Request's Connection header.
246
+ const someConnHeader = "X-Some-Conn-Header"
247
+
248
+ backend := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
249
+ if c := r .Header .Values ("Connection" ); len (c ) != 0 {
250
+ t .Errorf ("handler got header %q = %v; want empty" , "Connection" , c )
251
+ }
252
+ if c := r .Header .Get (someConnHeader ); c != "" {
253
+ t .Errorf ("handler got header %q = %q; want empty" , someConnHeader , c )
254
+ }
255
+ w .Header ().Add ("Connection" , "" )
256
+ w .Header ().Add ("Connection" , someConnHeader )
257
+ w .Header ().Set (someConnHeader , "should be deleted" )
258
+ io .WriteString (w , backendResponse )
259
+ }))
260
+ defer backend .Close ()
261
+ backendURL , err := url .Parse (backend .URL )
262
+ if err != nil {
263
+ t .Fatal (err )
264
+ }
265
+ proxyHandler := NewSingleHostReverseProxy (backendURL )
266
+ frontend := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
267
+ proxyHandler .ServeHTTP (w , r )
268
+ if c := r .Header .Get (someConnHeader ); c != "should be deleted" {
269
+ t .Errorf ("handler modified header %q = %q; want %q" , someConnHeader , c , "should be deleted" )
270
+ }
271
+ }))
272
+ defer frontend .Close ()
273
+
274
+ getReq , _ := http .NewRequest ("GET" , frontend .URL , nil )
275
+ getReq .Header .Add ("Connection" , "" )
276
+ getReq .Header .Add ("Connection" , someConnHeader )
277
+ getReq .Header .Set (someConnHeader , "should be deleted" )
278
+ res , err := frontend .Client ().Do (getReq )
279
+ if err != nil {
280
+ t .Fatalf ("Get: %v" , err )
281
+ }
282
+ defer res .Body .Close ()
283
+ bodyBytes , err := ioutil .ReadAll (res .Body )
284
+ if err != nil {
285
+ t .Fatalf ("reading body: %v" , err )
286
+ }
287
+ if got , want := string (bodyBytes ), backendResponse ; got != want {
288
+ t .Errorf ("got body %q; want %q" , got , want )
289
+ }
290
+ if c := res .Header .Get ("Connection" ); c != "" {
291
+ t .Errorf ("handler got header %q = %q; want empty" , "Connection" , c )
292
+ }
293
+ if c := res .Header .Get (someConnHeader ); c != "" {
294
+ t .Errorf ("handler got header %q = %q; want empty" , someConnHeader , c )
295
+ }
296
+ }
297
+
239
298
func TestXForwardedFor (t * testing.T ) {
240
299
const prevForwardedFor = "client ip"
241
300
const backendResponse = "I am the backend"
0 commit comments