---
title: Shrine 2.17.0
---

## New features

* The `download_endpoint` plugin now accepts ad-hoc options when creating the
  endpoint instance, which override any plugin options.

  ```rb
  Shrine.download_endpoint(disposition: "attachment")
  ```

* The `Shrine::Attacher#assign_remote_url` method in the `remote_url` plugin
  now accepts additional options forwarded to `Shrine#upload`.

  ```rb
  attacher.assign_remote_url(url, metadata: { "mime_type" => "text/plain" })
  ```

* The `Shrine::Attacher#assign_data_uri` method has been added to the
  `data_uri` plugin, which accepts additional `Shrine#upload` options.

  ```rb
  attacher.assign_data_uri(uri, metadata: { "filename" => "custom.txt" })
  ```

* The `default_url` plugin now accepts a `:host` option for specifying the URL
  host.

  ```rb
  plugin :default_url, host: "https://example.com"

  Attacher.default_url { "/#{name}/missing.png" }
  ```
  ```rb
  user.avatar_url #=> "https://example.com/avatar/missing.png"
  ```

## Other improvements

* The `derivation_endpoint` plugin now works correctly when `moving` plugin
  is loaded and `upload: true` is set.

* The `Shrine.download_endpoint` object is now compatible with the Rails router
  again (this was broken in Shrine 2.15.0).

* The `rack_response` plugin was in certain cases producing `nil`-chunks for
  the response body, which caused exceptions with some web servers. This has
  now been fixed.

* The `rack_response` plugin now stops retrieving file content that goes past
  the range specified in the `Range` header. This improves performance for
  storage classes that internally use `Down::ChunkedIO`.

* The `derivation_endpoint`, `rack_response`, and `download_endpoint` plugins
  now include `ETag` in the headers of responses, preventing the `Rack::ETag`
  middleware from buffering the response body.

* Fixed inheritance of `process` blocks in the `processing` plugin. Now adding
  `process` blocks in the `Shrine` subclass won't affect the superclass.

* Improved performance of `Shrine::Storage::FileSystem#delete` by switching
  from `Dir.foreach` to `Dir.empty?`.

* The `parsed_json` plugin now accepts hashes with symbol keys.

* The `versions` plugin now accepts string version names in
  `Shrine::Attacher#url`.

* The `versions` plugin now supports returning a hash of versions with string
  names inside the `process` block.

* The `download_endpoint` plugin has been rewritten to use plain Rack, so Roda
  isn't a dependency anymore.

* The endpoint's `#inspect` and `#to_s` outputs in `upload_endpoint`,
  `presign_endpoint`, `download_endpoint`, and `derivation_endpoint` plugins
  have been simplified. Now the `rake routes` command output in Rails apps
  should be much more compact.

  ```rb
  # BEFORE:
  ImageUploader.upload_endpoint(:cache)  #=> #<Shrine::Plugins::UploadEndpoint::App:0x00007f91bec17dc8 @max_size=nil, @rack_response=nil, @shrine_class=ImageUploader, @storage_key=:cache, @upload=nil, @upload_context=nil>
  ImageUploader.presign_endpoint(:cache) #=> #<Shrine::Plugins::PresignEndpoint::App:0x00007f91beca4ea8 @presign=nil, @presign_location=nil, @presign_options=nil, @rack_response=nil, @shrine_class=ImageUploader, @storage_key=:cache>
  ImageUploader.download_endpoint        #=> #<Class:0x00007f91bed1fa90>
  ImageUploader.derivation_endpoint      #=> #<Shrine::DerivationEndpoint:0x00007f91bed4c900 @options={}, @shrine_class=ImageUploader>

  # AFTER:
  ImageUploader.upload_endpoint(:cache)  #=> #<ImageUploader::UploadEndpoint(:cache)>
  ImageUploader.presign_endpoint(:cache) #=> #<ImageUploader::PresignEndpoint(:cache)>
  ImageUploader.download_endpoint        #=> #<ImageUploader::DownloadEndpoint>
  ImageUploader.derivation_endpoint      #=> #<ImageUploader::DerivationEndpoint>
  ```

* The `derivation_endpoint` plugin is now compatible with Rack 1.6.

* The `metadata_attributes` plugin now preserves `Attacher#assign` method
  signature, by retaining the second `options` argument.

## Backwards compatibility

* The support for MRI 2.3 has been dropped.

* The automatic filename fallback was removed from the `:marcel` analyzer in
  `determine_mime_type` plugin, as in some cases it caused MIME type to be
  incorrectly determined and could cause potential security issues. You can
  still opt in for it:

  ```rb
  plugin :determine_mime_type, analyzer: :marcel, analyzer_options: { filename_fallback: true }
  ```

* The `Shrine::Plugins::UploadEndpoint::App` class from the `upload_endpoint`
  plugin has been renamed to `Shrine::UploadEndpoint`. The old constant will be
  removed in Shrine 3.

* The `Shrine::Plugins::PresignEndpoint::App` class from the `presign_endpoint`
  plugin has been renamed to `Shrine::PresignEndpoint`. The old constant will
  be removed in Shrine 3.

* The `Shrine::Plugins::DownloadEndpoint::App` class is not a `Roda` subclass
  anymore, it's now a PORO whose instance responds to `#call`. This shouldn't
  affect your code unless you were calling Roda methods on that class.

* The plugin options of `upload_endpoint`, `presign_endpoint`, and
  `download_endpoint` are now internally stored in a different place in
  `Shrine.opts`. This shouldn't affect your code unless you were accessing
  these options directly.

* The `Shrine::UrlSigner` internal class in `derivation_endpoint` plugin has
  been updated. This shouldn't affect your code unless you were
  using/overriding that class.
