Skip to content

Conversation

@j-baker
Copy link
Contributor

@j-baker j-baker commented Sep 6, 2022

Jira: https://issues.redhat.com/browse/UNDERTOW-2157

2.2.x PR: #1829
2.3.x PR: #1830
2.4.x PR: #1831
undertow-ee PR: undertow-io/undertow-ee#25

BufferedWriteableOutputStream is currently implemented by:

  1. UndertowOutputStream
  2. ServletOutputStreamImpl

These have two different behaviours. In UndertowOutputStream, I believe that if the input FileChannel's position is 0, it transfers the whole channel, and if it's non-zero, it crashes.

In ServletOutputStreamImpl, I think the behaviour is something more like:

  1. If there is no listener set, transfer the bytes between the current position and end of file.
  2. If there is a listener set, transfer the bytes between the current position and end of file, setting the input channel's position as well.

This PR makes the behaviour be more consistent and adds a new, clearer API, deprecating the old one.

  1. Clarify the contract of BufferedWriteableOutputStream.transferTo as being the ServletOutputStreamImpl's behaviour, since it has a superset of the UndertowOutputStream's functionality.
  2. Never set the position of the input channel in ServletOutputStreamImpl, since it leads to inconsistent behaviour depending on whether the listener is set and seems incongruent with the contract of the underlying FileChannel apis.
  3. Add an explicit transferFrom(FileChannel source, long startPosition, long count) method to the interface and implement in both implementations. The current 'transferFrom' method has an extremely confusing signature - it's defined to transfer the rest of the file, which seems unnecessarily specific for such a generic interface.

In theory there is a breaking behaviour change for the user who is relying on their FileChannel's position being set to EOF as a side-effect of the change. Internally to Undertow there is no problem here but obviously this is an API. In my head this is a bugfix but I'd be happy to maintain the present behaviour - I just don't know enough about the 'intended' contract.

@fl4via
Copy link
Member

fl4via commented Sep 17, 2022

thanks for your PR @j-baker ! It will be reviewed shortly and, if approved, added to 2.3.0.Beta2 or 2.3.0.Final.

@fl4via fl4via self-requested a review September 17, 2022 21:26
@fl4via fl4via added the bug fix Contains bug fix(es) label Sep 17, 2022
@fl4via fl4via added the new feature / API change New feature to be introduced or a change to the API (non suitable to minor releases) label Oct 11, 2022
@fl4via fl4via added the waiting PR update Awaiting PR update(s) from contributor before merging label Oct 11, 2022
@fl4via
Copy link
Member

fl4via commented Oct 16, 2025

Because we did not get a response in a timely manner, I will be updating this PR to incorporate the feedback so it can be merged.

@fl4via
Copy link
Member

fl4via commented Oct 16, 2025

After somethought, I decided to remove the new method and keep the fixes. The reason for this is that, with this, it can be backported to old branches, and there is no need for a new method. The interface is used internally. If someone raises a need for a new method, then we will of course introduce it.

@fl4via fl4via added waiting CI check Ready to be merged but waiting for CI check and removed waiting PR update Awaiting PR update(s) from contributor before merging new feature / API change New feature to be introduced or a change to the API (non suitable to minor releases) labels Oct 16, 2025
@fl4via fl4via force-pushed the jbaker/uos_fix branch 3 times, most recently from 592a9e1 to c9e6c9c Compare October 16, 2025 14:22
j-baker and others added 3 commits October 16, 2025 17:57
…y contract, fix bug

BufferedWriteableOutputStream is currently implemented by:

1. UndertowOutputStream
2. ServletOutputStreamImpl

These have two different behaviours. In UndertowOutputStream, I
_believe_ that if the input FileChannel's position is 0, it transfers
the whole channel, and if it's non-zero, it crashes.

In ServletOutputStreamImpl, I think the behaviour is something more
like:
1. If there is no listener set, transfer the bytes between the current
   position and end of file.
2. If there is a listener set, transfer the bytes between the current
   position and end of file, setting the input channel's position as
well.

This PR makes the behaviour be more consistent and adds a new, clearer
API, deprecating the old one.

1. Clarify the contract of BufferedWriteableOutputStream.transferTo as
   being the ServletOutputStreamImpl's behaviour, since it has a
   superset of the UndertowOutputStream's functionality.
2. Never set the position of the input channel in
   ServletOutputStreamImpl, since it leads to inconsistent behaviour
   depending on whether the listener is set and seems incongruent with
   the contract of the underlying FileChannel apis.
3. Add an explicit `transferFrom(FileChannel source, long startPosition,
   long count)` method to the interface and implement in both
   implementations.

In theory there is a breaking behaviour change for the user who is
relying on their FileChannel's position being set to EOF as a
side-effect of the change. Internally to Undertow there is no problem
here.
@fl4via fl4via removed the waiting CI check Ready to be merged but waiting for CI check label Oct 16, 2025
@fl4via fl4via merged commit e9f2742 into undertow-io:main Oct 16, 2025
13 checks passed
@fl4via fl4via added the next release This PR will be merged before next release or has already been merged (for payload double check) label Oct 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug fix Contains bug fix(es) next release This PR will be merged before next release or has already been merged (for payload double check)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants