grape 0.13.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grape might be problematic. Click here for more details.

Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +9 -4
  3. data/CHANGELOG.md +28 -0
  4. data/Gemfile +0 -1
  5. data/Gemfile.lock +166 -0
  6. data/README.md +305 -163
  7. data/Rakefile +30 -33
  8. data/UPGRADING.md +31 -0
  9. data/benchmark/simple.rb +27 -0
  10. data/gemfiles/rack_1.5.2.gemfile +13 -0
  11. data/gemfiles/rails_3.gemfile +2 -2
  12. data/gemfiles/rails_4.gemfile +1 -2
  13. data/grape.gemspec +5 -4
  14. data/lib/grape.rb +9 -5
  15. data/lib/grape/dsl/configuration.rb +5 -2
  16. data/lib/grape/dsl/helpers.rb +8 -3
  17. data/lib/grape/dsl/inside_route.rb +67 -44
  18. data/lib/grape/dsl/parameters.rb +21 -12
  19. data/lib/grape/dsl/request_response.rb +1 -1
  20. data/lib/grape/dsl/routing.rb +3 -4
  21. data/lib/grape/endpoint.rb +63 -28
  22. data/lib/grape/error_formatter/base.rb +6 -6
  23. data/lib/grape/exceptions/base.rb +5 -5
  24. data/lib/grape/exceptions/invalid_version_header.rb +10 -0
  25. data/lib/grape/formatter/serializable_hash.rb +3 -2
  26. data/lib/grape/locale/en.yml +4 -1
  27. data/lib/grape/middleware/auth/base.rb +2 -2
  28. data/lib/grape/middleware/auth/dsl.rb +1 -1
  29. data/lib/grape/middleware/auth/strategies.rb +1 -1
  30. data/lib/grape/middleware/base.rb +7 -4
  31. data/lib/grape/middleware/error.rb +3 -2
  32. data/lib/grape/middleware/filter.rb +1 -1
  33. data/lib/grape/middleware/formatter.rb +47 -44
  34. data/lib/grape/middleware/globals.rb +3 -3
  35. data/lib/grape/middleware/versioner/accept_version_header.rb +5 -7
  36. data/lib/grape/middleware/versioner/header.rb +113 -50
  37. data/lib/grape/middleware/versioner/param.rb +5 -8
  38. data/lib/grape/middleware/versioner/parse_media_type_patch.rb +20 -0
  39. data/lib/grape/middleware/versioner/path.rb +3 -6
  40. data/lib/grape/path.rb +3 -3
  41. data/lib/grape/request.rb +40 -0
  42. data/lib/grape/util/content_types.rb +9 -9
  43. data/lib/grape/util/env.rb +22 -0
  44. data/lib/grape/util/strict_hash_configuration.rb +2 -1
  45. data/lib/grape/validations/attributes_iterator.rb +8 -3
  46. data/lib/grape/validations/params_scope.rb +83 -15
  47. data/lib/grape/validations/types.rb +144 -0
  48. data/lib/grape/validations/types/build_coercer.rb +53 -0
  49. data/lib/grape/validations/types/custom_type_coercer.rb +183 -0
  50. data/lib/grape/validations/types/file.rb +28 -0
  51. data/lib/grape/validations/types/json.rb +65 -0
  52. data/lib/grape/validations/types/multiple_type_coercer.rb +76 -0
  53. data/lib/grape/validations/types/variant_collection_coercer.rb +59 -0
  54. data/lib/grape/validations/types/virtus_collection_patch.rb +16 -0
  55. data/lib/grape/validations/validators/all_or_none.rb +1 -1
  56. data/lib/grape/validations/validators/allow_blank.rb +3 -3
  57. data/lib/grape/validations/validators/base.rb +7 -0
  58. data/lib/grape/validations/validators/coerce.rb +31 -42
  59. data/lib/grape/validations/validators/presence.rb +2 -3
  60. data/lib/grape/validations/validators/regexp.rb +2 -4
  61. data/lib/grape/validations/validators/values.rb +3 -3
  62. data/lib/grape/version.rb +1 -1
  63. data/pkg/grape-0.13.0.gem +0 -0
  64. data/spec/grape/api/custom_validations_spec.rb +5 -4
  65. data/spec/grape/api/deeply_included_options_spec.rb +7 -7
  66. data/spec/grape/api/nested_helpers_spec.rb +4 -2
  67. data/spec/grape/api/shared_helpers_spec.rb +8 -8
  68. data/spec/grape/api_spec.rb +88 -54
  69. data/spec/grape/dsl/configuration_spec.rb +13 -0
  70. data/spec/grape/dsl/helpers_spec.rb +16 -2
  71. data/spec/grape/dsl/inside_route_spec.rb +3 -2
  72. data/spec/grape/dsl/parameters_spec.rb +0 -6
  73. data/spec/grape/dsl/routing_spec.rb +1 -1
  74. data/spec/grape/endpoint_spec.rb +61 -20
  75. data/spec/grape/entity_spec.rb +10 -8
  76. data/spec/grape/exceptions/invalid_accept_header_spec.rb +1 -15
  77. data/spec/grape/integration/rack_spec.rb +3 -2
  78. data/spec/grape/middleware/base_spec.rb +7 -5
  79. data/spec/grape/middleware/error_spec.rb +16 -15
  80. data/spec/grape/middleware/exception_spec.rb +45 -43
  81. data/spec/grape/middleware/formatter_spec.rb +34 -0
  82. data/spec/grape/middleware/versioner/header_spec.rb +79 -47
  83. data/spec/grape/path_spec.rb +10 -10
  84. data/spec/grape/presenters/presenter_spec.rb +2 -2
  85. data/spec/grape/request_spec.rb +100 -0
  86. data/spec/grape/validations/params_scope_spec.rb +11 -9
  87. data/spec/grape/validations/types_spec.rb +95 -0
  88. data/spec/grape/validations/validators/coerce_spec.rb +335 -2
  89. data/spec/grape/validations/validators/values_spec.rb +15 -15
  90. data/spec/grape/validations_spec.rb +53 -24
  91. data/spec/shared/versioning_examples.rb +2 -2
  92. data/spec/spec_helper.rb +0 -1
  93. data/spec/support/versioned_helpers.rb +2 -2
  94. metadata +51 -13
  95. data/.gitignore +0 -46
  96. data/.rspec +0 -2
  97. data/.rubocop.yml +0 -7
  98. data/.rubocop_todo.yml +0 -84
  99. data/.travis.yml +0 -20
  100. data/.yardopts +0 -2
  101. data/lib/grape/http/request.rb +0 -35
  102. data/lib/grape/util/parameter_types.rb +0 -58
  103. data/spec/grape/util/parameter_types_spec.rb +0 -54
@@ -31,7 +31,7 @@ module Grape
31
31
  # end
32
32
  def use(*names)
33
33
  named_params = Grape::DSL::Configuration.stacked_hash_to_hash(@api.namespace_stackable(:named_params)) || {}
34
- options = names.last.is_a?(Hash) ? names.pop : {}
34
+ options = names.extract_options!
35
35
  names.each do |name|
36
36
  params_block = named_params.fetch(name) do
37
37
  fail "Params :#{name} not found!"
@@ -49,19 +49,30 @@ module Grape
49
49
  # the :using hash. The last key can be a hash, which specifies
50
50
  # options for the parameters
51
51
  # @option attrs :type [Class] the type to coerce this parameter to before
52
- # passing it to the endpoint. See Grape::ParameterTypes for supported
53
- # types, or use a class that defines `::parse` as a custom type
52
+ # passing it to the endpoint. See {Grape::Validations::Types} for a list of
53
+ # types that are supported automatically. Custom classes may be used
54
+ # where they define a class-level `::parse` method, or in conjunction
55
+ # with the `:coerce_with` parameter. `JSON` may be supplied to denote
56
+ # `JSON`-formatted objects or arrays of objects. `Array[JSON]` accepts
57
+ # the same values as `JSON` but will wrap single objects in an `Array`.
58
+ # @option attrs :types [Array<Class>] may be supplied in place of +:type+
59
+ # to declare an attribute that has multiple allowed types. See
60
+ # {Validations::Types::MultipleTypeCoercer} for more details on coercion
61
+ # and validation rules for variant-type parameters.
54
62
  # @option attrs :desc [String] description to document this parameter
55
63
  # @option attrs :default [Object] default value, if parameter is optional
56
64
  # @option attrs :values [Array] permissable values for this field. If any
57
65
  # other value is given, it will be handled as a validation error
58
66
  # @option attrs :using [Hash[Symbol => Hash]] a hash defining keys and
59
- # options, like that returned by Grape::Entity#documentation. The value
67
+ # options, like that returned by {Grape::Entity#documentation}. The value
60
68
  # of each key is an options hash accepting the same parameters
61
69
  # @option attrs :except [Array[Symbol]] a list of keys to exclude from
62
70
  # the :using Hash. The meaning of this depends on if :all or :none was
63
71
  # passed; :all + :except will make the :except fields optional, whereas
64
72
  # :none + :except will make the :except fields required
73
+ # @option attrs :coerce_with [#parse, #call] method to be used when coercing
74
+ # the parameter to the type named by `attrs[:type]`. Any class or object
75
+ # that defines `::parse` or `::call` may be used.
65
76
  #
66
77
  # @example
67
78
  #
@@ -86,7 +97,7 @@ module Grape
86
97
  def requires(*attrs, &block)
87
98
  orig_attrs = attrs.clone
88
99
 
89
- opts = attrs.last.is_a?(Hash) ? attrs.pop.clone : {}
100
+ opts = attrs.extract_options!.clone
90
101
  opts[:presence] = true
91
102
 
92
103
  if opts[:using]
@@ -94,8 +105,7 @@ module Grape
94
105
  else
95
106
  validate_attributes(attrs, opts, &block)
96
107
 
97
- block_given? ? new_scope(orig_attrs, &block) :
98
- push_declared_params(attrs)
108
+ block_given? ? new_scope(orig_attrs, &block) : push_declared_params(attrs)
99
109
  end
100
110
  end
101
111
 
@@ -106,7 +116,7 @@ module Grape
106
116
  def optional(*attrs, &block)
107
117
  orig_attrs = attrs.clone
108
118
 
109
- opts = attrs.last.is_a?(Hash) ? attrs.pop.clone : {}
119
+ opts = attrs.extract_options!.clone
110
120
  type = opts[:type]
111
121
 
112
122
  # check type for optional parameter group
@@ -120,8 +130,7 @@ module Grape
120
130
  else
121
131
  validate_attributes(attrs, opts, &block)
122
132
 
123
- block_given? ? new_scope(orig_attrs, true, &block) :
124
- push_declared_params(attrs)
133
+ block_given? ? new_scope(orig_attrs, true, &block) : push_declared_params(attrs)
125
134
  end
126
135
  end
127
136
 
@@ -153,7 +162,7 @@ module Grape
153
162
  # the given parameter is present. The parameters are not nested.
154
163
  # @param attr [Symbol] the parameter which, if present, triggers the
155
164
  # validations
156
- # @throws Grape::Exceptions::UnknownParameter if `attr` has not been
165
+ # @raise Grape::Exceptions::UnknownParameter if `attr` has not been
157
166
  # defined in this scope yet
158
167
  # @yield a parameter definition DSL
159
168
  def given(attr, &block)
@@ -163,7 +172,7 @@ module Grape
163
172
 
164
173
  # Test for whether a certain parameter has been defined in this params
165
174
  # block yet.
166
- # @returns [Boolean] whether the parameter has been defined
175
+ # @return [Boolean] whether the parameter has been defined
167
176
  def declared_param?(param)
168
177
  # @declared_params also includes hashes of options and such, but those
169
178
  # won't be flattened out.
@@ -104,7 +104,7 @@ module Grape
104
104
  handler = block
105
105
  end
106
106
 
107
- options = args.last.is_a?(Hash) ? args.pop : {}
107
+ options = args.extract_options!
108
108
  handler ||= proc { options[:with] } if options.key?(:with)
109
109
 
110
110
  if args.include?(:all)
@@ -28,9 +28,8 @@ module Grape
28
28
  #
29
29
  def version(*args, &block)
30
30
  if args.any?
31
- options = args.pop if args.last.is_a? Hash
32
- options ||= {}
33
- options = { using: :path }.merge(options)
31
+ options = args.extract_options!
32
+ options = options.reverse_merge(using: :path)
34
33
 
35
34
  fail Grape::Exceptions::MissingVendorOption.new if options[:using] == :header && !options.key?(:vendor)
36
35
 
@@ -76,7 +75,7 @@ module Grape
76
75
 
77
76
  if app.respond_to?(:inheritable_setting, true)
78
77
  mount_path = Rack::Mount::Utils.normalize_path(path)
79
- app.top_level_setting.namespace_stackable[:mount_path] = mount_path
78
+ app.top_level_setting.namespace_stackable[:mount_path] = mount_path
80
79
 
81
80
  app.inherit_settings(inheritable_setting)
82
81
 
@@ -12,15 +12,31 @@ module Grape
12
12
  include Grape::DSL::InsideRoute
13
13
 
14
14
  class << self
15
+ def new(*args, &block)
16
+ if self == Endpoint
17
+ Class.new(Endpoint).new(*args, &block)
18
+ else
19
+ super
20
+ end
21
+ end
22
+
15
23
  def before_each(new_setup = false, &block)
24
+ @before_each ||= []
16
25
  if new_setup == false
17
26
  if block_given?
18
- @before_each = block
27
+ @before_each << block
19
28
  else
20
29
  return @before_each
21
30
  end
22
31
  else
23
- @before_each = new_setup
32
+ @before_each = [new_setup]
33
+ end
34
+ end
35
+
36
+ def run_before_each(endpoint)
37
+ superclass.run_before_each(endpoint) unless self == Endpoint
38
+ before_each.each do |blk|
39
+ blk.call(endpoint) if blk.respond_to? :call
24
40
  end
25
41
  end
26
42
 
@@ -74,10 +90,12 @@ module Grape
74
90
  @options[:method] = Array(options[:method])
75
91
  @options[:route_options] ||= {}
76
92
 
77
- if block_given?
78
- @source = block
79
- @block = self.class.generate_api_method(method_name, &block)
80
- end
93
+ @lazy_initialize_lock = Mutex.new
94
+
95
+ return unless block_given?
96
+
97
+ @source = block
98
+ @block = self.class.generate_api_method(method_name, &block)
81
99
  end
82
100
 
83
101
  def require_option(options, key)
@@ -119,7 +137,7 @@ module Grape
119
137
  route_set.add_route(self, {
120
138
  path_info: route.route_compiled,
121
139
  request_method: method
122
- }, route_info: route)
140
+ }, route_info: route)
123
141
  end
124
142
  end
125
143
  end
@@ -187,20 +205,14 @@ module Grape
187
205
  end
188
206
 
189
207
  def call(env)
208
+ lazy_initialize!
190
209
  dup.call!(env)
191
210
  end
192
211
 
193
212
  def call!(env)
194
- extend helpers
195
-
196
- env['api.endpoint'] = self
197
- if options[:app]
198
- options[:app].call(env)
199
- else
200
- builder = build_middleware
201
- builder.run ->(arg) { run(arg) }
202
- builder.call(env)
203
- end
213
+ env[Grape::Env::API_ENDPOINT] = self
214
+ @env = env
215
+ @app.call(env)
204
216
  end
205
217
 
206
218
  # Return the collection of endpoints within this endpoint.
@@ -215,9 +227,8 @@ module Grape
215
227
 
216
228
  protected
217
229
 
218
- def run(env)
230
+ def run
219
231
  ActiveSupport::Notifications.instrument('endpoint_run.grape', endpoint: self, env: env) do
220
- @env = env
221
232
  @header = {}
222
233
 
223
234
  @request = Grape::Request.new(env)
@@ -226,7 +237,7 @@ module Grape
226
237
 
227
238
  cookies.read(@request)
228
239
 
229
- self.class.before_each.call(self) if self.class.before_each
240
+ self.class.run_before_each(self)
230
241
 
231
242
  run_filters befores, :before
232
243
 
@@ -235,8 +246,6 @@ module Grape
235
246
  # Retrieve validations from this namespace and all parent namespaces.
236
247
  validation_errors = []
237
248
 
238
- # require 'pry-byebug'; binding.pry
239
-
240
249
  route_setting(:saved_validations).each do |validator|
241
250
  begin
242
251
  validator.validate!(params)
@@ -261,7 +270,7 @@ module Grape
261
270
  end
262
271
  end
263
272
 
264
- def build_middleware
273
+ def build_stack
265
274
  b = Rack::Builder.new
266
275
 
267
276
  b.use Rack::Head
@@ -302,15 +311,39 @@ module Grape
302
311
  formatters: Grape::DSL::Configuration.stacked_hash_to_hash(namespace_stackable(:formatters)),
303
312
  parsers: Grape::DSL::Configuration.stacked_hash_to_hash(namespace_stackable(:parsers))
304
313
 
305
- b
314
+ b.run ->(env) { env[Grape::Env::API_ENDPOINT].run }
315
+
316
+ b.to_app
306
317
  end
307
318
 
319
+ def build_helpers
320
+ helpers = namespace_stackable(:helpers) || []
321
+ Module.new do
322
+ helpers.each do |mod_to_include|
323
+ include mod_to_include
324
+ end
325
+ end
326
+ end
327
+
328
+ private :build_stack, :build_helpers
329
+
308
330
  def helpers
309
- mod = Module.new
310
- (namespace_stackable(:helpers) || []).each do |mod_to_include|
311
- mod.send :include, mod_to_include
331
+ lazy_initialize! && @helpers
332
+ end
333
+
334
+ def lazy_initialize!
335
+ return true if @lazy_initialized
336
+
337
+ @lazy_initialize_lock.synchronize do
338
+ return true if @lazy_initialized
339
+
340
+ @app = options[:app] || build_stack
341
+ @helpers = build_helpers.tap do |mod|
342
+ self.class.send(:include, mod)
343
+ end
344
+
345
+ @lazy_initialized = true
312
346
  end
313
- mod
314
347
  end
315
348
 
316
349
  def run_filters(filters, type = :other)
@@ -319,6 +352,8 @@ module Grape
319
352
  instance_eval(&filter)
320
353
  end
321
354
  end
355
+ post_extension = DSL::InsideRoute.post_filter_methods(type)
356
+ extend post_extension if post_extension
322
357
  end
323
358
 
324
359
  def befores
@@ -33,22 +33,22 @@ module Grape
33
33
  present_options = {}
34
34
  present_options[:with] = message.delete(:with) if message.is_a?(Hash)
35
35
 
36
- presenter = env['api.endpoint'].entity_class_for_obj(message, present_options)
36
+ presenter = env[Grape::Env::API_ENDPOINT].entity_class_for_obj(message, present_options)
37
37
 
38
- unless presenter || env['rack.routing_args'].nil?
38
+ unless presenter || env[Grape::Env::RACK_ROUTING_ARGS].nil?
39
39
  # env['api.endpoint'].route does not work when the error occurs within a middleware
40
40
  # the Endpoint does not have a valid env at this moment
41
- http_codes = env['rack.routing_args'][:route_info].route_http_codes || []
41
+ http_codes = env[Grape::Env::RACK_ROUTING_ARGS][:route_info].route_http_codes || []
42
42
  found_code = http_codes.find do |http_code|
43
- (http_code[0].to_i == env['api.endpoint'].status) && http_code[2].respond_to?(:represent)
44
- end if env['api.endpoint'].request
43
+ (http_code[0].to_i == env[Grape::Env::API_ENDPOINT].status) && http_code[2].respond_to?(:represent)
44
+ end if env[Grape::Env::API_ENDPOINT].request
45
45
 
46
46
  presenter = found_code[2] if found_code
47
47
  end
48
48
 
49
49
  if presenter
50
50
  embeds = { env: env }
51
- embeds[:version] = env['api.version'] if env['api.version']
51
+ embeds[:version] = env[Grape::Env::API_VERSION] if env[Grape::Env::API_VERSION]
52
52
  message = presenter.represent(message, embeds).serializable_hash
53
53
  end
54
54
 
@@ -1,8 +1,8 @@
1
1
  module Grape
2
2
  module Exceptions
3
3
  class Base < StandardError
4
- BASE_MESSAGES_KEY = 'grape.errors.messages'
5
- BASE_ATTRIBUTES_KEY = 'grape.errors.attributes'
4
+ BASE_MESSAGES_KEY = 'grape.errors.messages'.freeze
5
+ BASE_ATTRIBUTES_KEY = 'grape.errors.attributes'.freeze
6
6
  FALLBACK_LOCALE = :en
7
7
 
8
8
  attr_reader :status, :message, :headers
@@ -51,16 +51,16 @@ module Grape
51
51
 
52
52
  def translate_attributes(keys, options = {})
53
53
  keys.map do |key|
54
- translate("#{BASE_ATTRIBUTES_KEY}.#{key}", { default: key }.merge(options))
54
+ translate("#{BASE_ATTRIBUTES_KEY}.#{key}", options.reverse_merge(default: key))
55
55
  end.join(', ')
56
56
  end
57
57
 
58
58
  def translate_attribute(key, options = {})
59
- translate("#{BASE_ATTRIBUTES_KEY}.#{key}", { default: key }.merge(options))
59
+ translate("#{BASE_ATTRIBUTES_KEY}.#{key}", options.reverse_merge(default: key))
60
60
  end
61
61
 
62
62
  def translate_message(key, options = {})
63
- translate("#{BASE_MESSAGES_KEY}.#{key}", { default: '' }.merge(options))
63
+ translate("#{BASE_MESSAGES_KEY}.#{key}", options.reverse_merge(default: ''))
64
64
  end
