Module: Refile
- Defined in:
- lib/refile.rb,
lib/refile/app.rb,
lib/refile/file.rb,
lib/refile/type.rb,
lib/refile/rails.rb,
lib/refile/version.rb,
lib/refile/attacher.rb,
lib/refile/download.rb,
lib/refile/signature.rb,
lib/refile/attachment.rb,
lib/refile/file_double.rb,
lib/refile/custom_logger.rb,
lib/refile/random_hasher.rb,
lib/refile/backend_macros.rb,
lib/refile/backend/file_system.rb,
lib/refile/attachment_definition.rb,
lib/refile/rails/attachment_helper.rb,
lib/refile/attachment/active_record.rb,
lib/refile/attachment/multiple_attachments.rb
Defined Under Namespace
Modules: ActiveRecord, Attachment, AttachmentHelper, Backend, BackendMacros Classes: App, Attacher, AttachmentDefinition, Confirm, CustomLogger, Download, Engine, Error, File, FileDouble, Invalid, InvalidFile, InvalidID, InvalidMaxSize, InvalidUrl, RandomHasher, Signature, TooManyRedirects, Type
Constant Summary collapse
- VERSION =
"0.7.3"
Class Attribute Summary collapse
-
.allow_downloads_from ⇒ Array[String], :all
A list of names which identify backends in the global backend registry.
-
.allow_origin ⇒ String
Value for Access-Control-Allow-Origin header.
-
.allow_uploads_to ⇒ Array[String], :all
A list of names which identify backends in the global backend registry.
-
.app ⇒ Refile::App?
A shortcut to the instance of the Rack application.
-
.app_host ⇒ String?
The host name that the Rack application can be reached at.
-
.automount ⇒ Boolean
Should the rack application be automounted in a Rails app?.
-
.cdn_host ⇒ String?
The host name of a CDN distribution that the Rack application can be reached at.
-
.content_max_age ⇒ Integer
Value for Cache-Control: max-age=<value in seconds> header.
-
.logger ⇒ Logger
Logger that should be used by rack application.
-
.mount_point ⇒ String
Where should the rack application be mounted? The default is ‘attachments’.
-
.secret_key ⇒ String
Value for generating signed attachment urls to protect from DoS.
Class Method Summary collapse
-
.app_url(host: nil, prefix: nil) ⇒ String
Generates a URL to the Refile application.
-
.attachment_presign_url(object, name, host: nil, prefix: nil) ⇒ String
Receives an instance of a class which has used the Attachment#attachment macro to generate an attachment column, and the name of this column, and based on this generates a URL to a App where a presign object for the backend can be retrieved.
-
.attachment_upload_url(object, name, host: nil, prefix: nil) ⇒ String
Receives an instance of a class which has used the Attachment#attachment macro to generate an attachment column, and the name of this column, and based on this generates a URL to a App where files can be uploaded.
-
.attachment_url(object, name, *args, expires_at: nil, host: nil, prefix: nil, filename: nil, format: nil, force_download: nil) ⇒ String?
Generate a URL to an attachment.
-
.backends ⇒ Hash{String => Backend}
A global registry of backends.
-
.cache ⇒ Backend
A shortcut to retrieving the backend named “cache” from the global registry.
-
.cache=(backend) ⇒ Object
A shortcut to setting the backend named “cache” in the global registry.
-
.configure { ... } ⇒ Object
Yield the Refile module as a convenience for configuring multiple config options at once.
-
.extract_content_type(uploadable) ⇒ String?
Extract the content type from an uploadable object.
-
.extract_filename(uploadable) ⇒ String?
Extract the filename from an uploadable object.
-
.file_url(file, *args, expires_at: nil, host: nil, prefix: nil, filename:, format: nil, force_download: nil) ⇒ String?
Receives a File and generates a URL to it.
-
.host ⇒ Object
deprecated
Deprecated.
use Refile.cdn_host instead
-
.host=(host) ⇒ Object
deprecated
Deprecated.
use Refile.cdn_host instead
- .parse_json(data, *args) ⇒ Object private
-
.presign_url(backend, host: nil, prefix: nil) ⇒ String
Receives a Refile backend and returns a URL to the Refile application where a presign object for the backend can be retrieved.
-
.processor(name, processor = nil) {|Refile::File| ... } ⇒ void
Adds a processor.
-
.processors ⇒ Hash{String => Proc}
A global registry of processors.
-
.store ⇒ Backend
A shortcut to retrieving the backend named “store” from the global registry.
-
.store=(backend) ⇒ Object
A shortcut to setting the backend named “store” in the global registry.
-
.token(path) ⇒ String?
Generate a signature for a given path concatenated with the configured secret token.
-
.types ⇒ Hash{Symbol => Refile::Type}
A global registry of types.
-
.upload_url(backend, host: nil, prefix: nil) ⇒ String
Receives a Refile backend and returns a URL to the Refile application where files can be uploaded.
-
.valid_token?(path, token) ⇒ Boolean
Check if the given token is a valid token for the given path.
Class Attribute Details
.allow_downloads_from ⇒ Array[String], :all
A list of names which identify backends in the global backend registry. The Rack application allows GET requests to only the backends specified in this config option. This defaults to ‘:all`, allowing files from all backends to be downloaded.
103 104 105 |
# File 'lib/refile.rb', line 103 def allow_downloads_from @allow_downloads_from end |
.allow_origin ⇒ String
Value for Access-Control-Allow-Origin header
113 114 115 |
# File 'lib/refile.rb', line 113 def allow_origin @allow_origin end |
.allow_uploads_to ⇒ Array[String], :all
A list of names which identify backends in the global backend registry. The Rack application allows POST requests to only the backends specified in this config option. This defaults to ‘[“cache”]`, only allowing direct uploads to the cache backend.
95 96 97 |
# File 'lib/refile.rb', line 95 def allow_uploads_to @allow_uploads_to end |
.app ⇒ Refile::App?
A shortcut to the instance of the Rack application. This should be set when the application is initialized. ‘refile/rails` sets this value.
43 44 45 |
# File 'lib/refile.rb', line 43 def app @app end |
.app_host ⇒ String?
The host name that the Rack application can be reached at. If not set, Refile will use an absolute URL without hostname. You should only change this setting if you are running the Refile app on a different domain than your main application.
If you are simply running the Refile app behind a CDN you’ll want to change cdn_host instead.
The difference between app_host and cdn_host is that the latter only affects URLs generated by file_url and the Refile::AttachmentHelper#attachment_url and Refile::AttachmentHelper#attachment_image_tag helpers, whereas the former also affects upload_url, presign_url and the Refile::AttachmentHelper#attachment_field helper.
75 76 77 |
# File 'lib/refile.rb', line 75 def app_host @app_host end |
.automount ⇒ Boolean
Should the rack application be automounted in a Rails app?
If set to false then Refile.app should be mounted in the Rails application routes.rb with the options ‘at: Refile.mount_point, as: :refile_app`
The default is true.
133 134 135 |
# File 'lib/refile.rb', line 133 def automount @automount end |
.cdn_host ⇒ String?
The host name of a CDN distribution that the Rack application can be reached at. If not set, Refile will use an absolute URL without hostname. It is strongly recommended to run Refile behind a CDN and to set this to the hostname of the CDN distribution.
The ‘cdn_host` setting is used when retrieving files, but not when uploading new files, since uploads should normally not go through the CDN.
A protocol relative URL is recommended for this value.
57 58 59 |
# File 'lib/refile.rb', line 57 def cdn_host @cdn_host end |
.content_max_age ⇒ Integer
Value for Cache-Control: max-age=<value in seconds> header
118 119 120 |
# File 'lib/refile.rb', line 118 def content_max_age @content_max_age end |
.logger ⇒ Logger
Logger that should be used by rack application
108 109 110 |
# File 'lib/refile.rb', line 108 def logger @logger end |
.mount_point ⇒ String
Where should the rack application be mounted? The default is ‘attachments’.
123 124 125 |
# File 'lib/refile.rb', line 123 def mount_point @mount_point end |
.secret_key ⇒ String
Value for generating signed attachment urls to protect from DoS
138 139 140 |
# File 'lib/refile.rb', line 138 def secret_key @secret_key end |
Class Method Details
.app_url(host: nil, prefix: nil) ⇒ String
Generates a URL to the Refile application.
The host defaults to app_host. You can also override the host via the ‘host` option. Normally the Refile app will not be mounted at the root but rather at some other path, the `prefix` option allows you to override this setting, and if not set it will fall back to mount_point.
284 285 286 287 288 289 290 291 |
# File 'lib/refile.rb', line 284 def app_url(host: nil, prefix: nil) host ||= Refile.app_host prefix ||= Refile.mount_point uri = URI(host.to_s) uri.path = prefix || "/" uri.to_s end |
.attachment_presign_url(object, name, host: nil, prefix: nil) ⇒ String
Receives an instance of a class which has used the Refile::Attachment#attachment macro to generate an attachment column, and the name of this column, and based on this generates a URL to a App where a presign object for the backend can be retrieved.
443 444 445 446 447 |
# File 'lib/refile.rb', line 443 def (object, name, host: nil, prefix: nil) backend = object.send(:"#{name}_attachment_definition").cache presign_url(backend, host: host, prefix: prefix) end |
.attachment_upload_url(object, name, host: nil, prefix: nil) ⇒ String
Receives an instance of a class which has used the Refile::Attachment#attachment macro to generate an attachment column, and the name of this column, and based on this generates a URL to a App where files can be uploaded.
424 425 426 427 428 |
# File 'lib/refile.rb', line 424 def (object, name, host: nil, prefix: nil) backend = object.send(:"#{name}_attachment_definition").cache upload_url(backend, host: host, prefix: prefix) end |
.attachment_url(object, name, *args, expires_at: nil, host: nil, prefix: nil, filename: nil, format: nil, force_download: nil) ⇒ String?
Generate a URL to an attachment. Receives an instance of a class which has used the Refile::Attachment#attachment macro to generate an attachment column, and the name of this column, and based on this generates a URL to a App.
Optionally the name of a processor and arguments to it can be appended.
If the filename option is not given, the filename is taken from the metadata stored in the attachment, or eventually falls back to the ‘name`.
The host defaults to cdn_host, which is useful for serving all attachments from a CDN. You can also override the host via the ‘host` option.
Returns ‘nil` if there is no file attached.
400 401 402 403 404 405 406 407 408 409 |
# File 'lib/refile.rb', line 400 def (object, name, *args, expires_at: nil, host: nil, prefix: nil, filename: nil, format: nil, force_download: nil) attacher = object.send(:"#{name}_attacher") file = attacher.get return unless file filename ||= attacher.basename || name.to_s format ||= attacher.extension file_url(file, *args, expires_at: expires_at, host: host, prefix: prefix, filename: filename, format: format, force_download: force_download) end |
.backends ⇒ Hash{String => Backend}
A global registry of backends.
143 144 145 |
# File 'lib/refile.rb', line 143 def backends @backends ||= {} end |
.cache ⇒ Backend
A shortcut to retrieving the backend named “cache” from the global registry.
217 218 219 |
# File 'lib/refile.rb', line 217 def cache backends["cache"] end |
.cache=(backend) ⇒ Object
A shortcut to setting the backend named “cache” in the global registry.
224 225 226 |
# File 'lib/refile.rb', line 224 def cache=(backend) backends["cache"] = backend end |
.configure { ... } ⇒ Object
Yield the Refile module as a convenience for configuring multiple config options at once.
232 233 234 |
# File 'lib/refile.rb', line 232 def configure yield self end |
.extract_content_type(uploadable) ⇒ String?
Extract the content type from an uploadable object. If the content type cannot be determined, this method will return ‘nil`.
255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/refile.rb', line 255 def extract_content_type(uploadable) if uploadable.respond_to?(:content_type) uploadable.content_type else filename = extract_filename(uploadable) if filename content_type = MIME::Types.of(filename).first content_type.to_s if content_type end end end |
.extract_filename(uploadable) ⇒ String?
Extract the filename from an uploadable object. If the filename cannot be determined, this method will return ‘nil`.
241 242 243 244 245 246 247 248 |
# File 'lib/refile.rb', line 241 def extract_filename(uploadable) path = if uploadable.respond_to?(:original_filename) uploadable.original_filename elsif uploadable.respond_to?(:path) uploadable.path end ::File.basename(path) if path end |
.file_url(file, *args, expires_at: nil, host: nil, prefix: nil, filename:, format: nil, force_download: nil) ⇒ String?
Receives a File and generates a URL to it.
Optionally the name of a processor and arguments to it can be appended.
The ‘filename` option must be given.
The host defaults to cdn_host, which is useful for serving all attachments from a CDN. You can also override the host via the ‘host` option.
Returns ‘nil` if the supplied file is `nil`.
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 |
# File 'lib/refile.rb', line 319 def file_url(file, *args, expires_at: nil, host: nil, prefix: nil, filename:, format: nil, force_download: nil) return unless file host ||= Refile.cdn_host backend_name = Refile.backends.key(file.backend) filename = Rack::Utils.escape(filename) filename << "." << format.to_s if format && !filename.downcase.end_with?(format.to_s.downcase) base_path = ::File.join("", backend_name, *args.map(&:to_s), file.id.to_s, filename) if expires_at base_path += "?expires_at=#{expires_at.to_i}" # UNIX timestamp end base_path += "?force_download=true" if force_download ::File.join(app_url(prefix: prefix, host: host), token(base_path), base_path) end |
.host ⇒ Object
use cdn_host instead
78 79 80 81 |
# File 'lib/refile.rb', line 78 def host warn "Refile.host is deprecated, please use Refile.cdn_host instead" cdn_host end |
.host=(host) ⇒ Object
use cdn_host instead
84 85 86 87 |
# File 'lib/refile.rb', line 84 def host=(host) warn "Refile.host is deprecated, please use Refile.cdn_host instead" self.cdn_host = host end |
.parse_json(data, *args) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
488 489 490 491 492 |
# File 'lib/refile.rb', line 488 def parse_json(data, *args) JSON.parse(data.to_s, *args) rescue JSON::ParserError nil end |
.presign_url(backend, host: nil, prefix: nil) ⇒ String
Receives a Refile backend and returns a URL to the Refile application where a presign object for the backend can be retrieved.
364 365 366 |
# File 'lib/refile.rb', line 364 def presign_url(backend, host: nil, prefix: nil) ::File.join(upload_url(backend, host: host, prefix: prefix), "presign") end |
.processor(name, processor = nil) {|Refile::File| ... } ⇒ void
This method returns an undefined value.
Adds a processor. The processor must respond to ‘call`, both receiving and returning an IO-like object. Alternatively a block can be given to this method which also receives and returns an IO-like object.
An IO-like object is recommended to be an instance of the ‘IO` class or one of its subclasses, like `File` or a `StringIO`, or a `Refile::File`. It can also be any other object which responds to `size`, `read`, `eof`? `rewind` and `close` and mimics the behaviour of IO objects for these methods.
193 194 195 196 |
# File 'lib/refile.rb', line 193 def processor(name, processor = nil, &block) processor ||= block processors[name.to_s] = processor end |
.processors ⇒ Hash{String => Proc}
A global registry of processors. These will be used by the Rack application to manipulate files prior to serving them up to the user, based on options sent trough the URL. This can be used for example to resize images or to convert files to another file format.
153 154 155 |
# File 'lib/refile.rb', line 153 def processors @processors ||= {} end |
.store ⇒ Backend
A shortcut to retrieving the backend named “store” from the global registry.
202 203 204 |
# File 'lib/refile.rb', line 202 def store backends["store"] end |
.store=(backend) ⇒ Object
A shortcut to setting the backend named “store” in the global registry.
209 210 211 |
# File 'lib/refile.rb', line 209 def store=(backend) backends["store"] = backend end |
.token(path) ⇒ String?
Generate a signature for a given path concatenated with the configured secret token.
Raises an error if no secret token is configured.
459 460 461 462 463 464 465 466 467 468 469 |
# File 'lib/refile.rb', line 459 def token(path) if secret_key.nil? error = "Refile.secret_key was not set.\n\n" error << "Please add the following to your Refile configuration and restart your application:\n\n" error << "```\nRefile.secret_key = '#{SecureRandom.hex(64)}'\n```\n\n" raise error end OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha1"), secret_key, path) end |
.types ⇒ Hash{Symbol => Refile::Type}
A global registry of types. Currently, types are simply aliases for a set of content types, but their functionality may expand in the future.
161 162 163 |
# File 'lib/refile.rb', line 161 def types @types ||= {} end |
.upload_url(backend, host: nil, prefix: nil) ⇒ String
Receives a Refile backend and returns a URL to the Refile application where files can be uploaded.
348 349 350 351 352 |
# File 'lib/refile.rb', line 348 def upload_url(backend, host: nil, prefix: nil) backend_name = Refile.backends.key(backend) ::File.join(app_url(host: host, prefix: prefix), backend_name) end |
.valid_token?(path, token) ⇒ Boolean
Check if the given token is a valid token for the given path.
480 481 482 483 484 485 |
# File 'lib/refile.rb', line 480 def valid_token?(path, token) expected = Digest::SHA1.hexdigest(token(path)) actual = Digest::SHA1.hexdigest(token) expected == actual end |