-
Notifications
You must be signed in to change notification settings - Fork 832
Harden HTTP Response Body Handling #4489
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
@@ -433,7 +433,7 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co | |||
return bidder, nil | |||
} | |||
|
|||
func (a *adapter) MakeTimeoutNotification(req *adapters.RequestData) (*adapters.RequestData, []error) { | |||
func (a *adapter) MakeTimeoutNotification(req *adapters.RequestData) (*adapters.RequestData, error) { |
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.
Not directly related. Updated the function signature since only a single error is used.
Code coverage summaryNote:
audienceNetworkRefer here for heat map coverage report
|
defer func() { | ||
if _, err := io.Copy(io.Discard, resp.Body); err != nil { | ||
glog.Errorf("[agmaAnalytics] Draining response body failed: %v", err) | ||
} |
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.
The response body must be fully read and closed to ensure connection reuse. Discarding the body is especially needed when the body content is ignored / not used.
@@ -238,13 +238,13 @@ func (f *PriceFloorFetcher) fetchAndValidate(config config.AccountFloorFetch) (* | |||
} | |||
|
|||
if len(floorResp) > (config.MaxFileSizeKB * 1024) { | |||
glog.Errorf("Recieved invalid floor data from URL: %s, reason : floor file size is greater than MaxFileSize", config.URL) | |||
glog.Errorf("Received invalid floor data from URL: %s, reason : floor file size is greater than MaxFileSize", config.URL) |
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.
Unrelated typo spotted while editing this file.
Code coverage summaryNote:
audienceNetworkRefer here for heat map coverage report
|
"net/http" | ||
"net/url" | ||
"time" | ||
|
||
"github.com/docker/go-units" | ||
"github.com/golang/glog" | ||
) | ||
|
||
func fetchConfig(client *http.Client, endpoint *url.URL) (*Configuration, error) { | ||
res, err := client.Get(endpoint.String()) |
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.
Do we want to add a timeout to this fetch while we are 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.
I agree we should. I don't know the pubstack analytics module well enough to implement it. Will reach out to pubstack to implement.
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.
Discussed offline. I will reach out to pubstack to see what a reasonable timeout would be and we can update it in another PR.
@@ -27,7 +28,12 @@ func NewHttpSender(client *http.Client, endpoint string) Sender { | |||
if err != nil { |
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.
Do we want to add a timeout just above to the http request?
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 agree we should. I don't know the pubstack analytics module well enough to implement it. Will reach out to pubstack to implement.
@@ -52,14 +52,20 @@ func (rc *RateConverter) fetch() (*Rates, error) { | |||
if err != nil { |
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.
Do we want to add a timeout to the http request just above?
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.
Yes. Good catch. I added a configurable timeout with a default of 60 seconds. In test from my machine, latency is around 30ms. Since this isn't part of the real time auction flow, happy to set this to a higher limit considering there is no limit today. Hosts can reduce if they find it necessary or we can revisit the default later if there are no concerns right now.
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.
Discussed offline. We can address this in a follow-up PR.
Looks good other than optionally adding timeouts to the calls that have no timeout context. |
if _, err := io.Copy(io.Discard, httpResp.Body); err != nil { | ||
glog.Errorf("Error while draining fetched floor response body: %v", err) | ||
} | ||
httpResp.Body.Close() |
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.
Is Body.Close()
neccessary? We do call Close()
on this body in unpackResponse()
s caller function FetchRequests(...)
80 func (fetcher *HttpFetcher) FetchRequests(ctx context.Context, requestIDs []string, impIDs []string) (requestData map[string]json.RawMessage, impData map[string]json.RawMessage, errs []error) {
81 *-- 8 lines: if len(requestIDs) == 0 && len(impIDs) == 0 {---------------------------------------------------------------------------------------------------------
89
90 httpResp, err := ctxhttp.Do(ctx, fetcher.client, httpReq)
91 if err != nil {
92 return nil, nil, []error{err}
93 }
94 defer httpResp.Body.Close()
95 requestData, impData, errs = unpackResponse(httpResp)
96 return
97 }
stored_requests/backends/http_fetcher/fetcher.go
Do we get a panic for calling Close()
twice?
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.
Not sure I follow. unpackResponse does not close the body.
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.
Line 94 inside FetchRequests(...)
defers the call to httpResp.Body.Close()
. Is it ok if unpackResponse(httpResp)
calls httpResp.Body.Close()
and we do another httpResp.Body.Close()
before FetchRequests(...)
goes out of scope?
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 got this one wrong @SyntaxNode. Nevermind
Code coverage summaryNote:
audienceNetworkRefer here for heat map coverage report
|
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.
LGTM
No description provided.