Conversation
| // WithProxy adds a per-request proxy URL to the request context. | ||
| // When provided, this proxy will be used instead of the client-level default. | ||
| // Pass an empty string to force a direct connection, bypassing any default proxy. | ||
| func WithProxy(ctx context.Context, proxyURL string) context.Context { |
| if proxyURL == "" { | ||
| return nil, nil | ||
| } | ||
| if cached, ok := d.proxyCache.Load(proxyURL); ok { |
There was a problem hiding this comment.
try cache first before resolving
| } | ||
|
|
||
| func (d *customDialer) CustomDialContext(ctx context.Context, network, address string) (conn net.Conn, err error) { | ||
| if d.proxyDialer != nil && d.proxyNeedsHostname { |
There was a problem hiding this comment.
use context resolved proxy instead of static d.proxyDialer
| @@ -396,12 +457,16 @@ func (d *customDialer) CustomDial(network, address string) (net.Conn, error) { | |||
|
|
|||
| func (d *customDialer) CustomDialTLSContext(ctx context.Context, network, address string) (net.Conn, error) { | |||
There was a problem hiding this comment.
CustomDialTLSContext and CustomDialContext are the two sites where implementation bugs are likely, special care needed here in the review.
The dialParallel just pass through the rp, and the changes in dialSingle are minimal
|
Should have looked through the PRs before writing this, possible duplicate of #160 😵💫 |
|
Hi there @AltayAkkus - it is definitely similar to #160 and we had some unresolved questions there that we never surfaced on GitHub. Primarily there were some concerns around how ProxyTypes were being treated. Both are pretty large changes to how gowarc operates and need to be done carefully to ensure we don't break anything and are "in scope" to gowarc. One of our design philosophies was to reduce anything Zeno specific we were adding to gowarc to ensure it could be used in different projects. Proxy support was historically in Zeno itself, but I can definitely see why it would be added to gowarc. We'll also need to think a little on this one as well. |
|
I think that #160 is better than this branch (even though I dont understand why |
#362 and #136 in Zeno request to have more granular control of the proxies which are used by
gowarc.Previous implementation
Previously, the proxy was defined statically per-client via
NewWARCWritingHTTPClient.More specificially, in the
newCustomDialer()gowarc/dialer.go
Lines 243 to 261 in ee15d6a
The
d *customDialerreturned by that method is then re-used for each request made using the Client. It is fully static and set once when creating the Client.When you
client.Do(req)it enters heregowarc/dialer.go
Lines 397 to 408 in ee15d6a
gowarc/dialer.go
Lines 350 to 360 in ee15d6a
called by
New implementation
gowarcalready has a way to configure something for a single request only, viaContextKeygowarc/dialer.go
Lines 31 to 42 in ee15d6a
This is where I implemented the
ContextKeyProxy,gowarccan retrieve the configured proxy per request rather than reading the staticd.proxyDialer. For DNS reasons we have to deal with the proxies at theCustomDialContextlevel too, see READMEgowarc/README.md
Lines 119 to 143 in ee15d6a
The proxyDialers are cached by their connection string in a map, so they can be re-used. They are handed over from the DialContext to
dialParalleland/ordialSingle.That's why the diff of dialer.go looks more complicated than I wished for, sorry.
Tests
The
client_test.goalready hosts a SOCKS5 proxy for testing, I consolidated the bringup intostartSOCKS5ServerThe method returns the connection string, a counter which increments on each request through the proxy, and a cleanup/stop
func(so we can omit the goroutine channel signalling logic)The proxy counts how many requests are passed through himself with a things-go/go-socks5 RuleSet
I validated the per-request proxy feature using that counter, see
client_test.go