class Rack::QueryParser
Constants
- COMMON_SEP
- DEFAULT_SEP
- ParamsTooDeepError
-
ParamsTooDeepErroris the old name for the error that is raised when params are recursively nested over the specified limit. Make it the same as asQueryLimitError, so that code that rescuesParamsTooDeepErrorerror to handle bad query strings also now handles other limits.
Attributes
Public Class Methods
# File lib/rack/query_parser.rb, line 30 def self.make_default(key_space_limit, param_depth_limit, **options) new(Params, key_space_limit, param_depth_limit, **options) end
# File lib/rack/query_parser.rb, line 56 def initialize(params_class, key_space_limit, param_depth_limit, bytesize_limit: BYTESIZE_LIMIT, params_limit: PARAMS_LIMIT) @params_class = params_class @key_space_limit = key_space_limit @param_depth_limit = param_depth_limit @bytesize_limit = bytesize_limit @params_limit = params_limit end
Public Instance Methods
Source
# File lib/rack/query_parser.rb, line 157 def make_params @params_class.new @key_space_limit end
# File lib/rack/query_parser.rb, line 165 def new_depth_limit(param_depth_limit) self.class.new @params_class, key_space_limit, param_depth_limit end
# File lib/rack/query_parser.rb, line 161 def new_space_limit(key_space_limit) self.class.new @params_class, key_space_limit, param_depth_limit end
# File lib/rack/query_parser.rb, line 116 def normalize_params(params, name, v, depth) raise ParamsTooDeepError if depth <= 0 name =~ %r(\A[\[\]]*([^\[\]]+)\]*) k = $1 || '' after = $' || '' if k.empty? if !v.nil? && name == "[]" return Array(v) else return end end if after == '' params[k] = v elsif after == "[" params[name] = v elsif after == "[]" params[k] ||= [] raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array) params[k] << v elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$) child_key = $1 params[k] ||= [] raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array) if params_hash_type?(params[k].last) && !params_hash_has_key?(params[k].last, child_key) normalize_params(params[k].last, child_key, v, depth - 1) else params[k] << normalize_params(make_params, child_key, v, depth - 1) end else params[k] ||= make_params raise ParameterTypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params_hash_type?(params[k]) params[k] = normalize_params(params[k], after, v, depth - 1) end params end
normalize_params recursively expands parameters into structural types. If the structural types represented by two different parameter names are in conflict, a ParameterTypeError is raised.
# File lib/rack/query_parser.rb, line 97 def parse_nested_query(qs, d = nil) params = make_params unless qs.nil? || qs.empty? check_query_string(qs, d).split(d ? (COMMON_SEP[d] || /[#{d}] */n) : DEFAULT_SEP).each do |p| k, v = p.split('=', 2).map! { |s| unescape(s) } normalize_params(params, k, v, param_depth_limit) end end return params.to_h rescue ArgumentError => e raise InvalidParameterError, e.message, e.backtrace end
parse_nested_query expands a query string into structural types. Supported types are Arrays, Hashes and basic value types. It is possible to supply query strings with parameters of conflicting types, in this case a ParameterTypeError is raised. Users are encouraged to return a 400 in this case.
# File lib/rack/query_parser.rb, line 69 def parse_query(qs, d = nil, &unescaper) unescaper ||= method(:unescape) params = make_params check_query_string(qs, d).split(d ? (COMMON_SEP[d] || /[#{d}] */n) : DEFAULT_SEP).each do |p| next if p.empty? k, v = p.split('=', 2).map!(&unescaper) if cur = params[k] if cur.class == Array params[k] << v else params[k] = [cur, v] end else params[k] = v end end return params.to_h end
Stolen from Mongrel, with some small modifications: Parses a query string by breaking it up at the ‘&’ and ‘;’ characters. You can also use this to parse cookies by changing the characters used in the second parameter (which defaults to ‘&;’).