Skip to content

Commit bf8508d

Browse files
authored
Merge pull request #16 from juggernaut/pass-along-content-length
Pass along Content-Length header to target
2 parents e0370fa + a04235c commit bf8508d

File tree

2 files changed

+81
-8
lines changed

2 files changed

+81
-8
lines changed

integration_test.go

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* Copyright (c) 2020 Ameya Lokare
3-
*/
3+
*/
44
package main
55

66
import (
@@ -113,7 +113,7 @@ func assertForbiddenIP(client *http.Client, host string, t *testing.T) {
113113
func TestPrivateNetworkForbidden(t *testing.T) {
114114
fixture := &testFixture{
115115
serversSetup: func(c *certutil.CertificateFixtures) []*http.Server {
116-
server := startTargetServer(t)
116+
server := startTargetServer(t, nil)
117117
return []*http.Server{server}
118118
},
119119
}
@@ -139,7 +139,7 @@ func TestProxy(t *testing.T) {
139139
},
140140
serversSetup: func(certificates *certutil.CertificateFixtures) []*http.Server {
141141
var servers []*http.Server
142-
httpServer := startTargetServer(t)
142+
httpServer := startTargetServer(t, nil)
143143
httpsServer := startTargetHTTPSServerWithInMemoryCert(t, certificates.InvalidHostnameServerCert)
144144
return append(servers, httpServer, httpsServer)
145145
},
@@ -477,7 +477,7 @@ func TestHTTPSProxyListener(t *testing.T) {
477477
config.RootCACerts = c.RootCAs
478478
},
479479
serversSetup: func(c *certutil.CertificateFixtures) []*http.Server {
480-
httpServer := startTargetServer(t)
480+
httpServer := startTargetServer(t, nil)
481481
httpsServer := startTargetHTTPSServerWithInMemoryCert(t, c.ServerCert)
482482
return []*http.Server{httpServer, httpsServer}
483483
},
@@ -623,6 +623,71 @@ func TestChunkedResponseContentLengthLimit(t *testing.T) {
623623
fixture.tearDown(t)
624624
}
625625

626+
func TestRequestContentLength(t *testing.T) {
627+
headerChan := make(chan map[string][]string, 1)
628+
fixture := &testFixture{
629+
configSetup: func(config *proxy.ProxyConfig, c *certutil.CertificateFixtures) {
630+
config.InsecureSkipCidrDenyList = true
631+
},
632+
serversSetup: func(certificates *certutil.CertificateFixtures) []*http.Server {
633+
var servers []*http.Server
634+
httpServer := startTargetServer(t, headerChan)
635+
return append(servers, httpServer)
636+
},
637+
}
638+
639+
client := fixture.setUp(t)
640+
641+
t.Run("Request with content length header is passed along to target", func(t *testing.T) {
642+
resp, err := client.Post(fmt.Sprintf("http://localhost:%s/target", httpTargetServerPort), "text/plain", strings.NewReader("Hello webhook sentry!"))
643+
if err != nil {
644+
t.Errorf("Error in GET request to target server via proxy: %s\n", err)
645+
}
646+
if resp.StatusCode != 200 {
647+
t.Errorf("Expected status code 200, got %d\n", resp.StatusCode)
648+
}
649+
headers := <-headerChan
650+
cl, ok := headers["Content-Length"]
651+
if !ok {
652+
t.Error("No Content-Length found in request headers")
653+
}
654+
655+
expectedLen := len("Hello webhook sentry!")
656+
if cl[0] != strconv.Itoa(expectedLen) {
657+
t.Errorf("Expected Content-Length %d, but found %s", expectedLen, cl[0])
658+
}
659+
})
660+
661+
t.Run("Request with Transfer-Encoding chunked is passed along to target", func(t *testing.T) {
662+
req, err := http.NewRequest("POST", fmt.Sprintf("http://localhost:%s/target", httpTargetServerPort), strings.NewReader("Hello webhook sentry!"))
663+
if err != nil {
664+
t.Fatal(err)
665+
}
666+
req.TransferEncoding = []string{"chunked"}
667+
resp, err := client.Do(req)
668+
if err != nil {
669+
t.Errorf("Error in GET request to target server via proxy: %s\n", err)
670+
}
671+
if resp.StatusCode != 200 {
672+
t.Errorf("Expected status code 200, got %d\n", resp.StatusCode)
673+
}
674+
headers := <-headerChan
675+
_, ok := headers["Content-Length"]
676+
if ok {
677+
t.Error("Expected absence of Content-Length in request headers, but was found")
678+
}
679+
680+
te, ok := headers["Transfer-Encoding"]
681+
if !ok {
682+
t.Error("Expected Transfer-Encoding in request headers, but was not found")
683+
}
684+
if te[0] != "chunked" {
685+
t.Errorf("Expected Transfer-Encoding value 'chunked', but was %s", te[0])
686+
}
687+
})
688+
689+
}
690+
626691
func waitForStartup(t *testing.T, address string) {
627692
i := 0
628693
for {
@@ -699,9 +764,17 @@ func startTLSProxyWithCert(t *testing.T, p *proxy.ProxyConfig, proxyCert *tls.Ce
699764
return pServer
700765
}
701766

702-
func startTargetServer(t *testing.T) *http.Server {
767+
func startTargetServer(t *testing.T, headerChan chan map[string][]string) *http.Server {
703768
serveMux := http.NewServeMux()
704769
serveMux.HandleFunc("/target", func(w http.ResponseWriter, r *http.Request) {
770+
if headerChan != nil {
771+
headers := r.Header.Clone()
772+
// Hack to add Transfer-Encoding, since the headers map doesn't seem to have it
773+
if r.TransferEncoding != nil {
774+
headers["Transfer-Encoding"] = r.TransferEncoding
775+
}
776+
headerChan <- headers
777+
}
705778
w.Header().Set("X-Custom-Header", "custom")
706779
fmt.Fprint(w, "Hello from target")
707780
})

proxy/proxy.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ const (
6060
ClientCertNotFoundError uint16 = 1010
6161
)
6262

63-
6463
func SetupLogging(config *ProxyConfig) error {
6564
if err := configureLog(accessLog, config.AccessLog, &AccessLogTextFormatter{}); err != nil {
6665
return err
@@ -172,7 +171,7 @@ func newProxyServer(listenerConfig ListenerConfig, proxyConfig *ProxyConfig, sd
172171
maxContentLength: proxyConfig.MaxResponseBodySize,
173172
currentInboundConnsGauge: connsGauge,
174173
mitmer: mitmer,
175-
requestIDHeader: proxyConfig.RequestIDHeader,
174+
requestIDHeader: proxyConfig.RequestIDHeader,
176175
}
177176
return &http.Server{
178177
Addr: listenerConfig.Address,
@@ -190,7 +189,7 @@ type ProxyHTTPHandler struct {
190189
currentInboundConnsGauge prometheus.Gauge
191190
maxContentLength uint32
192191
mitmer *Mitmer
193-
requestIDHeader string
192+
requestIDHeader string
194193
}
195194

196195
func (p *ProxyHTTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
@@ -334,6 +333,7 @@ func (p ProxyHTTPHandler) doProxy(ctx context.Context, r *http.Request) (*http.R
334333
}
335334
copyHeaders(r.Header, outboundRequest.Header)
336335
outboundRequest.Header["User-Agent"] = []string{"Webhook Sentry/0.1"}
336+
outboundRequest.ContentLength = r.ContentLength
337337
return p.roundTripper.RoundTrip(outboundRequest)
338338
}
339339

0 commit comments

Comments
 (0)