【问题标题】:mechanize and Ruby multipart/form-data - content transfer encodingmechanize 和 Ruby multipart/form-data - 内容传输编码
【发布时间】:2014-05-13 10:58:54
【问题描述】:

我正在尝试使用 mechanize 2.7.3 将 multipart/form-data POST 请求发送到远程服务器,以自动化与远程服务器的一些交互。不幸的是没有可用的<form>,所以我必须直接发出POST。幸运的是,mechanize 无论如何都能识别出我在做什么,但服务器不接受响应:

c:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/mechanize-2.7.3/lib/mechanize/http/agent.rb:308: in `fetch': 400 => Net::HTTPBadRequest for http://REDACTED/api/resources -- unhandled response (Mechanize::ResponseCodeError)
    from c:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/mechanize-2.7.3/lib/mechanize.rb:1281:in `post_form'
    from c:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/mechanize-2.7.3/lib/mechanize.rb:502:in `post'
    from thing.rb:38:in `upload'

以下是相关请求期间 mechanize logging 输出的样子:

D, [2014-05-13T12:40:34.580906 #3456] DEBUG -- : query: "--cNPsKCeBSrPGUwxyjMze\r\nContent-Disposition: form-data; name=\"force_create\"\r\n\r\ntrue\r\n--cNPsKCeBSrPGUwxyjMze\r\nContent-Disposition: form-data; name=\"file\"; filename=\"test.wgt\"\r\nContent-Transfer-Encoding: binary\r\n\r\nREDACTED\r\n--cNPsKCeBSrPGUwxyjMze--\r\n"
I, [2014-05-13T12:40:34.581906 #3456]  INFO -- : Net::HTTP::Post: /api/resources
D, [2014-05-13T12:40:34.581906 #3456] DEBUG -- : request-header: accept => */*
D, [2014-05-13T12:40:34.581906 #3456] DEBUG -- : request-header: user-agent => Mechanize/2.7.3 Ruby/1.9.3p392 (http://github.com/sparklemotion/mechanize/)
D, [2014-05-13T12:40:34.581906 #3456] DEBUG -- : request-header: accept-encoding => gzip,deflate,identity
D, [2014-05-13T12:40:34.581906 #3456] DEBUG -- : request-header: accept-charset => ISO-8859-1,utf-8;q=0.7,*;q=0.7
D, [2014-05-13T12:40:34.582906 #3456] DEBUG -- : request-header: accept-language => en-us,en;q=0.5
D, [2014-05-13T12:40:34.582906 #3456] DEBUG -- : request-header: cookie => csrftoken=G4dZv6fxRMq0Y2h5yntDsJTFBeEKVFaU; sessionid=9oqufupdt6r620eyep4l4jcl6i2cxda5
D, [2014-05-13T12:40:34.582906 #3456] DEBUG -- : request-header: host => REDACTED
D, [2014-05-13T12:40:34.582906 #3456] DEBUG -- : request-header: referer => REDACTED/login
D, [2014-05-13T12:40:34.582906 #3456] DEBUG -- : request-header: content-type => multipart/form-data; boundary=cNPsKCeBSrPGUwxyjMze
D, [2014-05-13T12:40:34.582906 #3456] DEBUG -- : request-header: content-length => 409

I, [2014-05-13T12:40:34.613906 #3456]  INFO -- : status: Net::HTTPBadRequest 1.1 400 BAD REQUEST
D, [2014-05-13T12:40:34.613906 #3456] DEBUG -- : response-header: date => Tue, 13 May 2014 10:33:44 GMT
D, [2014-05-13T12:40:34.613906 #3456] DEBUG -- : response-header: server => Apache/2.2.15 (CentOS)
D, [2014-05-13T12:40:34.613906 #3456] DEBUG -- : response-header: vary => Accept-Language,Cookie,Accept-Encoding
D, [2014-05-13T12:40:34.613906 #3456] DEBUG -- : response-header: content-language => en
D, [2014-05-13T12:40:34.613906 #3456] DEBUG -- : response-header: content-type => text/plain; charset=utf-8
D, [2014-05-13T12:40:34.613906 #3456] DEBUG -- : response-header: content-encoding => gzip
D, [2014-05-13T12:40:34.613906 #3456] DEBUG -- : response-header: content-length => 37
D, [2014-05-13T12:40:34.613906 #3456] DEBUG -- : response-header: connection => close
D, [2014-05-13T12:40:34.614906 #3456] DEBUG -- : Read 37 bytes (37 total)
D, [2014-05-13T12:40:34.614906 #3456] DEBUG -- : gzip response

这就是我在 Ruby 中的做法:

def upload(file)
    agent.post(base_uri + RESOURCES_PATH, {
        :force_create => true,
        :file => File.new(file)
    }) do … end
end

与站点的所有其他交互都正常工作(实际上机械化甚至首先登录,因此是 cookie)。上传在真正的浏览器中也可以正常工作——唯一明显的区别是内容传输编码(八位字节流而不是二进制)。或者我在这里遗漏了什么?重要的事情?

另外,我不能对有问题的远程服务器说太多。我只知道该站点正在运行某种基于 Python 的框架(Django、iirc)。

提前致谢,
曼努埃尔

【问题讨论】:

  • 你发现了吗?
  • 我确实做到了。等一下,给我几分钟的时间来发布答案:)

标签: ruby mechanize mechanize-ruby


【解决方案1】:

我已经设法确定了这里的罪魁祸首。由于我的开发机器是基于 Windows 的,这似乎是 mechanize(或其依赖项之一)和 Windows 的问题。通过在File.new 的第二个参数中指定b(二进制)部分,问题就自行消失了。 tl;dr:这是工作代码片段现在的样子:

agent.post(base_uri + RESOURCES_PATH, {
    :force_create => true,
    :file => File.new(file, 'rb')  # <-- changed
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-28
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多