Class: PusherPlatform::QueryParser

Inherits:
Object
  • Object
show all
Defined in:
lib/pusher-platform/rack_query_parser.rb

Defined Under Namespace

Classes: InvalidParameterError, ParameterTypeError, Params

Constant Summary collapse

DEFAULT_SEP =
/[&;] */n
COMMON_SEP =
{ ";" => /[;] */n, ";," => /[;,] */n, "&" => /[&] */n }

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params_class, key_space_limit, param_depth_limit) ⇒ QueryParser

Returns a new instance of QueryParser.



47
48
49
50
51
# File 'lib/pusher-platform/rack_query_parser.rb', line 47

def initialize(params_class, key_space_limit, param_depth_limit)
  @params_class = params_class
  @key_space_limit = key_space_limit
  @param_depth_limit = param_depth_limit
end

Instance Attribute Details

#key_space_limitObject (readonly)

Returns the value of attribute key_space_limit.



45
46
47
# File 'lib/pusher-platform/rack_query_parser.rb', line 45

def key_space_limit
  @key_space_limit
end

#param_depth_limitObject (readonly)

Returns the value of attribute param_depth_limit.



45
46
47
# File 'lib/pusher-platform/rack_query_parser.rb', line 45

def param_depth_limit
  @param_depth_limit
end

Class Method Details

.make_default(key_space_limit, param_depth_limit) ⇒ Object



41
42
43
# File 'lib/pusher-platform/rack_query_parser.rb', line 41

def self.make_default(key_space_limit, param_depth_limit)
  new Params, key_space_limit, param_depth_limit
end

Instance Method Details

#make_paramsObject



145
146
147
# File 'lib/pusher-platform/rack_query_parser.rb', line 145

def make_params
  @params_class.new @key_space_limit
end

#new_depth_limit(param_depth_limit) ⇒ Object



153
154
155
# File 'lib/pusher-platform/rack_query_parser.rb', line 153

def new_depth_limit(param_depth_limit)
  self.class.new @params_class, key_space_limit, param_depth_limit
end

#new_space_limit(key_space_limit) ⇒ Object



149
150
151
# File 'lib/pusher-platform/rack_query_parser.rb', line 149

def new_space_limit(key_space_limit)
  self.class.new @params_class, key_space_limit, param_depth_limit
end

#normalize_params(params, name, v, depth) ⇒ Object

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.

Raises:

  • (RangeError)


104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/pusher-platform/rack_query_parser.rb', line 104

def normalize_params(params, name, v, depth)
  raise RangeError 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

#parse_nested_query(qs, d = nil) ⇒ Object

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.



86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/pusher-platform/rack_query_parser.rb', line 86

def parse_nested_query(qs, d = nil)
  return {} if qs.nil? || qs.empty?
  params = make_params

  (qs || '').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

  return params.to_params_hash
rescue ArgumentError => e
  raise InvalidParameterError, e.message
end

#parse_query(qs, d = nil, &unescaper) ⇒ Object

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 ‘&;’).



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/pusher-platform/rack_query_parser.rb', line 58

def parse_query(qs, d = nil, &unescaper)
  unescaper ||= method(:unescape)

  params = make_params

  (qs || '').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_params_hash
end