lib/grape/middleware/formatter.rb in grape-0.6.1 vs lib/grape/middleware/formatter.rb in grape-0.7.0
- old
+ new
@@ -1,11 +1,10 @@
require 'grape/middleware/base'
module Grape
module Middleware
class Formatter < Base
-
def default_options
{
default_format: :txt,
formatters: {},
parsers: {}
@@ -40,109 +39,112 @@
Rack::Response.new(bodymap, status, headers).to_a
end
private
- # store read input in env['api.request.input']
- def read_body_input
- if (request.post? || request.put? || request.patch? || request.delete?) &&
- (!request.form_data? || !request.media_type) &&
- (!request.parseable_data?) &&
- (request.content_length.to_i > 0 || request.env['HTTP_TRANSFER_ENCODING'] == 'chunked')
+ def request
+ @request ||= Rack::Request.new(env)
+ end
- if (input = env['rack.input'])
+ # store read input in env['api.request.input']
+ def read_body_input
+ if (request.post? || request.put? || request.patch? || request.delete?) &&
+ (!request.form_data? || !request.media_type) &&
+ (!request.parseable_data?) &&
+ (request.content_length.to_i > 0 || request.env['HTTP_TRANSFER_ENCODING'] == 'chunked')
+
+ if (input = env['rack.input'])
+ input.rewind
+ body = env['api.request.input'] = input.read
+ begin
+ read_rack_input(body) if body && body.length > 0
+ ensure
input.rewind
- body = env['api.request.input'] = input.read
- begin
- read_rack_input(body) if body && body.length > 0
- ensure
- input.rewind
- end
end
end
end
+ end
- # store parsed input in env['api.request.body']
- def read_rack_input(body)
- fmt = mime_types[request.media_type] if request.media_type
- fmt ||= options[:default_format]
- if content_type_for(fmt)
- parser = Grape::Parser::Base.parser_for fmt, options
- if parser
- begin
- body = (env['api.request.body'] = parser.call(body, env))
- if body.is_a?(Hash)
- if env['rack.request.form_hash']
- env['rack.request.form_hash'] = env['rack.request.form_hash'].merge(body)
- else
- env['rack.request.form_hash'] = body
- end
- env['rack.request.form_input'] = env['rack.input']
+ # store parsed input in env['api.request.body']
+ def read_rack_input(body)
+ fmt = mime_types[request.media_type] if request.media_type
+ fmt ||= options[:default_format]
+ if content_type_for(fmt)
+ parser = Grape::Parser::Base.parser_for fmt, options
+ if parser
+ begin
+ body = (env['api.request.body'] = parser.call(body, env))
+ if body.is_a?(Hash)
+ if env['rack.request.form_hash']
+ env['rack.request.form_hash'] = env['rack.request.form_hash'].merge(body)
+ else
+ env['rack.request.form_hash'] = body
end
- rescue StandardError => e
- throw :error, status: 400, message: e.message
+ env['rack.request.form_input'] = env['rack.input']
end
- else
- env['api.request.body'] = body
+ rescue StandardError => e
+ throw :error, status: 400, message: e.message
end
else
- throw :error, status: 406, message: "The requested content-type '#{request.media_type}' is not supported."
+ env['api.request.body'] = body
end
+ else
+ throw :error, status: 406, message: "The requested content-type '#{request.media_type}' is not supported."
end
+ end
- def negotiate_content_type
- fmt = format_from_extension || format_from_params || options[:format] || format_from_header || options[:default_format]
- if content_type_for(fmt)
- env['api.format'] = fmt
- else
- throw :error, status: 406, message: "The requested format '#{fmt}' is not supported."
- end
+ def negotiate_content_type
+ fmt = format_from_extension || format_from_params || options[:format] || format_from_header || options[:default_format]
+ if content_type_for(fmt)
+ env['api.format'] = fmt
+ else
+ throw :error, status: 406, message: "The requested format '#{fmt}' is not supported."
end
+ end
- def format_from_extension
- parts = request.path.split('.')
+ 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
-
- def format_from_params
- fmt = Rack::Utils.parse_nested_query(env['QUERY_STRING'])["format"]
+ if parts.size > 1
+ extension = parts.last
# avoid symbol memory leak on an unknown format
- return fmt.to_sym if content_type_for(fmt)
- fmt
+ return extension.to_sym if content_type_for(extension)
end
+ nil
+ end
- def format_from_header
- mime_array.each do |t|
- return mime_types[t] if mime_types.key?(t)
- end
- nil
+ 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
+
+ def format_from_header
+ mime_array.each do |t|
+ return mime_types[t] if mime_types.key?(t)
end
+ nil
+ end
- def mime_array
- accept = headers['accept']
- return [] unless accept
+ def mime_array
+ accept = headers['accept']
+ return [] unless accept
- accept_into_mime_and_quality = %r(
- (
- \w+/[\w+.-]+) # eg application/vnd.example.myformat+xml
- (?:
- (?:;[^,]*?)? # optionally multiple formats in a row
- ;\s*q=([\d.]+) # optional "quality" preference (eg q=0.5)
- )?
- )x
+ accept_into_mime_and_quality = %r(
+ (
+ \w+/[\w+.-]+) # eg application/vnd.example.myformat+xml
+ (?:
+ (?:;[^,]*?)? # optionally multiple formats in a row
+ ;\s*q=([\d.]+) # optional "quality" preference (eg q=0.5)
+ )?
+ )x
- vendor_prefix_pattern = /vnd\.[^+]+\+/
+ vendor_prefix_pattern = /vnd\.[^+]+\+/
- accept.scan(accept_into_mime_and_quality)
- .sort_by { |_, quality_preference| -quality_preference.to_f }
- .map { |mime, _| mime.sub(vendor_prefix_pattern, '') }
- end
-
+ accept.scan(accept_into_mime_and_quality)
+ .sort_by { |_, quality_preference| -quality_preference.to_f }
+ .map { |mime, _| mime.sub(vendor_prefix_pattern, '') }
+ end
end
end
end