代码之家  ›  专栏  ›  技术社区  ›  Dimitri Cabete Jorge

在任何Rails应用程序中,这些参数都会引发500吗?

  •  9
  • Dimitri Cabete Jorge  · 技术社区  · 12 年前

    使用以下参数运行rails应用程序

    http://example.com/?b=1&b[a]=2
    

    总是让它升高 500 似乎无法捕捉的错误。

    例如。

    它会引发以下错误:

    Invalid query parameters: expected Hash (got String) for param `b'
    

    请求从未命中 Rails应用程序代码 .

    以下是完整回溯的最后一行:

    ActionController::BadRequest (Invalid query parameters: expected Hash (got String) for param `b'):
      rack (1.5.2) lib/rack/utils.rb:127:in `normalize_params'
      rack (1.5.2) lib/rack/utils.rb:96:in `block in parse_nested_query'
      rack (1.5.2) lib/rack/utils.rb:93:in `each'
      rack (1.5.2) lib/rack/utils.rb:93:in `parse_nested_query'
      rack (1.5.2) lib/rack/request.rb:373:in `parse_query'
      actionpack (4.1.4) lib/action_dispatch/http/request.rb:313:in `parse_query'
      rack (1.5.2) lib/rack/request.rb:188:in `GET'
      actionpack (4.1.4) lib/action_dispatch/http/request.rb:274:in `GET'
      actionpack (4.1.4) lib/action_dispatch/http/parameters.rb:16:in `parameters'
      actionpack (4.1.4) lib/action_dispatch/http/filter_parameters.rb:37:in `filtered_parameters'
      actionpack (4.1.4) lib/action_controller/metal/instrumentation.rb:22:in `process_action'
      actionpack (4.1.4) lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
      activerecord (4.1.4) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
      actionpack (4.1.4) lib/abstract_controller/base.rb:136:in `process'
      actionview (4.1.4) lib/action_view/rendering.rb:30:in `process'
      actionpack (4.1.4) lib/action_controller/metal.rb:196:in `dispatch'
      actionpack (4.1.4) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
      actionpack (4.1.4) lib/action_controller/metal.rb:232:in `block in action'
      actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:82:in `call'
      actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:82:in `dispatch'
      actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:50:in `call'
      actionpack (4.1.4) lib/action_dispatch/journey/router.rb:71:in `block in call'
      actionpack (4.1.4) lib/action_dispatch/journey/router.rb:59:in `each'
      actionpack (4.1.4) lib/action_dispatch/journey/router.rb:59:in `call'
      actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:678:in `call'
      rack (1.5.2) lib/rack/etag.rb:23:in `call'
      rack (1.5.2) lib/rack/conditionalget.rb:25:in `call'
      rack (1.5.2) lib/rack/head.rb:11:in `call'
      actionpack (4.1.4) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
    

    几年前我发现了这个 轨道3.2 我想知道为什么它还在崩溃 轨道4.1.4 .

    有人对这里发生的事情有好的解释吗?

    1 回复  |  直到 12 年前
        1
  •  4
  •   Brad Werth    12 年前

    这在技术上影响Rack,而不是Rails,我猜这是一个bug。。。Rack似乎无法正确解析嵌套查询。。。

    should "parse nested query strings correctly" do
        Rack::Utils.parse_nested_query("foo").
          should.equal "foo" => nil
        Rack::Utils.parse_nested_query("foo=").
          should.equal "foo" => ""
        Rack::Utils.parse_nested_query("foo=bar").
          should.equal "foo" => "bar"
        Rack::Utils.parse_nested_query("foo=\"bar\"").
          should.equal "foo" => "\"bar\""
    
        Rack::Utils.parse_nested_query("foo=bar&foo=quux").
          should.equal "foo" => "quux"
        Rack::Utils.parse_nested_query("foo&foo=").
          should.equal "foo" => ""
        Rack::Utils.parse_nested_query("foo=1&bar=2").
          should.equal "foo" => "1", "bar" => "2"
        Rack::Utils.parse_nested_query("&foo=1&&bar=2").
          should.equal "foo" => "1", "bar" => "2"
        Rack::Utils.parse_nested_query("foo&bar=").
          should.equal "foo" => nil, "bar" => ""
        Rack::Utils.parse_nested_query("foo=bar&baz=").
          should.equal "foo" => "bar", "baz" => ""
        Rack::Utils.parse_nested_query("my+weird+field=q1%212%22%27w%245%267%2Fz8%29%3F").
          should.equal "my weird field" => "q1!2\"'w$5&7/z8)?"
    
        Rack::Utils.parse_nested_query("a=b&pid%3D1234=1023").
          should.equal "pid=1234" => "1023", "a" => "b"
    
        Rack::Utils.parse_nested_query("foo[]").
          should.equal "foo" => [nil]
        Rack::Utils.parse_nested_query("foo[]=").
          should.equal "foo" => [""]
        Rack::Utils.parse_nested_query("foo[]=bar").
          should.equal "foo" => ["bar"]
    
        Rack::Utils.parse_nested_query("foo[]=1&foo[]=2").
          should.equal "foo" => ["1", "2"]
        Rack::Utils.parse_nested_query("foo=bar&baz[]=1&baz[]=2&baz[]=3").
          should.equal "foo" => "bar", "baz" => ["1", "2", "3"]
        Rack::Utils.parse_nested_query("foo[]=bar&baz[]=1&baz[]=2&baz[]=3").
          should.equal "foo" => ["bar"], "baz" => ["1", "2", "3"]
    
        Rack::Utils.parse_nested_query("x[y][z]=1").
          should.equal "x" => {"y" => {"z" => "1"}}
        Rack::Utils.parse_nested_query("x[y][z][]=1").
          should.equal "x" => {"y" => {"z" => ["1"]}}
        Rack::Utils.parse_nested_query("x[y][z]=1&x[y][z]=2").
          should.equal "x" => {"y" => {"z" => "2"}}
        Rack::Utils.parse_nested_query("x[y][z][]=1&x[y][z][]=2").
          should.equal "x" => {"y" => {"z" => ["1", "2"]}}
    
        Rack::Utils.parse_nested_query("x[y][][z]=1").
          should.equal "x" => {"y" => [{"z" => "1"}]}
        Rack::Utils.parse_nested_query("x[y][][z][]=1").
          should.equal "x" => {"y" => [{"z" => ["1"]}]}
        Rack::Utils.parse_nested_query("x[y][][z]=1&x[y][][w]=2").
          should.equal "x" => {"y" => [{"z" => "1", "w" => "2"}]}
    
        Rack::Utils.parse_nested_query("x[y][][v][w]=1").
          should.equal "x" => {"y" => [{"v" => {"w" => "1"}}]}
        Rack::Utils.parse_nested_query("x[y][][z]=1&x[y][][v][w]=2").
          should.equal "x" => {"y" => [{"z" => "1", "v" => {"w" => "2"}}]}
    
        Rack::Utils.parse_nested_query("x[y][][z]=1&x[y][][z]=2").
          should.equal "x" => {"y" => [{"z" => "1"}, {"z" => "2"}]}
        Rack::Utils.parse_nested_query("x[y][][z]=1&x[y][][w]=a&x[y][][z]=2&x[y][][w]=3").
          should.equal "x" => {"y" => [{"z" => "1", "w" => "a"}, {"z" => "2", "w" => "3"}]}
    
        lambda { Rack::Utils.parse_nested_query("x[y]=1&x[y]z=2") }.
          should.raise(TypeError).
          message.should.equal "expected Hash (got String) for param `y'"
    
        lambda { Rack::Utils.parse_nested_query("x[y]=1&x[]=1") }.
          should.raise(TypeError).
          message.should.match(/expected Array \(got [^)]*\) for param `x'/)
    
        lambda { Rack::Utils.parse_nested_query("x[y]=1&x[y][][w]=2") }.
          should.raise(TypeError).
          message.should.equal "expected Array (got String) for param `y'"
      end
    

    另一方面,我怀疑查询应该更正确地写为:

    http://example.com/?b[]=1&b[a]=2 http://example.com/?b[a]=1&b[a]=2

    你可能会从 http://codefol.io/posts/How-Does-Rack-Parse-Query-Params-With-parse-nested-query .