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

Raise EPIPE for all unseekable channels #7415

Open
wants to merge 1 commit into
base: jruby-9.3
Choose a base branch
from

Conversation

headius
Copy link
Member

@headius headius commented Oct 17, 2022

This relates to the discussion in discourse/mini_mime#38 where the proposed patch must work around JRuby's silent seek failure for some types of resources (at least classloader resources).

The patch here will now raise EPIPE for all NIO channels that are not seekable through some means. It is rather aggressive given the old logic that only raised if a channel was not seekable AND not selectable (for reasons long lost).

This relates to the discussion in discourse/mini_mime#38 where the
proposed patch must work around JRuby's silent seek failure for
some types of resources (at least classloader resources).

The patch here will now raise EPIPE for all NIO channels that are
not seekable through some means. It is rather aggressive given the
old logic that only raised if a channel was not seekable AND not
selectable (for reasons long lost).
@ikaronen-relex
Copy link
Contributor

The silent failure was originally introduced as a workaround for #3399. I'm all for getting rid of it, but we should probably make sure there's no regression for that issue.

@ikaronen-relex
Copy link
Contributor

FWIW, I did a bit of source digging: it looks like the error in #3399 was triggered by this line in Rack::File#each back in Rack 1.5. The code has since been moved and refactored, but a similar seek seems to still happen on this line in Rack::Files::BaseIterator#each_range_part.

The "fix" in a4cc5ee made the seek fail silently, which is probably fine in the common case where there's only one range that starts at position 0, but it also probably made actual HTTP range requests with a non-zero start offset silently return incorrect data when the underlying resource is non-seekable. Or, rather, it probably allowed such requests to continue breaking silently, since I doubt they ever worked correctly for non-seekable resources in the first place.

It would probably be worth filing a Rack issue about this, but in the mean time we also probably shouldn't break the current Rack code until it's been fixed (in all supported Rack versions). I wonder if it would be possible to detect no-op seeks that don't actually change the current file position (e.g. by maintaining our own file position counter) and only silently ignoring those. 🤔

@headius
Copy link
Member Author

headius commented Nov 3, 2022

@ikaronen-relex Thanks for that research! I agree we should not go forward with the breaking change for now, but I'm unsure how to proceed.

It seems logical that classloader resources should not be seekable, since the only way to access them is through an InputStream that does not support positioning. However, we don't want to break rack applications that might expect the silent seek failure as you discovered.

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

Successfully merging this pull request may close these issues.

None yet

2 participants