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

Dialogue response body stream safety #1740

Merged
merged 3 commits into from
Jun 15, 2022
Merged

Conversation

carterkozak
Copy link
Contributor

Before this PR

Warnings logged when the response body was closed before fully consuming content due to a runtime.discardEndpoint() followed by response.close() which internally attempts to consume remaining data from a stream that has been disconnected.

After this PR

==COMMIT_MSG==
Dialogue response body stream safety improvements to prevent accidental stream reuse and confusing warnings.
==COMMIT_MSG==

It's fully expected that closing the stream will not be able to consume
remaining bytes, the connection has been severed.
This PR introduces guard rails to prevent attempts to read a closed
stream after response.close has been invoked.
@changelog-app
Copy link

changelog-app bot commented Jun 14, 2022

Generate changelog in changelog/@unreleased

Type

  • Feature
  • Improvement
  • Fix
  • Break
  • Deprecation
  • Manual task
  • Migration

Description

Dialogue response body stream safety improvements to prevent accidental stream reuse and confusing warnings.

Check the box to generate changelog(s)

  • Generate changelog entry

@@ -455,37 +475,73 @@ public void close() {}

private static final class ResponseInputStream extends FilterInputStream {

// Client reference is used to prevent premature termination
@Nullable
private ApacheHttpClientChannels.CloseableClient client;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This client ref was unnecessary due to the strong reference to HttpClientResponse response.

try {
response.close();
} finally {
super.close();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This super.close() call is unnecessary as it may attempt to drain remaining bytes, which is already handled by response.close(). super.close may throw if response.close chose to terminate the connection rather than fully draining.

Comment on lines +283 to +284
if (snapshot == null) {
snapshot = createResponseBody();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

entity.getContent creates a new state tracking wrapper around the delegate InputStream for each invocation, by holding a reference to the single delegate, we can be more confident that state is consistent.

Comment on lines +27 to +28
testRuntimeOnly 'org.apache.logging.log4j:log4j-slf4j-impl'
testRuntimeOnly 'org.apache.logging.log4j:log4j-core'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the logging implementation in place, the reported warnings were very obvious in tests.

@carterkozak carterkozak requested a review from jkozlowski June 14, 2022 15:04
}
} finally {
client = null;
public int read() throws IOException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there some extra testing we can write to check the behavior you're fixing?

Copy link
Contributor

@jkozlowski jkozlowski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this makes sense, but feels awfully complicated to achieve this (Basically discard a connection. Upstream support would be nice

@bulldozer-bot bulldozer-bot bot merged commit 52228c2 into develop Jun 15, 2022
@bulldozer-bot bulldozer-bot bot deleted the ckozak/stream_state branch June 15, 2022 12:22
@svc-autorelease
Copy link
Collaborator

Released 3.62.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants