Question about file download endpoint with usage of UploadedFile

Hi,

We are currently using shrine with aws and are not relying on an uploader part from it. We just define some s3 storages (using minio locally) and use the presign and move to logic to get files uploaded to our storage which is working fine. We are also using serverside encryption with keys provided by us (sse-c). Now we are trying to use the download endpoint plugin in order to get the object directly from the storage layer and serve it but it seems the download endpoint and more specifically rack_response cannot deal with a file opened directly from s3, we are using roda to serve this request and when we do the following:

file = Shrine.storages[file_model.store.to_sym].open(
         'our_file_key',
          sse_customer_algorithm: 'AES256',
          sse_customer_key:       S3FILES_ENCRYPTION_KEY,
          sse_customer_key_md5:   Digest::MD5.hexdigest(S3FILES_ENCRYPTION_KEY),
        )             
 
Shrine::Plugins::RackResponse::FileResponse.new(file).call()

Then we get back undefined method `opened?’ for #Down::ChunkedIO:0x0000561ecab2c778 (NoMethodError).

So the question is if rack response is meant to work with this or not? Cause i found some history for the download endpoint in the past (see https://github.com/shrinerb/shrine/commit/7a90f0302853f4b03e54c2eeff6c16e90e92a8a2) which makes it work for Down::ChunkedIO but it seems to not longer support this.

Could somebody explain if this was intended and if there are workarounds for it? We know that serving files like this is not performant at all and we probably will to serve it differently in the future with nginx proxying but would still be interesting to know.

The rack_response plugin is meant to work only with Shrine::UploadedFile instances, as it calls methods specific to these objects.

You should be able to modify your code to use a Shrine::UploadedFile instance instead:

uploaded_file = Shrine.uploaded_file(
  storage: file_model.store.to_sym,
  id: "our_file_key",
)

uploaded_file.open(
  sse_customer_algorithm: 'AES256',
  sse_customer_key:       S3FILES_ENCRYPTION_KEY,
  sse_customer_key_md5:   Digest::MD5.hexdigest(S3FILES_ENCRYPTION_KEY),
)

uploaded_file.to_rack_response