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

Restore ActionDispatch::Http::UploadedFile compatibility with IO.copy_stream #35382

Conversation

janko
Copy link
Contributor

@janko janko commented Feb 23, 2019

Shrine relies on ActionDispatch::Http::UploadedFile working with IO.copy_stream. In #28676, #to_path method was added to ActionDispatch::Http::UploadedFile, which broke usage with IO.copy_stream (shrinerb/shrine#353):

source = ActionDispatch::Http::UploadedFile.new(...)
IO.copy_stream(source, destination)
# ~> TypeError: can't convert ActionDispatch::Http::UploadedFile to IO (ActionDispatch::Http::UploadedFile#to_io gives Tempfile)

Normally IO.copy_stream just calls #read on the source object to read the content. However, when #to_path is defined, IO.copy_stream calls #to_io in order to retrieve the raw File object. In this case it trips up, because ActionDispatch::Http::UploadedFile#to_io returned a Tempfile object, which is not an IO subclass.

We fix this by modifying #to_io to return an actual File object (which is a IO subclass). I think this is also more correct behaviour in general.

I had to test this with an actual Tempfile object, so then I also updated the rest of the tests to use an actual Tempfile objects (which simplified them).

@rails-bot rails-bot bot added the actionpack label Feb 23, 2019
In rails#28676 the `#to_path` method was
added to `ActionDispatch::Http::UploadedFile`. This broke usage with
`IO.copy_stream`:

  source = ActionDispatch::Http::UploadedFile.new(...)
  IO.copy_stream(source, destination)
  # ~> TypeError: can't convert ActionDispatch::Http::UploadedFile to IO (ActionDispatch::Http::UploadedFile#to_io gives Tempfile)

Normally `IO.copy_stream` just calls `#read` on the source object.
However, when `#to_path` is defined, `IO.copy_stream` calls `#to_io` in
order to retrieve the raw `File` object. In that case it trips up,
because `ActionDispatch::Http::UploadedFile#to_io` returned a `Tempfile`
object, which is not an `IO` subclass.

We fix this by having `#to_io` return an actual `File` object.
@janko janko force-pushed the restore-io-copy-stream-compatibility-with-uploaded-file branch from b2215cf to 32b2942 Compare February 23, 2019 22:37
@georgeclaghorn georgeclaghorn merged commit d4d53ec into rails:master Feb 24, 2019
@janko janko deleted the restore-io-copy-stream-compatibility-with-uploaded-file branch February 24, 2019 01:47
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.

None yet

3 participants