【发布时间】: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