Skip to main content

Infer Extension

The infer_extension plugin allows deducing the appropriate file extension for the upload location based on the MIME type of the file. This is useful when using data_uri and remote_url plugins, where the file extension might not be known.

plugin :infer_extension

By default an extension will only be inferred if needed to supply an otherwise missing extension. But option force: true will normalize even an already present extension to the extension inferred from MIME type. This could be used to fix incorrect or malicious extensions on user-submitted files.

plugin :infer_extension, force: true

Inferrers

By default, the mini_mime gem will be used for inferring the extension, but you can also choose a different inferrer:

plugin :infer_extension, inferrer: :mime_types

The following inferrers are accepted:

NameDescription
:mini_mime(Default). Uses the mini_mime gem to infer the appropriate extension from MIME type.
:mime_typesUses the mime-types gem to infer the appropriate extension from MIME type.

You can also define your own inferrer, with the possibility to call the built-in inferrers:

plugin :infer_extension, inferrer: -> (mime_type, inferrers) do
  # don't add extension if the file is a text file
  inferrers[:mini_mime].call(mime_type) unless mime_type == "text/plain"
end

API

You can also use methods for inferring extension directly:

Shrine.infer_extension("image/jpeg")
# => ".jpeg"

Shrine.extension_inferrers[:mime_types].call("image/jpeg")
# => ".jpeg"

Instrumentation

If the instrumentation plugin has been loaded, the infer_extension plugin adds instrumentation around inferring extension.

# instrumentation plugin needs to be loaded *before* infer_extension
plugin :instrumentation
plugin :infer_extension

Inferring extension will trigger a extension.shrine event with the following payload:

KeyDescription
:mime_typeMIME type to infer extension from
:uploaderThe uploader class that sent the event

A default log subscriber is added as well which logs these events:

Extension (5ms) – {:mime_type=>"image/jpeg", :uploader=>Shrine}

You can also use your own log subscriber:

plugin :infer_extension, log_subscriber: -> (event) {
  Shrine.logger.info JSON.generate(name: event.name, duration: event.duration, **event.payload)
}
{"name":"extension","duration":5,"mime_type":"image/jpeg","uploader":"Shrine"}

Or disable logging altogether:

plugin :infer_extension, log_subscriber: nil