- The S3 object URLs can now be signed with a custom signer. This enables
serving private objects via AWS CloudFront by signing the URLs with the
signer from the
aws-sdk-cloudfront
gem.
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))
- To make your S3 storage public, previously you needed to do two things: set
the
acl: "public-read"
upload option and set passpublic: true
when generating a 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),
}
- The
:force
option has been added to theinfer_extension
plugin, which makes the extension always determined from the MIME type, regardless of whether it exists or not.
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")) #
Shrine#upload
now accepts a:metadata
option for manually overrding the extracted metadata.
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" })
- It's now possible to use an S3 endpoint which requires bucket name to be in
the URI path (e.g. Minio) with CDNs where bucket name shouldn't be in the URI
path (e.g. CloudFront). Since version 2.11.0, when initializing
Shrine::Storage::S3
with:endpoint
with:force_path_style
, generating an URL with a:host
returned an URI with bucket name in the path. This introduced a regression for anyone relying on previous behaviour, so that change has been reverted, and this is the current behaviour:
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"
- The
:host
option toShrine::Storage::S3#url
now handles URLs with path prefixes, provided that the URL ends with a slash.
# 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"
-
Fixed error that would happen when uploading a file with a filename that had certain combination of UTF-8 characters to
upload_endpoint
. -
The
Content-Type
header inupload_endpoint
andpresign_endpoint
responses now specifiescharset=utf-8
. -
Shrine::Storage::S3
now usesAws::S3::Object#upload_stream
if available when uploading large IO streams which are not file objects, which uses parallelized multipart upload. This can make such uploads finish up to 2x faster. -
Shrine::Storage::S3
now usesAws::S3::Object#upload_stream
if available when uploading files of unknown size. -
The
file
command could sometimes exit successfully, but return acannot open: No such file or directory
on stdout. This is now detected and aShrine::Error
is raised. -
The
upload_endpoint
now returnsUpload Not Valid
error message when file parameter was present but not in correct format (previouslyUpload Not Found
was returned, which was a bit misleading).
- When
Shrine::Storage::S3
is initialized with:endpoint
with:force_path_style
, a file URL generated with a:host
will not include the bucket name in the URL path anymore. Users relying on this behaviour should update their code to include the bucket name in the:host
URL path.
s3.url("foo", host: "https://example.com/my-bucket/")
-
Using aws-sdk-s3 older than 1.14 with
Shrine::Storage::S3
when uploading files with unknown size is now deprecated and won't be supported in Shrine 3.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 returnsnil
), you should upgrade to aws-sdk-s3 1.14 or higher.