-
Notifications
You must be signed in to change notification settings - Fork 5.3k
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
8257736: InputStream from BodyPublishers.ofInputStream() leaks when IOE happens #1614
Conversation
👋 Welcome back ysuenaga! A progress list of the required criteria for merging this PR into |
Test failure in HotSpot on macOS does not seem to be caused by this change. |
Webrevs
|
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.
Hi Yasumasa,
Thanks for filing the issue and providing a fix.
Before integrating, can you please provide a non regression test that verifies the fix? You can place it in test/jdk/java/net/httpclient/
;
Please also make sure that there is no regression in existing tests.
best regards
-- daniel
need2Read = false; | ||
haveNext = false; |
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 shouldn't be required - need2Read
/haveNext
will be set by hasNext()
; I'd prefer if we kept the logic 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.
We can close the stream in hasNext()
, but we need to move close()
from read()
.
need2Read
and haveNext
will be set to false
if read()
returns -1. However read()
returns -1 when IOE or EOF happen. Is it ok? I concern to change location of close()
- it means the change of side-effect.
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.
You misunderstand. read()
should call close();
when read
returns -1
, hasNext()
will take care of updating need2Read
and haveNext
;
But now I'm no longer convinced that returning -1 when an exception occurs in the wrapped InputStreeam::read
call is the right thing to do.
} catch (IOException ex2) {} | ||
return -1; |
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.
} catch (IOException ex2) {}
return -1;
I wonder if the first exception ex
should actually be rethrown here instead of returning -1
. Have you tried to explore this possibility?
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.
read()
is not have IOE as checked exception, and also currently IOE is ignored.
So I ignored IOE at close()
in this PR to minimize side-effect.
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.
Right. But I am not sure that is the right thing to do. If InputStream::read throws then it's likely that the request body will be missing some bytes, so the request should probably be cancelled/aborted at this point - rather than having a truncated body sent to the server.
@dfuch Thanks for your comment! I updated PR.
Could you review again? |
* @compile ../../../com/sun/net/httpserver/EchoHandler.java | ||
* @compile ../../../com/sun/net/httpserver/FileServerHandler.java | ||
* @build jdk.test.lib.net.SimpleSSLContext | ||
* @build LightWeightHttpServer |
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.
It would be preferable to avoid the use of LightWeightHttpServer in this test. The server-side seems trivial enough to implement locally in the test.
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 with Chris. In addition it will make it possible to check that the server either doesn't receive the request, or get an exception when it tries to read the body bytes.
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 updated testcase not to use LightWeightHttpServer
.
This test is for HttpClient
, and HTTP server might work in undefined behavior if the error happens in client side (I guess it would be handled as an error in most case). So this test does not check request headers/body from the client.
@ChrisHegarty @dfuch could you review new change? It updates a testcase. |
PING: could you review this PR? |
Hi Yasumasa, The new StreamCloseTest seems to be suffering from some race conditions; On windows I saw it failing 29 times out of 50. config StreamCloseTest.setup(): success Maybe you should consider using the servers provided by the HttpServerAdapters interface provided in the test directory, as do many other httpclient tests. Look for tests that implement HttpServerAdapters for an example. |
Thanks @dfuch to notice the error! Could you review again? |
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 updated test looks good. I ran the httpclient tests ~200 times on all platform and the new test didn't fail. Please integrate and I will sponsor (if you need a sponsor?).
@YaSuenag This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 516 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
I'm OpenJDK Reviewer (ysuenaga), so I will integrate it. |
/integrate |
@YaSuenag Since your change was applied there have been 527 commits pushed to the
Your commit was automatically rebased without conflicts. Pushed as commit e3b548a. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
InputStream
fromBodyPublishers.ofInputStream()
is usually closed when the stream reaches EOF. However IOE handler returns without closing.I confirmed this problem in
BodyPublishers.ofInputStream()
, but I thinkBodyPublishers.ofFile()
has same problem because it also useStreamIterator
as well asofInputStream()
.How to reproduce:
Following code (Test.java) attempts to post body from
TestInputStream
which throws IOE inread()
. "close called" is shown on the console ifclose()
is called.Progress
Issue
Reviewers
Download
$ git fetch https://git.openjdk.java.net/jdk pull/1614/head:pull/1614
$ git checkout pull/1614