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

Potential resource leak by not closing the response body #14

Merged
merged 1 commit into from
Jan 17, 2017

Conversation

alexzeitgeist
Copy link
Contributor

The http client should always close the response body - even when there is an error. See this link:

Most of the time when your http request fails the resp variable will be nil and the err variable will be non-nil. However, when you get a redirection failure both variables will be non-nil. This means you can still end up with a leak.

In addition, in order to be able to reuse the connection (if keep alive is enabled on the backend), the client should read and discard the remaining response data.

@dropwhile
Copy link
Member

dropwhile commented Jan 17, 2017

If there is an error handled in the subsequent nil block, the connection is likely not reusable anyway (eg. "use of closed"). Further, a malicious server could result in that io.copy reading data forever (and thus consuming resources forever). If the client aborts, then the later io.copy aborts as well.

As such, I would rather just have a body close there and purposefully not reuse the connection for edge cases. If you change the code to just the defer close wrapped in a resp nil check, I would happily accept the pull req.

@dropwhile
Copy link
Member

Looking at the http transfer code (go1.7) it looks like on close the body is read out up until the content length or maxPostHandlerReadBytes already, and gives up appropriately if the server does something fishy.

ref1
ref2

@alexzeitgeist
Copy link
Contributor Author

alexzeitgeist commented Jan 17, 2017

Ahhh, very interesting. It seems to avoid the issue when dealing with an malicious connection in the first link you referred to they only discard up to 512 bytes to have the connection reused. The code is still in there in the latest commit, and it seems, although it was pointed out that the net/http implementation of close() should take care of the body discard, it doesn't work as expected?

ref

But I am not hard sold on this. I agree that it ought to be done in net/http directly. If you still like I can change the code to just include the defer close wrapped in the resp nil check.

@alexzeitgeist
Copy link
Contributor Author

Ok, after rereading the bug submit and bradfitz' explanation about a race condition that was caused by a flush, I fully agree that we should leave the response body draining code out. I updated the pull request accordingly.

@dropwhile dropwhile merged commit eebb5ac into cactus:master Jan 17, 2017
@dropwhile
Copy link
Member

thanks for the fix!

@alexzeitgeist alexzeitgeist deleted the fix-close-body branch January 18, 2017 09:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants