-
Notifications
You must be signed in to change notification settings - Fork 9
Add a SafeHttpClient method #82
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
Conversation
This adds a tracing method to a client that will make sure any request to a reserved IP is canceled at DNSDone time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally I like the approach but I think that you can do a few small things to make it more clear:
- override only the transport
- use anonymous functions
- use an optional logger
Like this (mostly untested)
type noLocalTransport struct {
inner http.RoundTripper
errlog logrus.FieldLogger
}
func (no noLocalTransport) RoundTrip(req *http.Request) (*http.Response, error) {
ctx, cancel := context.WithCancel(req.Context())
ctx = httptrace.WithClientTrace(ctx, &httptrace.ClientTrace{
DNSDone: func(info httptrace.DNSDoneInfo) {
if endpoint := isLocal(info); endpoint != "" {
cancel()
if no.errlog != nil {
no.errlog.WithFields(logrus.Fields{
"original_url": req.URL.String(),
"blocked_endpoint": endpoint,
})
}
}
},
})
req = req.WithContext(ctx)
return no.inner.RoundTrip(req)
}
func isLocal(info httptrace.DNSDoneInfo) string {
return "what was blocked"
}
func newLocalBlocker(trans http.RoundTripper, log logrus.FieldLogger) *noLocalTransport {
if trans == nil {
trans = http.DefaultTransport
}
ret := &noLocalTransport{
inner: trans,
errlog: log.WithField("transport", "local_blocker"),
}
return ret
}
I think that it does less setting on the transport object. I am mostly afraid of some kind of concurrency nightmare in the transport.
http/http_test.go
Outdated
func TestSafeHTTPClient(t *testing.T) { | ||
client := &http.Client{} | ||
|
||
counter := &countServer{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd use the httptest
lib instead. https://golang.org/pkg/net/http/httptest/#Server
http/http.go
Outdated
} | ||
} | ||
|
||
func SafeHttpClient(client *http.Client) *http.Client { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/Http/HTTP
I like that suggestion - plopped that implementation in there |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only needs minor adjustments.
The tests have room for improvement in general.
Also, outer users should be able to allow localhost for testing:
https://github.com/netlify/gotrue/blob/22a973955d0644e0a9163dda4dd8667fce7fcfe7/api/hook_test.go#L48-L49
http/http.go
Outdated
|
||
ctx = httptrace.WithClientTrace(ctx, &httptrace.ClientTrace{ | ||
ConnectStart: func(network, addr string) { | ||
fmt.Printf("Checking network %v\n", addr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be removed because it pollutes logs
http/http.go
Outdated
|
||
if isPrivateIP(ip) { | ||
cancel() | ||
fmt.Println("Canceleing dur to private ip range") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be great to log these and previous errors on the errlog
field of the noLocalTransport
I'm going to update the tests a bit |
I think I was using "unshift" wrong
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks really good.
There is still one case it does not cover:
We want to be able to allow certain ips/ranges inside of tests in other packages.
I propose adding a variadic arg to SafeRountripper
and SafeHTTPClient
for blocks you want to allow.
I'm thinking of this signature:
func SafeHTTPClient(client *http.Client, log logrus.FieldLogger, allowedBlocks ...*net.IPNet) *http.Client {
...
Another way could be to expose a method on the roundtripper to allow blocks temporarily.
There also is a typo in |
Ah, I thought you intended for that to be a follow-up (along with un-inlining this functionality in gotrue). I can put it in here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚢
This adds a tracing method to a client that will make sure
any request to a reserved IP is canceled at DNSDone time