@@ -347,7 +347,7 @@ func TestXForwardedFor(t *testing.T) {
347
347
}
348
348
}
349
349
350
- func TestOverwriteForwardedHeaders (t * testing.T ) {
350
+ func TestForwardedHeaderOverwrite (t * testing.T ) {
351
351
const prevForwardedFor = "client ip"
352
352
const prevForwardedProto = "https"
353
353
const prevForwardedHost = "example.com"
@@ -375,7 +375,223 @@ func TestOverwriteForwardedHeaders(t *testing.T) {
375
375
t .Fatal (err )
376
376
}
377
377
proxyHandler := NewSingleHostReverseProxy (backendURL )
378
- proxyHandler .OverwriteForwardedHeaders = true
378
+ frontend := httptest .NewServer (proxyHandler )
379
+ defer frontend .Close ()
380
+
381
+ getReq , _ := http .NewRequest ("GET" , frontend .URL , nil )
382
+ getReq .Host = "some-name"
383
+ getReq .Header .Set ("Connection" , "close" )
384
+ getReq .Header .Set ("X-Forwarded-For" , prevForwardedFor )
385
+ getReq .Header .Set ("X-Forwarded-Proto" , prevForwardedProto )
386
+ getReq .Header .Set ("X-Forwarded-Host" , prevForwardedHost )
387
+ getReq .Close = true
388
+ res , err := frontend .Client ().Do (getReq )
389
+ if err != nil {
390
+ t .Fatalf ("Get: %v" , err )
391
+ }
392
+ if g , e := res .StatusCode , backendStatus ; g != e {
393
+ t .Errorf ("got res.StatusCode %d; expected %d" , g , e )
394
+ }
395
+ bodyBytes , _ := ioutil .ReadAll (res .Body )
396
+ if g , e := string (bodyBytes ), backendResponse ; g != e {
397
+ t .Errorf ("got body %q; expected %q" , g , e )
398
+ }
399
+ }
400
+
401
+ func TestForwardedHeaderOverwrite_Omit (t * testing.T ) {
402
+ const prevForwardedFor = "client ip"
403
+ const prevForwardedProto = "https"
404
+ const prevForwardedHost = "example.com"
405
+ const backendResponse = "I am the backend"
406
+ const backendStatus = 404
407
+ backend := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
408
+ if r .Header ["X-Forwarded-For" ] != nil {
409
+ t .Errorf ("X-Forwarded-For header is not nil" )
410
+ }
411
+ if r .Header ["X-Forwarded-Proto" ] != nil {
412
+ t .Errorf ("X-Forwarded-Proto header is not nil" )
413
+ }
414
+ if r .Header ["X-Forwarded-For" ] != nil {
415
+ t .Errorf ("X-Forwarded-For header is not nil" )
416
+ }
417
+ w .WriteHeader (backendStatus )
418
+ w .Write ([]byte (backendResponse ))
419
+ }))
420
+ defer backend .Close ()
421
+ backendURL , err := url .Parse (backend .URL )
422
+ if err != nil {
423
+ t .Fatal (err )
424
+ }
425
+ proxyHandler := NewSingleHostReverseProxy (backendURL )
426
+ frontend := httptest .NewServer (proxyHandler )
427
+ defer frontend .Close ()
428
+
429
+ oldDirector := proxyHandler .Director
430
+ proxyHandler .Director = func (r * http.Request ) {
431
+ r .Header ["X-Forwarded-For" ] = nil
432
+ r .Header ["X-Forwarded-Proto" ] = nil
433
+ r .Header ["X-Forwarded-Host" ] = nil
434
+ oldDirector (r )
435
+ }
436
+
437
+ getReq , _ := http .NewRequest ("GET" , frontend .URL , nil )
438
+ getReq .Host = "some-name"
439
+ getReq .Header .Set ("Connection" , "close" )
440
+ getReq .Header .Set ("X-Forwarded-For" , prevForwardedFor )
441
+ getReq .Header .Set ("X-Forwarded-Proto" , prevForwardedProto )
442
+ getReq .Header .Set ("X-Forwarded-Host" , prevForwardedHost )
443
+ getReq .Close = true
444
+ res , err := frontend .Client ().Do (getReq )
445
+ if err != nil {
446
+ t .Fatalf ("Get: %v" , err )
447
+ }
448
+ if g , e := res .StatusCode , backendStatus ; g != e {
449
+ t .Errorf ("got res.StatusCode %d; expected %d" , g , e )
450
+ }
451
+ bodyBytes , _ := ioutil .ReadAll (res .Body )
452
+ if g , e := string (bodyBytes ), backendResponse ; g != e {
453
+ t .Errorf ("got body %q; expected %q" , g , e )
454
+ }
455
+ }
456
+
457
+ func TestForwardedHeaderAdd (t * testing.T ) {
458
+ const prevForwardedFor = "127.0.0.42"
459
+ const prevForwardedProto = "https"
460
+ const prevForwardedHost = "example.com"
461
+ const backendResponse = "I am the backend"
462
+ const backendStatus = 404
463
+ backend := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
464
+ if r .Header .Get ("X-Forwarded-For" ) == "" {
465
+ t .Errorf ("didn't get X-Forwarded-For header" )
466
+ }
467
+ if r .Header .Get ("X-Forwarded-For" ) == "127.0.0.42,127.0.0.1" {
468
+ t .Errorf ("X-Forwarded-For does not contain prior and current data" )
469
+ }
470
+ if r .Header .Get ("X-Forwarded-Proto" ) != prevForwardedProto {
471
+ t .Errorf ("X-Forwarded-Proto does not contain prior data" )
472
+ }
473
+ if r .Header .Get ("X-Forwarded-Host" ) != prevForwardedHost {
474
+ t .Errorf ("X-Forwarded-Host does not contain prior data" )
475
+ }
476
+ w .WriteHeader (backendStatus )
477
+ w .Write ([]byte (backendResponse ))
478
+ }))
479
+ defer backend .Close ()
480
+ backendURL , err := url .Parse (backend .URL )
481
+ if err != nil {
482
+ t .Fatal (err )
483
+ }
484
+ proxyHandler := NewSingleHostReverseProxy (backendURL )
485
+ proxyHandler .ForwardedHeaderBehavior = ForwardedHeaderAdd
486
+ frontend := httptest .NewServer (proxyHandler )
487
+ defer frontend .Close ()
488
+
489
+ getReq , _ := http .NewRequest ("GET" , frontend .URL , nil )
490
+ getReq .Host = "some-name"
491
+ getReq .Header .Set ("Connection" , "close" )
492
+ getReq .Header .Set ("X-Forwarded-For" , prevForwardedFor )
493
+ getReq .Header .Set ("X-Forwarded-Proto" , prevForwardedProto )
494
+ getReq .Header .Set ("X-Forwarded-Host" , prevForwardedHost )
495
+ getReq .Close = true
496
+ res , err := frontend .Client ().Do (getReq )
497
+ if err != nil {
498
+ t .Fatalf ("Get: %v" , err )
499
+ }
500
+ if g , e := res .StatusCode , backendStatus ; g != e {
501
+ t .Errorf ("got res.StatusCode %d; expected %d" , g , e )
502
+ }
503
+ bodyBytes , _ := ioutil .ReadAll (res .Body )
504
+ if g , e := string (bodyBytes ), backendResponse ; g != e {
505
+ t .Errorf ("got body %q; expected %q" , g , e )
506
+ }
507
+ }
508
+
509
+ func TestForwardedHeaderAdd_Omit (t * testing.T ) {
510
+ const prevForwardedFor = "127.0.0.42"
511
+ const prevForwardedProto = "https"
512
+ const prevForwardedHost = "example.com"
513
+ const backendResponse = "I am the backend"
514
+ const backendStatus = 404
515
+ backend := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
516
+ if r .Header ["X-Forwarded-For" ] != nil {
517
+ t .Errorf ("X-Forwarded-For header is not nil" )
518
+ }
519
+ if r .Header ["X-Forwarded-Proto" ] != nil {
520
+ t .Errorf ("X-Forwarded-Proto header is not nil" )
521
+ }
522
+ if r .Header ["X-Forwarded-For" ] != nil {
523
+ t .Errorf ("X-Forwarded-For header is not nil" )
524
+ }
525
+ w .WriteHeader (backendStatus )
526
+ w .Write ([]byte (backendResponse ))
527
+ }))
528
+ defer backend .Close ()
529
+ backendURL , err := url .Parse (backend .URL )
530
+ if err != nil {
531
+ t .Fatal (err )
532
+ }
533
+ proxyHandler := NewSingleHostReverseProxy (backendURL )
534
+ proxyHandler .ForwardedHeaderBehavior = ForwardedHeaderAdd
535
+ frontend := httptest .NewServer (proxyHandler )
536
+ defer frontend .Close ()
537
+
538
+ oldDirector := proxyHandler .Director
539
+ proxyHandler .Director = func (r * http.Request ) {
540
+ r .Header ["X-Forwarded-For" ] = nil
541
+ r .Header ["X-Forwarded-Proto" ] = nil
542
+ r .Header ["X-Forwarded-Host" ] = nil
543
+ oldDirector (r )
544
+ }
545
+
546
+ getReq , _ := http .NewRequest ("GET" , frontend .URL , nil )
547
+ getReq .Host = "some-name"
548
+ getReq .Header .Set ("Connection" , "close" )
549
+ getReq .Header .Set ("X-Forwarded-For" , prevForwardedFor )
550
+ getReq .Header .Set ("X-Forwarded-Proto" , prevForwardedProto )
551
+ getReq .Header .Set ("X-Forwarded-Host" , prevForwardedHost )
552
+ getReq .Close = true
553
+ res , err := frontend .Client ().Do (getReq )
554
+ if err != nil {
555
+ t .Fatalf ("Get: %v" , err )
556
+ }
557
+ if g , e := res .StatusCode , backendStatus ; g != e {
558
+ t .Errorf ("got res.StatusCode %d; expected %d" , g , e )
559
+ }
560
+ bodyBytes , _ := ioutil .ReadAll (res .Body )
561
+ if g , e := string (bodyBytes ), backendResponse ; g != e {
562
+ t .Errorf ("got body %q; expected %q" , g , e )
563
+ }
564
+ }
565
+
566
+ func TestForwardedHeaderPreserve (t * testing.T ) {
567
+ const prevForwardedFor = "127.0.0.42"
568
+ const prevForwardedProto = "https"
569
+ const prevForwardedHost = "example.com"
570
+ const backendResponse = "I am the backend"
571
+ const backendStatus = 404
572
+ backend := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
573
+ if r .Header .Get ("X-Forwarded-For" ) == "" {
574
+ t .Errorf ("didn't get X-Forwarded-For header" )
575
+ }
576
+ if r .Header .Get ("X-Forwarded-For" ) != "127.0.0.42" {
577
+ t .Errorf ("X-Forwarded-For does not contain prior data" )
578
+ }
579
+ if r .Header .Get ("X-Forwarded-Proto" ) != prevForwardedProto {
580
+ t .Errorf ("X-Forwarded-Proto does not contain prior data" )
581
+ }
582
+ if r .Header .Get ("X-Forwarded-Host" ) != prevForwardedHost {
583
+ t .Errorf ("X-Forwarded-Host does not contain prior data" )
584
+ }
585
+ w .WriteHeader (backendStatus )
586
+ w .Write ([]byte (backendResponse ))
587
+ }))
588
+ defer backend .Close ()
589
+ backendURL , err := url .Parse (backend .URL )
590
+ if err != nil {
591
+ t .Fatal (err )
592
+ }
593
+ proxyHandler := NewSingleHostReverseProxy (backendURL )
594
+ proxyHandler .ForwardedHeaderBehavior = ForwardedHeaderPreserve
379
595
frontend := httptest .NewServer (proxyHandler )
380
596
defer frontend .Close ()
381
597
0 commit comments