Derivatives and content disposition filename

Hi,

I’m using Shrine 3.2.0 and I’m having trouble getting derivatives to download with an appropriate filename. Every derivative ends up with a random filename such as “image_processingXYZ.jpg”, which is not ideal.

I’ve found a few issues and google groups issues on this, but can’t seem to find anything for the new derivatives functionality.

I don’t necessarily need to keep the original filename for the derivatives, but I would like to have a uuid type filename for these. An option to use the original filename would also be helpful.

The stored location for the images works correctly based on the pretty_location plugin, but the filename metadata which is used for the content disposition has the random temp file name.

As a work around for this, I’m getting a filename based on the file id, but it would be great if I could control the derivative filename.

plugin :url_options, store: -> (file, _options) do
  # file.original_filename is something like "image_processingXYZ.jpg"
  { response_content_disposition: ContentDisposition.attachment(File.basename(file.id))
end

Is there a way to access the attachment record in that code block? file is a Shrine::UploadedFile or a Tempfile, so I’m not sure how to access the attachment metadata to look up the original metadata, and not the metadata for the derivative.

Any help is appreciated!

Hi Mike,

Yes, the url_options plugin works on the Shrine::UploadedFile level, and doesn’t have access to the attachment. This decision was made so that it works whether user calls record.attachment_url(:foo) or record.attachment(:foo).url or record.attachment_derivatives[:foo].url.

If it’s enough to solve this problem for new uploads, you can specify content disposition at the time of the upload, where you have access to the record:

plugin :upload_options, store: -> (io, derivative: nil, record: nil, name: nil, metadata: {}, **) do
  metadata["filename"] # original filename
  record # the record instance
  name # attachment name

  { content_disposition: "attachment" } if derivative
end

This doesn’t sound like an ideal default behaviour. For derivatives it would be better to have no content disposition specified, so that it defaults to the basename of the upload location.

I think the S3 storage should not set any :content_disposition by default, it seems like a wrong decision now. I will investigate the backwards compatibility consequences of getting rid of that.