Skip to content

Commit a76356f

Browse files
authored
Fix HTTP proxy logging (#169)
1 parent 10a1480 commit a76356f

File tree

4 files changed

+101
-46
lines changed

4 files changed

+101
-46
lines changed

cli/integrationtest/httpproxy_test.go

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"path"
1212
"testing"
1313

14+
"github.com/microsoft/tyger/cli/internal/install"
1415
"github.com/stretchr/testify/require"
1516
)
1617

@@ -83,19 +84,37 @@ logPath: /logs
8384

8485
s.CommandSucceeds("start", "tyger-proxy")
8586

86-
squidProxy := "squid:3128"
87+
squidProxy := "http://squid:3128"
8788

8889
// Test tyger using the Squid proxy
89-
_, _, err = s.ShellExec("tyger-proxy", fmt.Sprintf("curl --fail %s/v1/metadata", tygerUri))
90+
stdOut, stdErr, err := s.ShellExec("tyger-proxy", fmt.Sprintf("curl --fail %s/v1/metadata -v", tygerUri))
91+
t.Log("stdout", stdOut)
92+
t.Log("stdErr", stdErr)
9093
require.Error(t, err, "curl should fail because the proxy is not used")
9194
s.ShellExecSucceeds("tyger-proxy", fmt.Sprintf("curl --retry 5 --proxy %s --fail %s/v1/metadata", squidProxy, tygerUri))
9295

9396
// Specify the proxy via environment variable
94-
s.ShellExecSucceeds("tyger-proxy", fmt.Sprintf("export HTTPS_PROXY=%s && tyger login -f /creds.yml && tyger buffer read %s > /dev/null", squidProxy, bufferId))
97+
s.ShellExecSucceeds("tyger-proxy", fmt.Sprintf("export HTTPS_PROXY=%s && tyger login -f /creds.yml --log-level trace && tyger buffer read %s > /dev/null", squidProxy, bufferId))
9598

9699
// Specify the proxy in the config file
97100
s.ShellExecSucceeds("tyger-proxy", fmt.Sprintf("echo 'proxy: %s' >> /creds.yml", squidProxy))
98-
s.ShellExecSucceeds("tyger-proxy", fmt.Sprintf("tyger login -f /creds.yml && tyger buffer read %s > /dev/null", bufferId))
101+
102+
_, stdErr, err = s.ShellExec("tyger-proxy", "tyger login -f /creds.yml --log-level trace --log-format json")
103+
require.NoError(t, err, "tyger login should succeed", stdErr)
104+
105+
parsedLogLines, err := install.ParseJsonLogs([]byte(stdErr))
106+
require.NoError(t, err, "failed to parse log lines")
107+
foundCount := 0
108+
for _, line := range parsedLogLines {
109+
if line["message"] == "Sending request" {
110+
foundCount++
111+
proxyLogEntry := line["proxy"]
112+
require.Equal(t, squidProxy, proxyLogEntry, "proxy argument missing from log entry")
113+
}
114+
}
115+
require.Greater(t, foundCount, 0, "no log entries found with proxy argument")
116+
117+
s.ShellExecSucceeds("tyger-proxy", fmt.Sprintf("tyger buffer read %s > /dev/null", bufferId))
99118

100119
// Now start up the tyger proxy
101120
s.ShellExecSucceeds("tyger-proxy", "tyger-proxy start -f /creds.yml")

cli/internal/client/client.go

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,8 @@ const (
2727
)
2828

2929
var (
30-
underlyingHttpTransport = http.DefaultTransport.(*http.Transport)
31-
DefaultClient *Client
32-
DefaultRetryableClient *retryablehttp.Client
30+
DefaultClient *Client
31+
DefaultRetryableClient *retryablehttp.Client
3332
)
3433

