Module: Hanami::Action::Mime

Defined in:
lib/hanami/action/mime.rb,
lib/hanami/action/mime/request_mime_weight.rb

Overview

rubocop:disable Metrics/ModuleLength

Since:

  • 0.1.0

Defined Under Namespace

Classes: RequestMimeWeight

Constant Summary collapse

TYPES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Most commom MIME Types used for responses

Since:

  • 1.0.0

{
  txt: "text/plain",
  html: "text/html",
  json: "application/json",
  manifest: "text/cache-manifest",
  atom: "application/atom+xml",
  avi: "video/x-msvideo",
  bmp: "image/bmp",
  bz: "application/x-bzip",
  bz2: "application/x-bzip2",
  chm: "application/vnd.ms-htmlhelp",
  css: "text/css",
  csv: "text/csv",
  flv: "video/x-flv",
  gif: "image/gif",
  gz: "application/x-gzip",
  h264: "video/h264",
  ico: "image/vnd.microsoft.icon",
  ics: "text/calendar",
  jpg: "image/jpeg",
  js: "application/javascript",
  mp4: "video/mp4",
  mov: "video/quicktime",
  mp3: "audio/mpeg",
  mp4a: "audio/mp4",
  mpg: "video/mpeg",
  oga: "audio/ogg",
  ogg: "application/ogg",
  ogv: "video/ogg",
  pdf: "application/pdf",
  pgp: "application/pgp-encrypted",
  png: "image/png",
  psd: "image/vnd.adobe.photoshop",
  rss: "application/rss+xml",
  rtf: "application/rtf",
  sh: "application/x-sh",
  svg: "image/svg+xml",
  swf: "application/x-shockwave-flash",
  tar: "application/x-tar",
  torrent: "application/x-bittorrent",
  tsv: "text/tab-separated-values",
  uri: "text/uri-list",
  vcs: "text/x-vcalendar",
  wav: "audio/x-wav",
  webm: "video/webm",
  wmv: "video/x-ms-wmv",
  woff: "application/font-woff",
  woff2: "application/font-woff2",
  wsdl: "application/wsdl+xml",
  xhtml: "application/xhtml+xml",
  xml: "application/xml",
  xslt: "application/xslt+xml",
  yml: "text/yaml",
  zip: "application/zip"
}.freeze
ANY_TYPE =

Since:

  • 0.1.0

"*/*"

Class Method Summary collapse

Class Method Details

.best_q_match(q_value_header, available_mimes = TYPES.values) ⇒ 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.

Patched version of Rack::Utils.best_q_match.



182
183
184
185
186
187
188
189
# File 'lib/hanami/action/mime.rb', line 182

def best_q_match(q_value_header, available_mimes = TYPES.values)
  ::Rack::Utils.q_values(q_value_header).each_with_index.map { |(req_mime, quality), index|
    match = available_mimes.find { |am| ::Rack::Mime.match?(am, req_mime) }
    next unless match

    RequestMimeWeight.new(req_mime, quality, index, match)
  }.compact.max&.format
end

.content_type_with_charset(content_type, charset) ⇒ String

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.

Returns a string combining the given content type and charset, intended for setting as a ‘Content-Type` header.

Examples:

Mime.content_type_with_charset("application/json", "utf-8")
# => "application/json; charset=utf-8"

Parameters:

  • content_type (String)
  • charset (String)

Returns:

  • (String)

Since:

  • 2.0.0



149
150
151
# File 'lib/hanami/action/mime.rb', line 149

def content_type_with_charset(content_type, charset)
  "#{content_type}; charset=#{charset}"
end

.detect_format(content_type, config) ⇒ Symbol?

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.

Returns a format name for the given content type.

The format name will come from the configured formats, if such a format is configured there, or instead from the default list of formats in ‘Mime::TYPES`.

Returns nil if no matching format can be found.

This is used to return the format name a Response.

Examples:

detect_format("application/jsonl charset=utf-8", config) # => :json

Returns:

  • (Symbol, nil)

See Also:

Since:

  • 2.0.0



93
94
95
96
97
98
# File 'lib/hanami/action/mime.rb', line 93

def detect_format(content_type, config)
  return if content_type.nil?

  ct = content_type.split(";").first
  config.formats.format_for(ct) || TYPES.key(ct)
end

.detect_format_and_content_type(value, config) ⇒ Array<(Symbol, String)>

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.

Returns a format name and content type pair for a given format name or content type string.

Examples:

detect_format_and_content_type(:json, config)
# => [:json, "application/json"]

detect_format_and_content_type("application/json", config)
# => [:json, "application/json"]

Unknown format name

detect_format_and_content_type(:unknown, config)
# raises Hanami::Action::UnknownFormatError

Unknown content type

detect_format_and_content_type("application/unknown", config)
# => [nil, "application/unknown"]

Returns:

  • (Array<(Symbol, String)>)

Raises:

Since:

  • 2.0.0



124
125
126
127
128
129
130
131
132
133
# File 'lib/hanami/action/mime.rb', line 124

def detect_format_and_content_type(value, config)
  case value
  when Symbol
    [value, format_to_mime_type(value, config)]
  when String
    [detect_format(value, config), value]
  else
    raise UnknownFormatError.new(value)
  end
end

.enforce_accept(request, config) ⇒ 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.

Yields if an action is configured with ‘formats`, the request has an `Accept` header, an none of the Accept types matches the accepted formats. The given block is expected to halt the request handling.

If any of these conditions are not met, then the request is acceptable and the method returns without yielding.

See Also:

Since:

  • 2.0.0



203
204
205
206
207
208
209
210
# File 'lib/hanami/action/mime.rb', line 203

def enforce_accept(request, config)
  return unless request.accept_header?

  accept_types = ::Rack::Utils.q_values(request.accept).map(&:first)
  return if accept_types.any? { |mime_type| accepted_mime_type?(mime_type, config) }

  yield
end

.enforce_content_type(request, config) ⇒ 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.

Yields if an action is configured with ‘formats`, the request has a `Content-Type` header (or a `default_requst_format` is configured), and the content type does not match the accepted formats. The given block is expected to halt the request handling.

If any of these conditions are not met, then the request is acceptable and the method returns without yielding.

See Also:

Since:

  • 2.0.0



224
225
226
227
228
229
230
231
232
# File 'lib/hanami/action/mime.rb', line 224

def enforce_content_type(request, config)
  content_type = request.content_type

  return if content_type.nil?

  return if accepted_mime_type?(content_type, config)

  yield
end

.response_content_type_with_charset(request, config) ⇒ String

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.

Returns a string combining a MIME type and charset, intended for setting as the ‘Content-Type` header for the response to the given request.

This uses the request’s ‘Accept` header (if present) along with the configured formats to determine the best content type to return.

Returns:

  • (String)

See Also:

Since:

  • 2.0.0



165
166
167
168
169
170
# File 'lib/hanami/action/mime.rb', line 165

def response_content_type_with_charset(request, config)
  content_type_with_charset(
    response_content_type(request, config),
    config.default_charset || Action::DEFAULT_CHARSET
  )
end