Class: Rack::MediaType

Inherits:
Sinatra::Base
  • Object
show all
Includes:
RespondTo::Helpers
Defined in:
lib/sinatra/rack_accept.rb

Constant Summary collapse

ACCEPTED_MEDIA_TYPES =

Define supported media types here The :return key stands for content-type which will be returned The :match key stands for the matching Accept header

{
  :xml => { :return => 'application/xml', :match => ['application/xml', 'text/xml'] },
  :json => { :return => 'application/json', :match => ['application/json'] },
  :html => { :return => 'text/html', :match => ['application/xhtml+xml', 'text/html', '*/*'] },
  :png => { :return => 'image/png', :match => ['image/png'] },
  :gv => { :return => 'application/ghostscript', :match => ['application/ghostscript'] }
}

Instance Method Summary collapse

Methods included from RespondTo::Helpers

#accepting_formats, included, #respond_to, #static_file?

Instance Method Details

#call(env) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/sinatra/rack_accept.rb', line 127

def call(env)
  accept, index = env['rack-accept.request'], {}

  # Skip everything when 'format' parameter is set in URL
  if env['rack.request.query_hash'] and env['rack.request.query_hash']["format"]
     media_type = case env['rack.request.query_hash']["format"]
        when 'html' then :html
        when 'xml' then :xml
        when 'json' then :json
        when 'gv' then :gv
        when 'png' then :png
      end
    index[media_type] = 1 if media_type
  else
    # Sort all requested media types in Accept using their 'q' values
    sorted_media_types = accept.media_type.qvalues.to_a.sort{ |a,b| a[1]<=>b[1] }.collect { |t| t.first }
    # If Accept header is missing or is empty, fallback to XML format
    sorted_media_types << 'application/xml' if sorted_media_types.empty?
    # Choose the right format with the media type according to the priority
    ACCEPTED_MEDIA_TYPES.each do |format, definition|
      definition[:match].each do |mt|
        break if index[format] = sorted_media_types.index(mt)
      end
    end
    # Reject formats with no/nil priority
    index.reject! { |format, priority| not priority }
  end

  #puts sorted_media_types.inspect
  #puts index.inspect

  # If after all we don't have any matching format assume that client has
  # requested unknown/wrong media type and throw an 406 error with no body
  if index.keys.empty?
    status, headers, response = 406, {}, ""
  else
    env['rack-accept.formats'] = index
    status, headers, response = @app.call(env)
  end
  [status, headers, response]
end