Skip to content

Commit 0f83d77

Browse files
committed
even more compatibility with rack's parse_nested_query logic for "pure" servlet-env
1 parent 5f2e6bd commit 0f83d77

File tree

2 files changed

+69
-4
lines changed

2 files changed

+69
-4
lines changed

src/main/ruby/rack/handler/servlet/servlet_env.rb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def [](key)
111111
public :[]
112112

113113
# @private
114-
KEY_SEP = /([^\[\]]*)(?:\[(.*?)\])?/
114+
KEY_SEP = /([^\[\]]+)(?:\[(.*)\])?/
115115

116116
# Store the parameter into the given Hash.
117117
# By default this is performed in a Rack compatible way and thus
@@ -138,12 +138,11 @@ def store_parameter(key, val, hash)
138138
end
139139
hash[ n_key ] = val.to_a # String[]
140140
else # foo[bar]=rrr&foo[baz]=zzz
141-
v = val[ val.length - 1 ] # last
142141
if hsh = hash[ n_key ]
143142
return mark_parameter_error "expected Hash (got #{hsh.class}) for param `#{n_key}'" unless hsh.is_a?(Hash)
144-
hsh[ sub ] = v
143+
store_parameter(sub, val, hsh)
145144
else
146-
hash[ n_key ] = { sub => v }
145+
hash[ n_key ] = { sub => val[ val.length - 1 ] }
147146
end
148147
end
149148
else

src/spec/ruby/rack/handler/servlet_spec.rb

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,72 @@ def getAttributeNames
368368
expect( env['org.apache.internal'] ).to be true
369369
end
370370

371+
it "parses strange request parameters (Rack-compat)" do
372+
servlet_request = @servlet_request
373+
servlet_request.setMethod 'GET'
374+
servlet_request.setContextPath '/'
375+
servlet_request.setPathInfo '/path'
376+
servlet_request.setRequestURI '/home/path'
377+
378+
servlet_request.setQueryString 'foo]=0&bar[=1&baz_=2&[meh=3'
379+
servlet_request.addParameter('foo]', '0')
380+
servlet_request.addParameter('bar[', '1')
381+
servlet_request.addParameter('baz_', '2')
382+
servlet_request.addParameter('[meh', '3')
383+
384+
env = servlet.create_env(@servlet_env)
385+
rack_request = Rack::Request.new(env)
386+
387+
# Rack (1.5.2) does it as :
388+
# { "foo" => "0", "bar" => nil, "baz_" => "2", "meh" => "3" }
389+
# 1.6.0 :
390+
# { "foo" => "0", "bar[" => "1", "baz_" => "2", "meh" => "3" }
391+
392+
expect( rack_request.GET['foo'] ).to eql('0')
393+
expect( rack_request.GET['baz_'] ).to eql('2')
394+
395+
if rack_release('1.6')
396+
# expect( rack_request.GET['bar['] ).to eql('1')
397+
else
398+
expect( rack_request.GET.key?('bar') ).to be true
399+
end
400+
expect( rack_request.GET['meh'] ).to eql('3')
401+
402+
expect( rack_request.query_string ).to eql 'foo]=0&bar[=1&baz_=2&[meh=3'
403+
end
404+
405+
it "parses nestedx request parameters (Rack-compat)" do
406+
servlet_request = @servlet_request
407+
servlet_request.setMethod 'GET'
408+
servlet_request.setContextPath '/'
409+
servlet_request.setPathInfo '/path'
410+
servlet_request.setRequestURI '/home/path'
411+
412+
servlet_request.setQueryString 'foo[bar]=0&foo[baz]=1&foo[bar]=2&foo[meh[]]=x&foo[meh[]]=42&huh[1]=b&huh[0]=a'
413+
servlet_request.addParameter('foo[bar]', '0')
414+
servlet_request.addParameter('foo[baz]', '1')
415+
servlet_request.addParameter('foo[bar]', '2')
416+
servlet_request.addParameter('foo[meh[]]', 'x')
417+
servlet_request.addParameter('foo[meh[]]', '42')
418+
servlet_request.addParameter('huh[1]', 'b')
419+
servlet_request.addParameter('huh[0]', 'a')
420+
421+
env = servlet.create_env(@servlet_env)
422+
rack_request = Rack::Request.new(env)
423+
424+
#params = { "foo" => { "bar" => "2", "baz" => "1", "meh" => [ nil, nil ] }, "huh" => { "1" => "b", "0" => "a" } }
425+
#expect( rack_request.GET ).to eql(params)
426+
427+
expect( rack_request.GET['foo']['bar'] ).to eql('2')
428+
expect( rack_request.GET['foo']['baz'] ).to eql('1')
429+
expect( rack_request.params['foo']['meh'] ).to be_a Array
430+
expect( rack_request.params['huh'] ).to eql({ "1" => "b", "0" => "a" })
431+
432+
expect( rack_request.POST ).to eql Hash.new
433+
434+
expect( rack_request.query_string ).to eql 'foo[bar]=0&foo[baz]=1&foo[bar]=2&foo[meh[]]=x&foo[meh[]]=42&huh[1]=b&huh[0]=a'
435+
end
436+
371437
it "raises if nested request parameters are broken (Rack-compat)" do
372438
servlet_request = @servlet_request
373439
servlet_request.setMethod 'GET'

0 commit comments

Comments
 (0)