sdubois
(Sébastien Dubois)
June 25, 2022, 10:35am
1
Our Rails 7.0.3 app high-res images are scaled down before rendering them for the user (using image_tag blob.representation(resize_to_limit: X)
). However in our admin page we also want to be able to view the unscaled original version, so for that specific purpose we render it straight with image_tag my_blob
. The problem is that if the image is too big, only the first 4.88 MB (= 5000 kB) are downloaded, no matter how fast the internet connection is (and visually, the jpg image is partly blank at the bottom). NB: The image can be downloaded fine when retrieving it directly from the underlying AWS S3 storage (not using the Rails app).
How to render images >5 MB with Active Storage?
sdubois
(Sébastien Dubois)
June 25, 2022, 10:58am
2
OK there’s apparently a fix merged (not available in 7.0.3).
rails:main
← feliperaul:fix_activestorage_proxy_downloads_files_larger_5mb
opened 04:08PM - 15 May 22 UTC
### Summary
This PR fixes the issue described in another PR (#44679), that ma… kes it impossible to download files larger than 5mb stored in S3-like services using the proxy mode. The proposed PR in #44679 didn't solve the issue for me, so this is why I'm opening a new one.
As described in greater detail in my comment [here](https://github.com/rails/rails/pull/44679#issuecomment-1126960722), Rails's `ActiveStorage::Blobs::ProxyController` uses `#send_blob_stream`, which in turn uses `#send_stream`, which is provided by the `ActionController::Live` concern.
`ActiveStorage::Blobs::ProxyController` doesn't include `ActionController::Live` directly; it does however include `ActiveStorage::Streaming`, which in turns includes `ActionController::Live`, so that's how `#send_blob_stream` can use `#send_stream`.
However, downloads over 5mb in size were being truncated at ~ 5mb, and/or halting, when using S3-like storage services.
The cause is that `ActiveStorage::Streaming` is a regular module, and not a Rails concern. So even tough it includes `ActionController::Live`, the fact it is not a concern made so that `ActionController::Live`'s `module ClassMethods` was not being extended, and that's essential to wrap the response in a `Live::Response` instance that makes the streaming response > 5mb work without a glitch.
Btw, the fact that `ActiveStorage::Streaming` is located in a `/concerns` subfolder and it's not a concern is also telling that the intention was to make it a concern.
This PR is a one-liner that makes `ActiveStorage::Streaming` a concern, so it has proper concern dependency resolution, making so that `ActionController::Live` that it includes has it's class method installed.
In the PR #44679, it was proposed to remove the `Content-Length` header, but as per my [comment](https://github.com/rails/rails/pull/44679#issuecomment-1126796327) in that issue, that didn't solve the issues for me, while this does.
1 Like