title: Shrine 2.13.0

New features

require "aws-sdk-cloudfront"

signer = Aws::CloudFront::UrlSigner.new(
  key_pair_id:      "cf-keypair-id",
  private_key_path: "./cf_private_key.pem",
)

Shrine::Storage::S3.new(signer: signer.method(:signed_url))
Shrine.storages = {
  cache: Shrine::Storage::S3.new(upload_options: { acl: "public-read" }, **options),
  store: Shrine::Storage::S3.new(upload_options: { acl: "public-read" }, **options),
}

Shrine.plugin :default_url_options,
  cache: { public: true },
  store: { public: true }

Now you can achieve the same thing just by setting public: true when initializing the S3 storage.

Shrine.storages = {
  cache: Shrine::Storage::S3.new(public: true, **options),
  store: Shrine::Storage::S3.new(public: true, **options),
}
Shrine.plugin :infer_extension, force: true

This is useful for when you want to normalize the file extensions of uploaded files.

uploader.upload(File.open("image.jpg"))  #
uploader.upload(File.open("image.jpeg")) # all these will be uploaded with a .jpeg extension
uploader.upload(File.open("image.JPG"))  #
uploaded_file = uploader.upload(file, metadata: { "filename" => "my-file.txt" })
uploaded_file.original_filename    #=> "my-file.txt"

Furthermore, Shrine::Attacher#assign now forwards any additional options to Shrine#upload, so you can also override metadata when attaching files.

photo.image_attacher.assign(file, metadata: { "mime_type" => "text/plain" })

Other improvements

s3 = Shrine::Storage::S3.new(endpoint: "https://minio.example.com")
s3.url("foo")                                     #=> "https://my-s3-endpoint.com/foo"
s3.url("foo", host: "https://123.cloudfront.net") #=> "https://123.cloudfront.net/foo"

s3 = Shrine::Storage::S3.new(endpoint: "https://my-s3-endpoint.com", force_path_style: true, **options)
s3.url("foo")                                     #=> "https://my-s3-endpoint.com/my-bucket/foo"
s3.url("foo", host: "https://123.cloudfront.net") #=> "https://123.cloudfront.net/foo"
# old behaviour
s3.url("foo", host: "https://example.com/prefix/") #=> "https://example.com/foo"
# new behaviour
s3.url("foo", host: "https://example.com/prefix/") #=> "https://example.com/prefix/foo"

Backwards compatibility

s3.url("foo", host: "https://example.com/my-bucket/")

Also, in this case Shrine::Storage::S3 will now first copy the whole file onto disk before uploading it (previously only a chunk of the input file was copied to disk at a time).

If you’re uploading files of unknown size (ones where #size is not defined or returns nil), you should upgrade to aws-sdk-s3 1.14 or higher.