Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for per-request HTTPS traffic Proxying #23

Merged

Conversation

pspieker-stripe
Copy link

@pspieker-stripe pspieker-stripe commented Nov 21, 2023

Summary

This PR adds a new supported header to goproxy - X-Https-Proxy, which is parsed by goproxy and passed as the Proxy Connect Header to a request that's already being proxied.

This allows support for goproxy to allow per request proxying, so long as the given request passes the X-Https-Proxy header. Previous, there was only support for env variable-level proxying, so all requests from a goproxy instance would have their proxy decisions made based on the given env vars.

Tests

Test with:

go test -v -run ^TestOverrideHttpsProxyAddrsFromEnvWithRequest$

Debug with setting some runtime.Breakpoint() calls, then:

dlv test -- -test.run=^TestOverrideHttpsProxyAddrsFromEnvWithRequest$

and then:

continue

@pspieker-stripe pspieker-stripe force-pushed the pspieker-add-per-request-https-proxy-support branch from bb58097 to 229d23d Compare November 29, 2023 00:35
@pspieker-stripe pspieker-stripe marked this pull request as ready for review November 29, 2023 00:35
@pspieker-stripe pspieker-stripe force-pushed the pspieker-add-per-request-https-proxy-support branch from 229d23d to 82957d4 Compare November 29, 2023 01:29
WIP on tests

linting etc.

Hacky solution to golang bug
@pspieker-stripe pspieker-stripe force-pushed the pspieker-add-per-request-https-proxy-support branch from 82957d4 to def7612 Compare November 29, 2023 01:30
Copy link

@cds2-stripe cds2-stripe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few quick comments. I'm not sure that we need to change anything in httpsProxyAddr()

https.go Outdated

httpsProxy, err := httpsProxyAddr(r.URL, proxy.HttpsProxyAddr)
var httpsProxyURL string
if r.Header[PerRequestHTTPSProxyHeaderKey] != nil && r.Header[PerRequestHTTPSProxyHeaderKey][0] != "" {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we change this to something like:

httpsProxyURL := proxy.HttpsProxyAddr
if r.Header.Get(PerRequestHTTPSProxyHeaderKey) != "" {
    httpsProxyURL = r.Header.Get(PerRequestHTTPSProxyHeaderKey) 
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also clear this header.

Copy link
Author

@pspieker-stripe pspieker-stripe Dec 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack fixed!

We should also clear this header.

Not sure what this means?

https.go Outdated Show resolved Hide resolved
Copy link

@cds2-stripe cds2-stripe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of small changes but otherwise LGTM!

https.go Outdated
@@ -587,6 +593,10 @@ func httpsProxyAddr(reqURL *url.URL, httpsProxy string) (string, error) {
reqSchemeURL.Scheme = "https"

proxyURL, err := cfg.ProxyFunc()(reqSchemeURL)
if err != nil {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to add this twice?

https.go Outdated
HTTPMitmConnect = &ConnectAction{Action: ConnectHTTPMitm, TLSConfig: TLSConfigFromCA(&GoproxyCa)}
RejectConnect = &ConnectAction{Action: ConnectReject, TLSConfig: TLSConfigFromCA(&GoproxyCa)}
httpsRegexp = regexp.MustCompile(`^https:\/\/`)
PerRequestHTTPSProxyHeaderKey = "X-Https-Proxy"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a small nit, but I think we should be more explicit. Can we change this to X-Upstream-Https-Proxy?

proxy_test.go Outdated
}
client := &http.Client{Transport: tr}

// r := string(getOrFail(finalDestinationUrl, client, t))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we delete this?

proxy_test.go Outdated
}

// Ensuring the external proxy was routed through
if resBody[len(resBody)-14:] != "-externalproxy" {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably prefer something less brittle like another strings.Contains

@@ -733,6 +733,91 @@ func TestHttpProxyAddrsFromEnv(t *testing.T) {
os.Unsetenv("https_proxy")
}

func TestOverrideHttpsProxyAddrsFromEnvWithRequest(t *testing.T) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great test! Thanks for getting this working.

@pspieker-stripe pspieker-stripe merged commit 560c3ba into master Dec 6, 2023
5 checks passed
@pspieker-stripe pspieker-stripe deleted the pspieker-add-per-request-https-proxy-support branch December 6, 2023 17:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants