Skip to content

Commit db7d190

Browse files
committed
Fix: symbol memory leak in formatter middleware.
1 parent df8665c commit db7d190

File tree

5 files changed

+29
-9
lines changed

5 files changed

+29
-9
lines changed

lib/grape/error_formatter/base.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
require 'active_support/core_ext/hash/indifferent_access'
2+
13
module Grape
24
module ErrorFormatter
35
module Base
@@ -12,7 +14,9 @@ class << self
1214
}
1315

1416
def formatters(options)
15-
FORMATTERS.merge(options[:error_formatters] || {})
17+
HashWithIndifferentAccess.new(
18+
FORMATTERS.merge(options[:error_formatters] || {})
19+
)
1620
end
1721

1822
def formatter_for(api_format, options = {})

lib/grape/formatter/base.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
require 'active_support/core_ext/hash/indifferent_access'
2+
13
module Grape
24
module Formatter
35
module Base
@@ -12,7 +14,9 @@ class << self
1214
}
1315

1416
def formatters(options)
15-
FORMATTERS.merge(options[:formatters] || {})
17+
HashWithIndifferentAccess.new(
18+
FORMATTERS.merge(options[:formatters] || {})
19+
)
1620
end
1721

1822
def formatter_for(api_format, options = {})

lib/grape/middleware/base.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require 'active_support/ordered_hash'
2+
require 'active_support/core_ext/hash/indifferent_access'
23
require 'multi_json'
34
require 'multi_xml'
45

@@ -55,12 +56,16 @@ def response
5556
Rack::Response.new(@app_response)
5657
end
5758

59+
def content_type_for(format)
60+
HashWithIndifferentAccess.new(content_types)[format]
61+
end
62+
5863
def content_types
5964
options[:content_types] || CONTENT_TYPES
6065
end
6166

6267
def content_type
63-
content_types[env['api.format'] || options[:format]] || 'text/html'
68+
content_type_for(env['api.format'] || options[:format]) || 'text/html'
6469
end
6570

6671
def mime_types

lib/grape/middleware/formatter.rb

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def headers
1818

1919
def before
2020
fmt = format_from_extension || format_from_params || options[:format] || format_from_header || options[:default_format]
21-
if content_types.key?(fmt)
21+
if content_type_for(fmt)
2222
if !env['rack.input'].nil? and (body = env['rack.input'].read).strip.length != 0
2323
parser = Grape::Parser::Base.parser_for fmt, options
2424
unless parser.nil?
@@ -42,15 +42,18 @@ def format_from_extension
4242
parts = request.path.split('.')
4343

4444
if parts.size > 1
45-
extension = parts.last.to_sym
46-
return extension if content_types.key?(extension)
45+
extension = parts.last
46+
# avoid symbol memory leak on an unknown format
47+
return extension.to_sym if content_type_for(extension)
4748
end
4849
nil
4950
end
5051

5152
def format_from_params
5253
fmt = Rack::Utils.parse_nested_query(env['QUERY_STRING'])["format"]
53-
fmt ? fmt.to_sym : nil
54+
# avoid symbol memory leak on an unknown format
55+
return fmt.to_sym if content_type_for(fmt)
56+
fmt
5457
end
5558

5659
def format_from_header
@@ -76,7 +79,7 @@ def after
7679
bodymap = bodies.collect do |body|
7780
formatter.call body, env
7881
end
79-
headers['Content-Type'] = content_types[env['api.format']] unless headers['Content-Type']
82+
headers['Content-Type'] = content_type_for(env['api.format']) unless headers['Content-Type']
8083
Rack::Response.new(bodymap, status, headers).to_a
8184
end
8285

lib/grape/parser/base.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
require 'active_support/core_ext/hash/indifferent_access'
2+
13
module Grape
24
module Parser
35
module Base
@@ -10,7 +12,9 @@ class << self
1012
}
1113

1214
def parsers(options)
13-
PARSERS.merge(options[:parsers] || {})
15+
HashWithIndifferentAccess.new(
16+
PARSERS.merge(options[:parsers] || {})
17+
)
1418
end
1519

1620
def parser_for(api_format, options = {})

0 commit comments

Comments
 (0)