3534
func GetDefaultSocketUrl() string {
@@ -47,10 +46,6 @@ type MakeDialer func(next dialContextFunc) dialContextFunc
4746

4847
type dialContextFunc func(ctx context.Context, network, address string) (net.Conn, error)
4948

50-
type roundTripFunc func(req *http.Request) (*http.Response, error)
51-
52-
func (f roundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) { return f(req) }
53-
5449
type Client struct {
5550
*retryablehttp.Client
5651
transport http.RoundTripper
@@ -93,7 +88,7 @@ func NewClient(opts *ClientOptions) (*Client, error) {
9388
var roundTripper http.RoundTripper = transport
9489

9590
if opts.CreateTransport == nil {
96-
opts.CreateTransport = makeUnixTransport
91+
opts.CreateTransport = makeUnixAwareTransport
9792
}
9893

9994
roundTripper = opts.CreateTransport(roundTripper)
@@ -196,11 +191,28 @@ func (c *TygerClient) ConnectionType() TygerConnectionType {
196191

197192
type HttpTransportOption func(*http.Transport)
198193

194+
func getHttpTransport(roudtripper http.RoundTripper) *http.Transport {
195+
if transport, ok := roudtripper.(*http.Transport); ok {
196+
return transport
197+
}
198+
199+
if exposer, ok := roudtripper.(HttpTransportExposer); ok {
200+
return exposer.GetUnderlyingTransport()
201+
}
202+
203+
panic(fmt.Sprintf("could not get *http.Transport from %T", roudtripper))
204+
}
205+
206+
type HttpTransportExposer interface {
207+
GetUnderlyingTransport() *http.Transport
208+
}
209+
199210
type loggingTransport struct {
200211
http.RoundTripper
201212
}
202213

203214
func (t *loggingTransport) RoundTrip(req *http.Request) (*http.Response, error) {
215+
underlyingHttpTransport := getHttpTransport(t.RoundTripper)
204216
proxy, err := underlyingHttpTransport.Proxy(req)
205217
if err != nil {
206218
return nil, fmt.Errorf("error getting proxy: %w", err)
@@ -232,6 +244,12 @@ func (t *loggingTransport) RoundTrip(req *http.Request) (*http.Response, error)
232244
return resp, err
233245
}
234246

247+
func (t *loggingTransport) GetUnderlyingTransport() *http.Transport {
248+
return getHttpTransport(t.RoundTripper)
249+
}
250+
251+
var _ HttpTransportExposer = &loggingTransport{}
252+
235253
func ParseProxy(proxyString string) (func(r *http.Request) (*url.URL, error), error) {
236254
switch proxyString {
237255
case "none":

cli/internal/client/commandtransport.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ func (c *CommandTransport) RoundTrip(req *http.Request) (*http.Response, error)
9494
return resp, nil
9595
}
9696

97+
func (c *CommandTransport) GetUnderlyingTransport() *http.Transport {
98+
return getHttpTransport(c.next)
99+
}
100+
101+
var _ HttpTransportExposer = &CommandTransport{}
102+
97103
type cleanupOnCloseReader struct {
98104
io.ReadCloser
99105
cleanup func()

cli/internal/client/unixtransport.go

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -35,47 +35,59 @@ func makeUnixDialer(next dialContextFunc) dialContextFunc {
3535
}
3636
}
3737

38-
func makeUnixTransport(next http.RoundTripper) http.RoundTripper {
39-
return roundTripFunc(func(req *http.Request) (*http.Response, error) {
40-
if req.URL == nil {
41-
return next.RoundTrip(req)
42-
}
38+
type unixAwareTransport struct {
39+
next http.RoundTripper
40+
}
4341

44-
var scheme string
45-
switch req.URL.Scheme {
46-
case "http+unix":
47-
scheme = "http"
48-
case "https+unix":
49-
scheme = "https"
50-
default:
51-
return next.RoundTrip(req)
52-
}
42+
func makeUnixAwareTransport(next http.RoundTripper) http.RoundTripper {
43+
return &unixAwareTransport{next: next}
44+
}
5345

54-
parts := strings.SplitN(req.URL.Path, ":", 2)
55-
var socketPath string
56-
var requestPath string
57-
58-
switch len(parts) {
59-
case 1:
60-
socketPath = parts[0]
61-
requestPath = ""
62-
case 2:
63-
socketPath = parts[0]
64-
requestPath = parts[1]
65-
default:
66-
return nil, errors.New("unix transport: invalid path")
67-
}
46+
func (t *unixAwareTransport) RoundTrip(req *http.Request) (*http.Response, error) {
47+
if req.URL == nil {
48+
return t.next.RoundTrip(req)
49+
}
6850

69-
req = req.Clone(req.Context())
51+
var scheme string
52+
switch req.URL.Scheme {
53+
case "http+unix":
54+
scheme = "http"
55+
case "https+unix":
56+
scheme = "https"
57+
default:
58+
return t.next.RoundTrip(req)
59+
}
7060

71-
req.URL.Scheme = scheme
72-
req.URL.Host = encodeUnixPathToHost(socketPath)
73-
req.URL.Path = requestPath
61+
parts := strings.SplitN(req.URL.Path, ":", 2)
62+
var socketPath string
63+
var requestPath string
64+
65+
switch len(parts) {
66+
case 1:
67+
socketPath = parts[0]
68+
requestPath = ""
69+
case 2:
70+
socketPath = parts[0]
71+
requestPath = parts[1]
72+
default:
73+
return nil, errors.New("unix transport: invalid path")
74+
}
75+
76+
req = req.Clone(req.Context())
77+
78+
req.URL.Scheme = scheme
79+
req.URL.Host = encodeUnixPathToHost(socketPath)
80+
req.URL.Path = requestPath
7481

75-
return next.RoundTrip(req)
76-
})
82+
return t.next.RoundTrip(req)
7783
}
7884

85+
func (t *unixAwareTransport) GetUnderlyingTransport() *http.Transport {
86+
return getHttpTransport(t.next)
87+
}
88+
89+
var _ HttpTransportExposer = &unixAwareTransport{}
90+
7991
func encodeUnixPathToHost(socketPath string) string {
8092
return fmt.Sprintf("!unix!%s", encoding.EncodeToString([]byte(socketPath)))
8193
}

0 commit comments

Comments
 (0)