【问题标题】:Is this a bug in Rack?这是 Rack 中的错误吗?
【发布时间】:2011-09-28 21:03:22
【问题描述】:

我正在尝试使用 java 客户端将多部分内容(一个文件和一些字符串)发布到本地主机上的 Sinatra 服务器。似乎服务器不喜欢 POST 消息。堆栈跟踪是:

ERROR NoMethodError: undefined method `rewind' for "hi":String
        D:/Ruby192/lib/ruby/gems/1.9.1/gems/rack-1.2.3/lib/rack/utils.rb:581:in`block in parse_multipart'
        D:/Ruby192/lib/ruby/gems/1.9.1/gems/rack-1.2.3/lib/rack/utils.rb:499:in`loop'
        D:/Ruby192/lib/ruby/gems/1.9.1/gems/rack-1.2.3/lib/rack/utils.rb:499:in`parse_multipart'
        D:/Ruby192/lib/ruby/gems/1.9.1/gems/rack-1.2.3/lib/rack/request.rb:270:in `parse_multipart'
        D:/Ruby192/lib/ruby/gems/1.9.1/gems/rack-1.2.3/lib/rack/request.rb:148:in `POST'
        D:/Ruby192/lib/ruby/gems/1.9.1/gems/rack-1.2.3/lib/rack/methodoverride.rb:15:in `call'
        D:/Ruby192/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:1272:in `block in call'
        D:/Ruby192/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:1303:in `synchronize'
        D:/Ruby192/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:1272:in `call'
        D:/Ruby192/lib/ruby/gems/1.9.1/gems/rack-1.2.3/lib/rack/content_length.rb:13:in `call'
        D:/Ruby192/lib/ruby/gems/1.9.1/gems/rack-1.2.3/lib/rack/handler/webrick.rb:52:in `service'
        D:/Ruby192/lib/ruby/1.9.1/webrick/httpserver.rb:111:in `service'
        D:/Ruby192/lib/ruby/1.9.1/webrick/httpserver.rb:70:in `run'
        D:/Ruby192/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread'

我的服务器打印出帖子消息中的参数。这是我的 java 客户端的内容:

Content-Disposition: form-data; name="file"; filename="fff.jpg"
Content-Type: image/jpeg
Content-Transfer-Encoding: binary
#<File:0xedbc10>
Content-Disposition: form-data; name="jjj"
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
hi

我使用的java代码是:

HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://localhost:4567/upload");
File file = new File("D:/My Documents/My Desktop/fff.jpg");     
MultipartEntity mpEntity = new MultipartEntity();
ContentBody cbFile = new FileBody(file, "image/jpeg");
mpEntity.addPart("file", cbFile);
ContentBody stringBody = new StringBody("hi", Charset.forName("UTF8"));
mpEntity.addPart("jjj", stringBody);
httppost.setEntity(mpEntity);
HttpResponse response = httpclient.execute(httppost);

所以当内容类型是字符串时,Rack 似乎不喜欢处理内容类型。当我将 rack/utils.rb 中的 content_type 变量设置为 nil 时,当参数不是文件时,一切正常。这是故意的还是应该作为错误提交?
另见http://blogs.oracle.com/mandy/entry/rack_and_content_type_for

【问题讨论】:

    标签: ruby rack


    【解决方案1】:

    这是一个 Rack 错误,但您可以在 java 中通过像这样上传来避免它:

    HttpPost httpost = new HttpPost(
                    "http://192.168.140.17:3000/ze/api/documents.xml");
    MultipartEntity entity = new MultipartEntity( HttpMultipartMode.BROWSER_COMPATIBLE );
    entity.addPart( "folder_id", new StringBody("3", "multipart/form-data", Charset.defaultCharset()) );//f2
    entity.addPart( "labels", new StringBody("1,3,4", "form-data", Charset.defaultCharset() ) );
    entity.addPart( "uploaded_data", new FileBody(this.file, filename, "application/pdf", null) );
    httpost.setEntity(entity);
    

    关键是使用 HttpMultipartMode.BROWSER_COMPATIBLE 创建 MultipartEntity。

    【讨论】:

    • 谢谢!知道为什么它不是地址吗?该错误是否已在某处注册?
    • 太棒了。我想知道为什么我的 Android 应用程序无法将在另一个 rails 项目上运行良好的代码上传到一个 rails 服务器。第一条线索:不同的 Rails 配置:)
    猜你喜欢
    • 2013-05-04
    • 2017-07-23
    • 2012-09-15
    • 2017-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多