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