65
65
 
66
66
  def translate(key, options = {})
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+ module Grape
3
+ module Exceptions
4
+ class InvalidVersionHeader < Base
5
+ def initialize(message, headers)
6
+ super(message: compose_message('invalid_version_header', message: message), status: 406, headers: headers)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -21,10 +21,11 @@ module Grape
21
21
  elsif object.is_a?(Array) && !object.map { |o| o.respond_to? :serializable_hash }.include?(false)
22
22
  object.map(&:serializable_hash)
23
23
  elsif object.is_a?(Hash)
24
- object.inject({}) do |h, (k, v)|
24
+ h = {}
25
+ object.each_pair do |k, v|
25
26
  h[k] = serialize(v)
26
- h
27
27
  end
28
+ h
28
29
  else
29
30
  object
30
31
  end
@@ -35,7 +35,7 @@ en:
35
35
  exactly_one: 'are missing, exactly one parameter must be provided'
36
36
  all_or_none: 'provide all or none of parameters'
37
37
  missing_group_type: 'group type is required'
38
- unsupported_group_type: 'group type must be Array or Hash'
38
+ unsupported_group_type: 'group type must be Array, Hash, JSON or Array[JSON]'
39
39
  invalid_message_body:
40
40
  problem: "message body does not match declared format"
41
41
  resolution:
@@ -45,4 +45,7 @@ en:
45
45
  invalid_accept_header:
46
46
  problem: 'Invalid accept header'
47
47
  resolution: '%{message}'
48
+ invalid_version_header:
49
+ problem: 'Invalid version header'
50
+ resolution: '%{message}'
48
51
 
@@ -12,7 +12,7 @@ module Grape
12
12
  end
13
13
 
14
14
  def context
15
- env['api.endpoint']
15
+ env[Grape::Env::API_ENDPOINT]
16
16
  end
17
17
 
18
18
  def call(env)
@@ -26,7 +26,7 @@ module Grape
26
26
  auth_proc = options[:proc]
27
27
  auth_proc_context = context
28
28
 
29
- strategy_info = Grape::Middleware::Auth::Strategies[options[:type]]
29
+ strategy_info = Grape::Middleware::Auth::Strategies[options[:type]]
30
30
 
31
31
  throw(:error, status: 401, message: 'API Authorization Failed.') unless strategy_info.present?
32
32
 
@@ -12,7 +12,7 @@ module Grape
12
12
  # only `:http_basic`, `:http_digest` are supported.
13
13
  def auth(type = nil, options = {}, &block)
14
14
  if type
15
- namespace_inheritable(:auth, { type: type.to_sym, proc: block }.merge(options))
15
+ namespace_inheritable(:auth, options.reverse_merge(type: type.to_sym, proc: block))
16
16
  use Grape::Middleware::Auth::Base, namespace_inheritable(:auth)
17
17
  else
18
18
  namespace_inheritable(:auth)
@@ -5,7 +5,7 @@ module Grape
5
5
  module_function
6
6
 
7
7
  def add(label, strategy, option_fetcher = ->(_) { [] })
8
- auth_strategies[label] = StrategyInfo.new(strategy, option_fetcher)
8
+ auth_strategies[label] = StrategyInfo.new(strategy, option_fetcher)
9
9
  end
10
10
 
11
11
  def auth_strategies
@@ -2,6 +2,7 @@ module Grape
2
2
  module Middleware
3
3
  class Base
4
4
  attr_reader :app, :env, :options
5
+ TEXT_HTML = 'text/html'.freeze
5
6
 
6
7
  # @param [Rack Application] app The standard argument for a Rack middleware.
7
8
  # @param [Hash] options A hash of options, simply stored for use by subclasses.
@@ -50,13 +51,15 @@ module Grape
50
51
  end
51
52
 
52
53
  def content_type
53
- content_type_for(env['api.format'] || options[:format]) || 'text/html'
54
+ content_type_for(env[Grape::Env::API_FORMAT] || options[:format]) || TEXT_HTML
54
55
  end
55
56
 
56
57
  def mime_types
57
- content_types.each_with_object({}) do |(k, v), types_without_params|
58
- types_without_params[k] = v.split(';').first
59
- end.invert
58
+ types_without_params = {}
59
+ content_types.each_pair do |k, v|
60
+ types_without_params[v.split(';').first] = k
61
+ end
62
+ types_without_params
60
63
  end
61
64
  end
62
65
  end