@@ -5,11 +5,13 @@ import (
55 "context"
66 "net/http"
77 "net/http/httptest"
8+ "net/url"
89 "sort"
910 "strconv"
1011 "time"
1112
1213 "github.com/chromedp/cdproto/har"
14+ "github.com/gorilla/handlers"
1315 "github.com/speakeasy-api/speakeasy-go-sdk/internal/bodymasking"
1416 "github.com/speakeasy-api/speakeasy-go-sdk/internal/log"
1517 "go.uber.org/zap"
@@ -18,20 +20,7 @@ import (
1820type harBuilder struct {}
1921
2022func (h * harBuilder ) buildHarFile (ctx context.Context , cw * captureWriter , r * http.Request , startTime time.Time , c * controller ) * har.HAR {
21- queryParams := r .URL .Query ()
22- for key , values := range queryParams {
23- queryParams .Del (key )
24-
25- for _ , value := range values {
26- mask , ok := c .queryStringMasks [key ]
27- if ok {
28- value = mask
29- }
30-
31- queryParams .Add (key , value )
32- }
33- }
34- r .URL .RawQuery = queryParams .Encode ()
23+ resolvedURL := getResolvedURL (r , c )
3524
3625 return & har.HAR {
3726 Log : & har.Log {
@@ -40,15 +29,15 @@ func (h *harBuilder) buildHarFile(ctx context.Context, cw *captureWriter, r *htt
4029 Name : sdkName ,
4130 Version : speakeasyVersion ,
4231 },
43- Comment : "request capture for " + r . URL .String (),
32+ Comment : "request capture for " + resolvedURL .String (),
4433 Entries : []* har.Entry {
4534 {
4635 StartedDateTime : startTime .Format (time .RFC3339Nano ),
4736 Time : float64 (timeSince (startTime ).Milliseconds ()),
48- Request : h .getHarRequest (ctx , cw , r , c ),
37+ Request : h .getHarRequest (ctx , cw , r , c , resolvedURL ),
4938 Response : h .getHarResponse (ctx , cw , r , startTime , c ),
50- Connection : r . URL .Port (),
51- ServerIPAddress : r . URL .Hostname (),
39+ Connection : resolvedURL .Port (),
40+ ServerIPAddress : resolvedURL .Hostname (),
5241 Cache : & har.Cache {},
5342 Timings : & har.Timings {
5443 Send : - 1 ,
@@ -61,8 +50,50 @@ func (h *harBuilder) buildHarFile(ctx context.Context, cw *captureWriter, r *htt
6150 }
6251}
6352
53+ func getResolvedURL (r * http.Request , c * controller ) * url.URL {
54+ var url * url.URL
55+
56+ // Taking advantage of Gorilla's ProxyHeaders parsing to resolve Forwarded headers
57+ handlers .ProxyHeaders (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
58+ url = r .URL
59+ })).ServeHTTP (nil , r )
60+
61+ queryParams := url .Query ()
62+ for key , values := range queryParams {
63+ queryParams .Del (key )
64+
65+ for _ , value := range values {
66+ mask , ok := c .queryStringMasks [key ]
67+ if ok {
68+ value = mask
69+ }
70+
71+ queryParams .Add (key , value )
72+ }
73+ }
74+ url .RawQuery = queryParams .Encode ()
75+
76+ if url .IsAbs () {
77+ return url
78+ }
79+
80+ if url .Scheme == "" {
81+ if r .TLS != nil {
82+ url .Scheme = "https"
83+ } else {
84+ url .Scheme = "http"
85+ }
86+ }
87+
88+ if url .Host == "" {
89+ url .Host = r .Host
90+ }
91+
92+ return url
93+ }
94+
6495//nolint:funlen
65- func (h * harBuilder ) getHarRequest (ctx context.Context , cw * captureWriter , r * http.Request , c * controller ) * har.Request {
96+ func (h * harBuilder ) getHarRequest (ctx context.Context , cw * captureWriter , r * http.Request , c * controller , url * url. URL ) * har.Request {
6697 reqHeaders := []* har.NameValuePair {}
6798 for key , headers := range r .Header {
6899 for _ , headerValue := range headers {
@@ -123,7 +154,7 @@ func (h *harBuilder) getHarRequest(ctx context.Context, cw *captureWriter, r *ht
123154
124155 return & har.Request {
125156 Method : r .Method ,
126- URL : r . URL .String (),
157+ URL : url .String (),
127158 Headers : reqHeaders ,
128159 QueryString : reqQueryParams ,
129160 BodySize : bodySize ,
0 commit comments