Class: Grape::Middleware::Formatter

Inherits:
Base
  • Object
show all
Defined in:
lib/grape/middleware/formatter.rb

Constant Summary

Constants inherited from Base

Base::CONTENT_TYPES

Instance Attribute Summary

Attributes inherited from Base

#app, #env, #options

Instance Method Summary collapse

Methods inherited from Base

#call, #call!, #content_type, #content_type_for, #content_types, #initialize, #mime_types, #request, #response

Constructor Details

This class inherits a constructor from Grape::Middleware::Base

Instance Method Details

#afterObject



76
77
78
79
80
81
82
83
84
# File 'lib/grape/middleware/formatter.rb', line 76

def after
  status, headers, bodies = *@app_response
  formatter = Grape::Formatter::Base.formatter_for env['api.format'], options
  bodymap = bodies.collect do |body|
    formatter.call body, env
  end
  headers['Content-Type'] = content_type_for(env['api.format']) unless headers['Content-Type']
  Rack::Response.new(bodymap, status, headers).to_a
end

#beforeObject



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/grape/middleware/formatter.rb', line 19

def before
  fmt = format_from_extension || format_from_params || options[:format] || format_from_header || options[:default_format]
  if content_type_for(fmt)
    if !env['rack.input'].nil? and (body = env['rack.input'].read).strip.length != 0
      parser = Grape::Parser::Base.parser_for fmt, options
      unless parser.nil?
        begin
          body = parser.call body, env
          env['rack.request.form_hash'] = !env['rack.request.form_hash'].nil? ? env['rack.request.form_hash'].merge(body) : body
          env['rack.request.form_input'] = env['rack.input']
        rescue
          # It's possible that it's just regular POST content -- just back off
        end
      end
      env['rack.input'].rewind
    end
    env['api.format'] = fmt
  else
    throw :error, :status => 406, :message => 'The requested format is not supported.'
  end
end

#default_optionsObject



7
8
9
10
11
12
13
# File 'lib/grape/middleware/formatter.rb', line 7

def default_options
  {
    :default_format => :txt,
    :formatters => {},
    :parsers => {}
  }
end

#format_from_extensionObject



41
42
43
44
45
46
47
48
49
50
# File 'lib/grape/middleware/formatter.rb', line 41

def format_from_extension
  parts = request.path.split('.')

  if parts.size > 1
    extension = parts.last
    # avoid symbol memory leak on an unknown format
    return extension.to_sym if content_type_for(extension)
  end
  nil
end

#format_from_headerObject



59
60
61
62
63
64
65
66
# File 'lib/grape/middleware/formatter.rb', line 59

def format_from_header
  mime_array.each do |t|
    if mime_types.key?(t)
      return mime_types[t]
    end
  end
  nil
end

#format_from_paramsObject



52
53
54
55
56
57
# File 'lib/grape/middleware/formatter.rb', line 52

def format_from_params
  fmt = Rack::Utils.parse_nested_query(env['QUERY_STRING'])["format"]
  # avoid symbol memory leak on an unknown format
  return fmt.to_sym if content_type_for(fmt)
  fmt
end

#headersObject



15
16
17
# File 'lib/grape/middleware/formatter.rb', line 15

def headers
  env.dup.inject({}){|h,(k,v)| h[k.to_s.downcase[5..-1]] = v if k.to_s.downcase.start_with?('http_'); h}
end

#mime_arrayObject



68
69
70
71
72
73
74
# File 'lib/grape/middleware/formatter.rb', line 68

def mime_array
  accept = headers['accept'] or return []

  accept.gsub(/\b/,'').scan(%r((\w+/[\w+.-]+)(?:(?:;[^,]*?)?;\s*q=([\d.]+))?)).sort_by { |_, q| -q.to_f }.map {|mime, _|
    mime.sub(%r(vnd\.[^+]+\+), '')
  }
end