123456789_123456789_123456789_123456789_123456789_

Module: ActionDispatch::Http::MimeNegotiation

Relationships & Source Files
Namespace Children
Exceptions:
Extension / Inclusion / Inheritance Descendants
Included In:
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
Defined in: actionpack/lib/action_dispatch/http/mime_negotiation.rb

Constant Summary

Class Method Summary

::ActiveSupport::Concern - Extended

class_methods

Define class methods from given block.

included

Evaluate given block in context of base class, so that you can write class macros here.

prepended

Evaluate given block in context of base class, so that you can write class macros here.

Instance Attribute Summary

Instance Method Summary

DSL Calls

included

[ GitHub ]


17
18
19
# File 'actionpack/lib/action_dispatch/http/mime_negotiation.rb', line 17

included do
  mattr_accessor :ignore_accept_header, default: false
end

Instance Attribute Details

#formats (rw)

[ GitHub ]

  
# File 'actionpack/lib/action_dispatch/http/mime_negotiation.rb', line 69

def formats
  fetch_header("action_dispatch.request.formats") do |k|
    v = if params_readable?
      Array(Mime[parameters[:format]])
    elsif use_accept_header && valid_accept_header
      accepts
    elsif extension_format = format_from_path_extension
      [extension_format]
    elsif xhr?
      [Mime[:js]]
    else
      [Mime[:html]]
    end

    v = v.select do |format|
      format.symbol || format.ref == "*/*"
    end

    set_header k, v
  end
end

#formats=(extensions) (rw)

Sets the formats by string extensions. This differs from #format= by allowing you to set multiple, ordered formats, which is useful when you want to have a fallback.

In this example, the :iphone format will be used if it’s available, otherwise it’ll fallback to the :html format.

class ApplicationController < ActionController::Base
  before_action :adjust_format_for_iphone_with_html_fallback

  private
    def adjust_format_for_iphone_with_html_fallback
      request.formats = [ :iphone, :html ] if request.env["HTTP_USER_AGENT"][/iPhone/]
    end
end
[ GitHub ]

  
# File 'actionpack/lib/action_dispatch/http/mime_negotiation.rb', line 136

def formats=(extensions)
  parameters[:format] = extensions.first.to_s
  set_header "action_dispatch.request.formats", extensions.collect { |extension|
    Mime::Type.lookup_by_extension(extension)
  }
end

#params_readable?Boolean (readonly, private)

[ GitHub ]

  
# File 'actionpack/lib/action_dispatch/http/mime_negotiation.rb', line 165

def params_readable? # :doc:
  parameters[:format]
rescue *RESCUABLE_MIME_FORMAT_ERRORS
  false
end

#should_apply_vary_header?Boolean (readonly)

[ GitHub ]

  
# File 'actionpack/lib/action_dispatch/http/mime_negotiation.rb', line 156

def should_apply_vary_header?
  !params_readable? && use_accept_header && valid_accept_header
end

#variant (rw)

[ GitHub ]

  
# File 'actionpack/lib/action_dispatch/http/mime_negotiation.rb', line 102

def variant
  @variant ||= ActiveSupport::ArrayInquirer.new
end

#variant=(variant) (rw)

Sets the variant for template.

[ GitHub ]

  
# File 'actionpack/lib/action_dispatch/http/mime_negotiation.rb', line 92

def variant=(variant)
  variant = Array(variant)

  if variant.all? { |v| v.is_a?(Symbol) }
    @variant = ActiveSupport::ArrayInquirer.new(variant)
  else
    raise ArgumentError, "request.variant must be set to a Symbol or an Array of Symbols."
  end
end

Instance Method Details

#accepts

Returns the accepted MIME type for the request.

[ GitHub ]

  
# File 'actionpack/lib/action_dispatch/http/mime_negotiation.rb', line 44

def accepts
  fetch_header("action_dispatch.request.accepts") do |k|
    header = get_header("HTTP_ACCEPT").to_s.strip

    v = if header.empty?
      [content_mime_type]
    else
      Mime::Type.parse(header)
    end
    set_header k, v
  rescue ::Mime::Type::InvalidMimeType => e
    raise InvalidType, e.message
  end
end

#content_mime_type

The MIME type of the HTTP request, such as Mime.

[ GitHub ]

  
# File 'actionpack/lib/action_dispatch/http/mime_negotiation.rb', line 22

def content_mime_type
  fetch_header("action_dispatch.request.content_type") do |k|
    v = if get_header("CONTENT_TYPE") =~ /^([^,\;]*)/
      Mime::Type.lookup($1.strip.downcase)
    else
      nil
    end
    set_header k, v
  rescue ::Mime::Type::InvalidMimeType => e
    raise InvalidType, e.message
  end
end

#content_type

[ GitHub ]

  
# File 'actionpack/lib/action_dispatch/http/mime_negotiation.rb', line 35

def content_type
  content_mime_type && content_mime_type.to_s
end

#format(view_path = [])

Returns the MIME type for the format used in the request.

GET /posts/5.xml   | request.format => Mime[:xml]
GET /posts/5.xhtml | request.format => Mime[:html]
GET /posts/5       | request.format => Mime[:html] or Mime[:js], or request.accepts.first
[ GitHub ]

  
# File 'actionpack/lib/action_dispatch/http/mime_negotiation.rb', line 65

def format(view_path = [])
  formats.first || Mime::NullType.instance
end

#format=(extension)

Sets the format by string extension, which can be used to force custom formats that are not controlled by the extension.

class ApplicationController < ActionController::Base
  before_action :adjust_format_for_iphone

  private
    def adjust_format_for_iphone
      request.format = :iphone if request.env["HTTP_USER_AGENT"][/iPhone/]
    end
end
[ GitHub ]

  
# File 'actionpack/lib/action_dispatch/http/mime_negotiation.rb', line 117

def format=(extension)
  parameters[:format] = extension.to_s
  set_header "action_dispatch.request.formats", [Mime::Type.lookup_by_extension(parameters[:format])]
end

#format_from_path_extension (private)

[ GitHub ]

  
# File 'actionpack/lib/action_dispatch/http/mime_negotiation.rb', line 180

def format_from_path_extension # :doc:
  path = get_header("action_dispatch.original_path") || get_header("PATH_INFO")
  if match = path && path.match(/\.(\w+)\z/)
    Mime[match.captures.first]
  end
end

#negotiate_mime(order)

Returns the first MIME type that matches the provided array of MIME types.

[ GitHub ]

  
# File 'actionpack/lib/action_dispatch/http/mime_negotiation.rb', line 144

def negotiate_mime(order)
  formats.each do |priority|
    if priority == Mime::ALL
      return order.first
    elsif order.include?(priority)
      return priority
    end
  end

  order.include?(Mime::ALL) ? format : nil
end

#use_accept_header (private)

[ GitHub ]

  
# File 'actionpack/lib/action_dispatch/http/mime_negotiation.rb', line 176

def use_accept_header # :doc:
  !self.class.ignore_accept_header
end

#valid_accept_header (private)

[ GitHub ]

  
# File 'actionpack/lib/action_dispatch/http/mime_negotiation.rb', line 171

def valid_accept_header # :doc:
  (xhr? && (accept.present? || content_mime_type)) ||
    (accept.present? && !accept.match?(BROWSER_LIKE_ACCEPTS))
end