ruby-on-rails-3 - 导轨/Rack : "ArgumentError: invalid %-encoding" for POST data

标签 ruby-on-rails-3 rack ruby-1.9.3

我们的 Ruby on Rails 网站有一个 URI,我们的合作伙伴之一将 XML 数据发布到该 URI。

由于我们不想处理 XML,因此我们实际上只是将原始数据填充到数据库列中,并且不再进一步处理它。

但是,我们收到的一篇帖子在空气制动中给了我们这个错误:

ArgumentError: invalid %-encoding ("http://ns.hr-xml.org/2004-08-02" 
userId="" password=""><BackgroundReportPackage type="report">
<ProviderReferenceId>....

带有回溯:

vendor/ruby-1.9.3/lib/ruby/1.9.1/uri/common.rb:898:in `decode_www_form_component'
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/utils.rb:41:in `unescape'
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/utils.rb:94:in `block (2 levels) in parse_nested_query'
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/utils.rb:94:in `map'
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/utils.rb:94:in `block in parse_nested_query'
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/utils.rb:93:in `each'
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/utils.rb:93:in `parse_nested_query'
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/request.rb:332:in `parse_query'
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/request.rb:209:in `POST'
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/methodoverride.rb:26:in `method_override'
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/methodoverride.rb:14:in `call'
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/runtime.rb:17:in `call'
vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.13/lib/active_support/cache/strategy/local_cache.rb:72:in `call'
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/lock.rb:15:in `call'
vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.13/lib/action_dispatch/middleware/static.rb:63:in `call'
vendor/bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:136:in `forward'
vendor/bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:143:in `pass'
vendor/bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:155:in `invalidate'
vendor/bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:71:in `call!'
vendor/bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:51:in `call'
vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/engine.rb:479:in `call'
vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/application.rb:223:in `call'
vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/railtie/configurable.rb:30:in `method_missing'
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/deflater.rb:13:in `call'
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/content_length.rb:14:in `call'
vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/rack/log_tailer.rb:17:in `call'
vendor/bundle/ruby/1.9.1/gems/thin-1.4.1/lib/thin/connection.rb:80:in `block in pre_process'
vendor/bundle/ruby/1.9.1/gems/thin-1.4.1/lib/thin/connection.rb:78:in `catch'
vendor/bundle/ruby/1.9.1/gems/thin-1.4.1/lib/thin/connection.rb:78:in `pre_process'
vendor/bundle/ruby/1.9.1/gems/thin-1.4.1/lib/thin/connection.rb:53:in `process'
vendor/bundle/ruby/1.9.1/gems/thin-1.4.1/lib/thin/connection.rb:38:in `receive_data'
vendor/bundle/ruby/1.9.1/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in `run_machine'
vendor/bundle/ruby/1.9.1/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in `run'
vendor/bundle/ruby/1.9.1/gems/thin-1.4.1/lib/thin/backends/base.rb:63:in `start'
vendor/bundle/ruby/1.9.1/gems/thin-1.4.1/lib/thin/server.rb:159:in `start'
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/handler/thin.rb:13:in `run'
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/server.rb:268:in `start'
vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands/server.rb:70:in `start'
vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands.rb:55:in `block in <top (required)>'
vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands.rb:50:in `tap'
vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands.rb:50:in `<top (required)>'
script/rails:6:in `require'
script/rails:6:in `<main>'

问题是 POST 包含数据:

<ChargeOrComplaint>DRIVE WHILE BLOOD ALCOHOL LEVEL IS 0.08% OR MORE</ChargeOrComplaint>

大概这是有效的 XML,但 0.08% 末尾的裸露 % 导致了错误,因为它是通过 HTTP 传入的,我猜 Rack 正在期待它进行 URL 编码。

回溯表明这种情况在到达我们的代码之前就发生了,所以我认为它与我们处理它的方式没有任何关系。

那么我的问题是:

1)问题出在哪里? Ruby 1.9.3 的 decode_www_form_component 实现(位于堆栈跟踪的顶部)?架子?我们合作伙伴的 POST 数据或 header ?我们对 POST 的处理?

2) 通过 HTTP POST 的 XML 数据是否需要进行 URL 编码?

3) 此 POST 是否需要有一个 header 才能让 Rack 正确解释它? (即:它是 XML 二进制数据,而不是 URL 编码)。

4) 如果我无法让我们的合作伙伴更改他们向我们发布的内容,我们该如何解决这个问题?一些 Rack 中间件?

最佳答案

我猜测您的合作伙伴可能会将数据作为“x-www-form-urlencoded”发布给您,使 Rack 尝试以这种方式解析它。如果他们可以更改发送的内容,我怀疑将其内容类型设置为“text/xml”将解决此问题。

如果您无法让他们更改发送的内容,那么是的,我认为您必须使用 Rack 中间件(或 Monkeypatching)。尽管您可以浏览 Rack 源代码,但也许有一个设置可以避免进行任何解析。

关于ruby-on-rails-3 - 导轨/Rack : "ArgumentError: invalid %-encoding" for POST data,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15769681/

相关文章:

mysql - Rails 和 MySQL。有什么方法可以查看表格?

ruby-on-rails - 使用 rvm 升级到 ruby​​ 1.9.3 破坏了我的 rails 应用程序

Ruby 1.9.3 打破了 rake 测试

ruby - Ruby 网络服务器与 nginx 等其他服务器之间的区别

ruby-on-rails - 如何访问 Rack 中间件的特定实例?

ruby - Rack::Server.build_app 如何添加中间件?

ruby - 如何为 Ruby 安装 Selenium 和 Nokogiri?

ruby-on-rails - 在 Rails 迁移中添加数据

Ruby 将数组的内容输出为逗号分隔的字符串 Ruby

ruby-on-rails - Rails设计:after_confirmation