module Shrine::Plugins::DownloadEndpoint

  1. lib/shrine/plugins/download_endpoint.rb

The download_endpoint plugin provides a Rack endpoint for downloading uploaded files from specified storages. This can be useful when files from your storage isn't accessible over URL (e.g. database storages) or if you want to authenticate your downloads. It requires the Roda gem.

# Gemfile
gem "roda" # dependency of the download_endpoint plugin

You can configure the plugin with the path prefix which the endpoint will be mounted on.

plugin :download_endpoint, prefix: "attachments"

The endpoint should then be mounted on the specified prefix:

# config.ru (Rack)
map "/attachments" do
  run Shrine.download_endpoint
end

# OR

# config/routes.rb (Rails)
Rails.application.routes.draw do
  mount Shrine.download_endpoint => "/attachments"
end

Any uploaded file can be downloaded through this endpoint. When a file is requested, its content will be efficiently streamed from the storage into the response body.

Links to the download endpoint are generated by calling UploadedFile#download_url instead of the usual UploadedFile#url.

uploaded_file.download_url #=> "/attachments/eyJpZCI6ImFkdzlyeTM5ODJpandoYWla"

Note that streaming the file through your app might impact the request throughput of your app, depending on which web server is used. It's recommended to either configure a CDN to serve these files:

plugin :download_endpoint, host: "http://abc123.cloudfront.net"

or configure the endpoint to redirect to the direct file URL:

plugin :download_endpoint, redirect: true
# or
plugin :download_endpoint, redirect: -> (uploaded_file, request) do
  # return URL which the request will redirect to
end

Alternatively, you can stream files yourself from your controller using the rack_response plugin, which this plugin uses internally.

Methods

Public Class

  1. configure
  2. load_dependencies

Public Class methods

configure (uploader, opts = {})

Accepts the following options:

:prefix

The location where the download endpoint was mounted. If it was mounted at the root level, this should be set to nil.

:host

The host that you want the download URLs to use (e.g. your app's domain name or a CDN). By default URLs are relative.

:disposition

Can be set to “attachment” if you want that the user is always prompted to download the file when visiting the download URL. The default is “inline”.

:redirect

If set to true, requests will redirect to the direct file URL. If set to a proc object, the proc will called with the UploadedFile instance and the Rack::Request object, and is expected to return the URL to which the request will redirect to. Defaults to false, meaning that the file content will be served through the endpoint.

[show source]
# File lib/shrine/plugins/download_endpoint.rb, line 90
def self.configure(uploader, opts = {})
  uploader.opts[:download_endpoint_storages] = opts.fetch(:storages, uploader.opts[:download_endpoint_storages])
  uploader.opts[:download_endpoint_prefix] = opts.fetch(:prefix, uploader.opts[:download_endpoint_prefix])
  uploader.opts[:download_endpoint_disposition] = opts.fetch(:disposition, uploader.opts.fetch(:download_endpoint_disposition, "inline"))
  uploader.opts[:download_endpoint_host] = opts.fetch(:host, uploader.opts[:download_endpoint_host])
  uploader.opts[:download_endpoint_redirect] = opts.fetch(:redirect, uploader.opts.fetch(:download_endpoint_redirect, false))

  Shrine.deprecation("The :storages download_endpoint option is deprecated, you should use UploadedFile#download_url for generating URLs to the download endpoint.") if uploader.opts[:download_endpoint_storages]

  uploader.assign_download_endpoint(App) unless uploader.const_defined?(:DownloadEndpoint)
end
load_dependencies (uploader, opts = {})
[show source]
# File lib/shrine/plugins/download_endpoint.rb, line 65
def self.load_dependencies(uploader, opts = {})
  uploader.plugin :rack_response
end