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.

append_features, prepend_features

Instance Attribute Summary

Instance Method Summary

DSL Calls

included

[ GitHub ]


19
20
21
# File 'actionpack/lib/action_dispatch/http/mime_negotiation.rb', line 19

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 67

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.dup
    elsif extension_format = format_from_path_extension
      [extension_format]
    elsif xhr?
      [Mime[:js]]
    else
      [Mime[:html]]
    end

    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 fall back 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 135

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

#has_content_type?Boolean (readonly)

This method is for internal use only.
[ GitHub ]

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

def has_content_type? # :nodoc:
  get_header "CONTENT_TYPE"
end

#params_readable?Boolean (readonly, private)

[ GitHub ]

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

def params_readable?
  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 155

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 100

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 90

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

  if variant.all?(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 42

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](:xml).

[ GitHub ]

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

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

#format(_view_path = nil)

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 63

def format(_view_path = nil)
  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 115

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 179

def format_from_path_extension
  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 143

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 175

def use_accept_header
  !self.class.ignore_accept_header
end

#valid_accept_header (private)

[ GitHub ]

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

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