Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Posting a multipart form with file data can break params assignment (in 2.3)

#1875

When posting a multipart form to create a record, posted attributes are not being included in the controller's params hash.

Example:

POST a Contact with a photo file and a name attribute; the :name key is not found in params => { contact => { ... } }

Update

I've found this issue occurs only when uploading .jpg files (thus far). No issues testing with .gif, .pdf, .ppt and .mov.

Possibly relevant: I'm running Mac OS X 10.5.6.

Steps to reproduce

1) Create a new rails project (Rails 2.3.0)


  $ rails -v
  Rails 2.3.0

  $ rails test
  $ cd test

2) Create a Contact scaffold with a "name"


  $ script/generate scaffold Contact name:string

3) Migrate the db


  $ rake db:migrate

4) Add a photo attr_accessor to the model for testing multipart posting


  # app/models/contact.rb
  class Contact < ActiveRecord::Base
    attr_accessor :photo
  end

5) Update the "new" view: (1) specify multipart, and (2) add file_field for the photo file (NOTE: photo file_field must come BEFORE name field in order to reproduce this issue!)


  # app/views/contacts/new.html.erb
  <% form_for(@contact, :html => { :multipart => true }) do |f| %>

    ...

    <p>
      <%= f.label :photo %><br />
      <%= f.file_field :photo %>
    </p>

    <p>
      <%= f.label :name %><br />
      <%= f.text_field :name %>
    </p>

    ...

6) Run the server


  $ script/server

7) Load the view (http://localhost:3000/contacts/new) and submit the form with a photo file and a name specified

8) Examine the server log: the name attribute is NOT included in the parameters hash and is NOT saved to the DB... FAIL!


  # server output
  Processing ContactsController#create (for 127.0.0.1 at 2009-02-04 09:06:27) [POST]
    Parameters: {"commit"=>"Create", "authenticity_token"=>"nsn4WHo9KPvWqiA4a8PPkELmeJVHKeLtXx9Dz1CVtTs=", "contact"=>{"photo"=>#<File:/var/folders/Ot/OtD86Bd4GzuaRTn9EQb1NE+++TI/-Tmp-/RackMultipart.2795.1>}}
    Contact Create (0.6ms)   INSERT INTO "contacts" ("name", "updated_at", "created_at") VALUES(NULL, '2009-02-04 14:06:27', '2009-02-04 14:06:27')
  Redirected to #<Contact:0x244d534>
  Completed in 85ms (DB: 1) | 302 Found [http://localhost/contacts]

9) Try resubmitting the form without a photo file; the name attribute IS included in the parameters hash and saved to the DB... SUCCESS!


  # server output
  Processing ContactsController#create (for 127.0.0.1 at 2009-02-04 09:26:06) [POST]
    Parameters: {"commit"=>"Create", "contact"=>{"photo"=>nil, "name"=>"Jonathan"}, "authenticity_token"=>"nsn4WHo9KPvWqiA4a8PPkELmeJVHKeLtXx9Dz1CVtTs="}
    Contact Create (0.4ms)   INSERT INTO "contacts" ("name", "updated_at", "created_at") VALUES('Jonathan', '2009-02-04 14:26:06', '2009-02-04 14:26:06')
  Redirected to #<Contact:0x249d1b0>
  Completed in 21ms (DB: 0) | 302 Found [http://localhost/contacts]

10) Try reverting to Rails 2.2.2, and submit the form with a photo file and name specified... SUCCESS!


  # config/environment.rb
  RAILS_GEM_VERSION = '2.2.2' unless defined? RAILS_GEM_VERSION

  # server output
  Processing ContactsController#create (for 127.0.0.1 at 2009-02-04 09:29:46) [POST]
    Parameters: {"commit"=>"Create", "contact"=>{"photo"=>#<File:/var/folders/Ot/OtD86Bd4GzuaRTn9EQb1NE+++TI/-Tmp-/CGI.2855.1>, "name"=>"Jonathan"}, "authenticity_token"=>"27198d70b52a49b60cdc8c6e722bc945da344f63"}
    Contact Create (0.6ms)   INSERT INTO "contacts" ("name", "updated_at", "created_at") VALUES('Jonathan', '2009-02-04 14:29:46', '2009-02-04 14:29:46')
  Redirected to #<Contact:0x22dbcf0>
  Completed in 21ms (DB: 1) | 302 Found [http://localhost/contacts]

Reported by Jonathan Sutherland · February 4th, 2009 @ 03:26 PM

State: resolved
Milestone: none
Assigned to: josh josh
Importance: none

Activity

  1. Jan Xie
    Jan Xie

    Hi,

    I tested in edge rails (clone from github), can't reproduce the problem.

    Processing ContactsController#create (for 127.0.0.1 at 2009-02-05 00:28:22) [POST] Parameters: {"commit"=>"Create", "contact"=>{"photo"=>#<File:/tmp/RackMultipart.32439.3>, "name"=>"234"}, "authenticity_token"=>"WUrkOOZ9iTsGR9CGvL3zuoQJvAYoc3DD7G4eeNkaTpU="} Contact Create (0.7ms) INSERT INTO "contacts" ("name", "updated_at", "created_at") VALUES('234', '2009-02-04 16:28:22', '2009-02-04 16:28:22') Redirected to #<Contact:0x7f67a1c28de0> Completed in 29ms (DB: 1) | 302 Found [http://localhost/contacts]

    February 4th, 2009 @ 04:30 PM

  2. Jonathan Sutherland
    Jonathan Sutherland

    Jan,

    Ensure you test with <%= f.file_field ... %> appearing BEFORE <%= f.text_field ... %> in your view.

    Reproducing this issue is dependent on the order in which form parameters are posted.

    February 4th, 2009 @ 05:19 PM

  3. Jonathan Sutherland
    Jonathan Sutherland

    Also,

    Appears to occur for .jpg files only (thus far). No issues testing with .gif, .pdf, .ppt and .mov.

    Possibly relevant: I'm running Mac OS X 10.5.6.

    February 4th, 2009 @ 05:39 PM

  4. Simon Lau
    Simon Lau

    I also see this behaviour on Mac OS X 10.5.6.

    I have used rake rails:freeze:edge to obtain the latest copy of edge.

    As far as I can see, something about jpg files causes the issue of missing form fields after the first f.file_field, whether it is uploaded in Firefox, Safari and Firefox on windows.

    February 6th, 2009 @ 10:49 AM

  5. DHH
    DHH
    • Assigned user set to Michael Koziarski
    • Milestone cleared.

    February 6th, 2009 @ 01:40 PM

  6. Jonathan Sutherland
    Jonathan Sutherland

    Appears it may be a parsing issue in Rack's Utils::Multipart.parse_multipart.

    For a posted JPEG, use debugger to examine Utils::Multipart.parse_multipart as it parses through the posted data:

    
      /usr/local/lib/ruby/gems/1.8/gems/rack-0.9.1/lib/rack/utils.rb:341
      break  if buf.empty? || content_length == -1
    
      (rdb:4) head
      "ntent-Disposition: form-data; name=\"contact[name]\"\r\n"
    
      (rdb:4) name
      nil
    

    Looks like the header got parsed wrong: it's missing "Co" from "Content-Disposition". Thus, contact[name] isn't added to params as it's not matched by the corresponding regex:

    
      # rack-0.9.1/lib/rack/utils.rb:293
      name = head[/Content-Disposition:.* name="?([^\";]*)"?/ni, 1]
    

    ====

    For other posted file types (e.g. PDF), there's no issue:

    
      (rdb:5) head
      "Content-Disposition: form-data; name=\"contact[name]\"\r\n"
    
      (rdb:5) name
      "contact[name]"
     
      (rdb:5) params
      {"contact[name]"=>"Jonathan", "authenticity_token"=>"sd76bBiUOGsmSW... etc.
    

    February 6th, 2009 @ 05:58 PM

  7. Michael Koziarski
    Michael Koziarski
    • Assigned user changed from Michael Koziarski to josh

    Handing off to josh who was making changes to our parser

    February 7th, 2009 @ 10:15 PM

  8. josh
    josh

    Can you please test this issue against rack/master.

    I vendor it for the moment so we can test Rails against it before Rack 1.0 is released.

    February 7th, 2009 @ 11:10 PM

  9. Chris Barnes
    Chris Barnes

    I verified this affects jpg files on OSX 10.5.6 with Firefox 2.0.0.12 and Safari 3.1.2. I tried to test against rack/master but I am unsure if I did it correctly.

    I did git submodule add git://github.com/chneukirchen/rack.git vendor/plugins/rack

    restarted my server and re-tested, the results were the same

    How do I tell if my application is using the rack installed in vendor/plugins?

    February 9th, 2009 @ 07:12 PM

  10. josh
    josh

    O, my mistake. I meant to say with edge rails.

    I bundled rack into edge rails. You should be able to do rake rails:freeze:edge and try again.

    February 9th, 2009 @ 08:06 PM

  11. Chris Barnes
    Chris Barnes

    Ok, I created a new app, froze to edge and tested again exactly as Johnathan did in his example and I get a 500 error "bad content body" You can find the full error at http://www.pastie.org/384389.
    >

    Anything I can do to help, let me know. I would love to get this working.

    February 9th, 2009 @ 09:35 PM

  12. josh
    josh
    • State changed from new to open

    This looks like a bug in Rack core.

    If your dying to jump on this, you can write a failing unit test against rack (http://github.com/rack/rack/blob... and submit it to http://rack.lighthouseapp.com/. You can actually still assign the ticket to me :)

    Otherwise I'll take a look at the issue closer towards the end of the week.

    February 9th, 2009 @ 09:40 PM

  13. josh
    josh
    • State changed from open to resolved

    BINGO! Your on the 0.9.1 rack release. /Users/chris/.gem/ruby/1.8/gems/rack-0.9.1

    I think I fixed the vendored rack load path. Please try again, I suspect it will work fine.

    February 10th, 2009 @ 07:51 PM

  14. Jonathan Sutherland
    Jonathan Sutherland

    Looks good Josh.

    Don't see this issue anymore with Rails edge + vendored Rack.

    February 10th, 2009 @ 08:04 PM

  15. Chris Barnes
    Chris Barnes

    Awesome!

    I don't see this issues anymore with edge rails also.

    February 11th, 2009 @ 07:49 PM

  16. Nick Quaranto
    Nick Quaranto

    I just ran into this issue myself, I had 2 file fields on the page and a textarea. Submitting the form with one or no files made Rails recognize the textarea, but submitting both file fields would make the textarea disappear from the params. After checking out the POST parameters to ensure it wasn't a browser issue, I figured it had to be an issue with Rails.

    Luckily, I found this thread but I have a feeling most developers won't. I can definitely make a blog post about it but perhaps something more public should be made known about this issue.

    February 12th, 2009 @ 03:37 AM

  17. Michael Koziarski
    Michael Koziarski

    Nick, the fixes in this thread will be shipped as part of the second RC for rails 2.3, it'll be fixed before the releases are 'in the wild'

    February 12th, 2009 @ 05:38 AM

  18. Russ Smith
    Russ Smith

    I'm getting strange errors still with the latest Rails edge.

    http://gist.github.com/77057

    I've tried digging through the code, but I can't quite figure it out. It's happening in this file: rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb on line 298 and 330. It looks like rack.input.read is nil.

    I've tested this both using Passenger and Litespeed with the same effect.

    March 10th, 2009 @ 06:53 PM

  19. Steve Martocci
    Steve Martocci

    I'm still getting this but it is hard to reproduce, I have one safari browser that is getting the errors. I am on a frozen v2.3.2.1 and passenger 2.1.3. Here is my stack trace

    /!\ FAILSAFE /!\ Tue Apr 07 21:19:30 +0000 2009 Status: 500 Internal Server Error bad content body

    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb:311:in `parse_multipart'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb:125:in `POST'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/request.rb:428:in `request_parameters'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/request.rb:381:in `parameters'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/base.rb:1279:in `assign_shortcuts'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/base.rb:518:in `process_without_filters'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/filters.rb:606:in `sass_old_process'
    /mnt/app/releases/20090407190947/vendor/gems/haml-2.0.9/rails/../lib/sass/plugin/rails.rb:19:in `process'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/rescue.rb:65:in `call_with_exception'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/dispatcher.rb:91:in `dispatch'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/dispatcher.rb:111:in `_call'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/dispatcher.rb:82:in `initialize'
    /mnt/app/releases/20090407190947/vendor/rails/activerecord/lib/active_record/query_cache.rb:29:in `call'
    /mnt/app/releases/20090407190947/vendor/rails/activerecord/lib/active_record/query_cache.rb:29:in `call'
    /mnt/app/releases/20090407190947/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
    /mnt/app/releases/20090407190947/vendor/rails/activerecord/lib/active_record/query_cache.rb:9:in `cache'
    /mnt/app/releases/20090407190947/vendor/rails/activerecord/lib/active_record/query_cache.rb:28:in `call'
    /mnt/app/releases/20090407190947/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb:361:in `call'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/head.rb:9:in `call'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/methodoverride.rb:24:in `call'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/params_parser.rb:15:in `call'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/rewindable_input.rb:25:in `call'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/session/cookie_store.rb:93:in `call'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/failsafe.rb:11:in `call'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lock.rb:11:in `call'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lock.rb:11:in `synchronize'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lock.rb:11:in `call'
    /mnt/app/releases/20090407190947/vendor/rails/actionpack/lib/action_controller/dispatcher.rb:106:in `call'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/rack/request_handler.rb:65:in `process_request'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/abstract_request_handler.rb:197:in `main_loop'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/railz/application_spawner.rb:340:in `start_request_handler'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/railz/application_spawner.rb:298:in `handle_spawn_application'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/utils.rb:176:in `safe_fork'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/railz/application_spawner.rb:296:in `handle_spawn_application'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/abstract_server.rb:332:in `__send__'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/abstract_server.rb:332:in `main_loop'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/abstract_server.rb:182:in `start_synchronously'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/abstract_server.rb:149:in `start'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/railz/application_spawner.rb:192:in `start'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/spawn_manager.rb:260:in `spawn_rails_application'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/abstract_server_collection.rb:121:in `lookup_or_add'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/spawn_manager.rb:254:in `spawn_rails_application'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/abstract_server_collection.rb:75:in `synchronize'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/abstract_server_collection.rb:74:in `synchronize'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/spawn_manager.rb:253:in `spawn_rails_application'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/spawn_manager.rb:148:in `spawn_application'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/spawn_manager.rb:285:in `handle_spawn_application'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/abstract_server.rb:332:in `__send__'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/abstract_server.rb:332:in `main_loop'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/lib/phusion_passenger/abstract_server.rb:182:in `start_synchronously'
    /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/bin/passenger-spawn-server:50
    
    

    April 7th, 2009 @ 10:32 PM

  20. Steve Martocci
    Steve Martocci

    I don't have Rack 0.9.1 installed and this has been marked as resolved? Does that mean there is a fix in edge/rack?

    April 8th, 2009 @ 02:58 PM

  21. Evgeniy Pirogov
    Evgeniy Pirogov

    The problem was inside the Rack v0.9.1 utils.rb

    rx = /(?:#{EOL})?#{Regexp.quote boundary}(#{EOL}|--)/

    version 1.0 announced on Apr 25

    http://blade.nagaokaut.ac.jp/cgi...

    has this regexp fixed rx = /(?:#{EOL})?#{Regexp.quote boundary}(#{EOL}|--)/n

    the last modifier tells ruby to use regexp on a binary stream, rather then on the default kcode (which is utf8 under rails).

    and as a result the last byte in the jpg was joined with \r byte and it generates wrong match for

    i = buf.index(rx)

    and two extra-bytes where cut from stream and added to the file

    uploaded file

    ls -l /home/epirogov/469792-20090427134009-945951-328497.jpeg -rw-r--r-- 1 epirogov epirogov 577926 2009-04-27 08:02 /home/epirogov/469792-20090427134009-945951-328497.jpeg

    temp rack file epirogov@ep:/opt/ror/uping$ ls -l /tmp/RackMultipart.28044.0 -rw------- 1 epirogov epirogov 577928 2009-04-27 16:54 /tmp/RackMultipart.28044.0

    the left over of the buf becomes

    "-----------------------------16244688581190744854224487137\r\nContent-Disposition: form-data; name="tags"\r\n\r\n12 12 12 12 \r\n-----------------------------16244688581190744854224487137\r\nContent-Disposition: form-data; name="submit"\r\n\r\nSubmit\r\n-----------------------------16244688581190744854224487137--\r\n"

    Notice absence of \r\n in front, and after buf.slice!(0, boundary_size+2)

    buf lost 'Co'.

    after updating rack to 1.0 and restarting passenger problem went away

    April 27th, 2009 @ 10:15 PM

  22. Simon
    Simon

    Seems, that the error is still in Rack 1.0.
    I have a multipart Form for video-file-upload. The upload runs into errors on a Linux Gentoo Machine. On Max OS X all is fine.

    Rails Version is 2.3.2, Mongrel 1.5. Ruby 1.8.

    Has anybody a solution for this issue?

    Best Regards.
    Simon

    Trace:
    [09.06.09 12:04:12] [FATAL] /!\ FAILSAFE /!\ Tue Jun 09 12:04:12 +0000 2009 Status: 500 Internal Server Error bad content body

    /usr/lib64/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/vendor/rack-1.0/rack/utils.rb:311:in `parse_multipart'
    /usr/lib64/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/vendor/rack-1.0/rack/request.rb:125:in `POST'
    /usr/lib64/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/vendor/rack-1.0/rack/methodoverride.rb:15:in `call'
    /usr/lib64/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/params_parser.rb:15:in `call'
    /usr/lib64/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/rewindable_input.rb:25:in `call'
    /usr/lib64/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/session/cookie_store.rb:93:in `call'
    /usr/lib64/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/failsafe.rb:11:in `call'
    /usr/lib64/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/vendor/rack-1.0/rack/lock.rb:11:in `call'
    /usr/lib64/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/vendor/rack-1.0/rack/lock.rb:11:in `synchronize'
    /usr/lib64/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/vendor/rack-1.0/rack/lock.rb:11:in `call'
    /usr/lib64/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/dispatcher.rb:106:in `call'
    /usr/lib64/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/cgi_process.rb:44:in `dispatch_cgi'
    /usr/lib64/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/dispatcher.rb:102:in `dispatch_cgi'
    /usr/lib64/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/dispatcher.rb:28:in `dispatch'
    /usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:76:in `process'
    /usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:74:in `synchronize'
    /usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:74:in `process'
    /usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:159:in `process_client'
    /usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:158:in `each'
    /usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:158:in `process_client'
    /usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `run'
    /usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `initialize'
    /usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `new'
    /usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `run'
    /usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:268:in `initialize'
    /usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:268:in `new'
    /usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:268:in `run'
    /usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/configurator.rb:282:in `run'
    /usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/configurator.rb:281:in `each'
    /usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/configurator.rb:281:in `run'
    /usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:128:in `run'
    /usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/command.rb:212:in `run'
    /usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:281
    /usr/bin/mongrel_rails:19:in `load'
    /usr/bin/mongrel_rails:19
    

    June 9th, 2009 @ 01:13 PM

  23. Andrew Cantino
    Andrew Cantino

    I don't think this is resolved.

    In Rack1.0, I still have issues where the multi-part parser incorrectly handles "\r\n--\r\n". Rack doesn't like the leading "\r\n", but only on internal boundaries, the ends still need the proper leading and trailing \r\n's.

    June 18th, 2009 @ 07:41 PM

  24. Amie
    Amie

    I have the same issue as well. Rails 2.3.2, Ruby 1.8.6.
    I get the following error with multipart post, and it only happens with Safari3. I used Rack 1.0.0 tag from github.

    /!\ FAILSAFE /!\ Wed Jun 17 13:25:51 -0400 2009 Status: 500 Internal Server Error bad content body

    /Users/akweon/workspace_dev/testme/vendor/gems/rack-1.0.0/lib/rack/utils.rb:315:in `parse_multipart'
    /Users/akweon/workspace_dev/testme/vendor/gems/rack-1.0.0/lib/rack/request.rb:150:in `POST'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.3.2/lib/action_controller/request.rb:428:in `request_parameters'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.3.2/lib/action_controller/request.rb:381:in `parameters'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.3.2/lib/action_controller/base.rb:1279:in `assign_shortcuts'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.3.2/lib/action_controller/base.rb:518:in `process_without_filters'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.3.2/lib/action_controller/filters.rb:606:in `process'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.3.2/lib/action_controller/rescue.rb:65:in `call_with_exception'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.3.2/lib/action_controller/dispatcher.rb:91:in `dispatch'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.3.2/lib/action_controller/dispatcher.rb:111:in `_call'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.3.2/lib/action_controller/dispatcher.rb:82:in `initialize'
    /Users/akweon/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/active_record/query_cache.rb:29:in `call'
    /Users/akweon/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/active_record/query_cache.rb:29:in `call'
    /Users/akweon/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
    /Users/akweon/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/active_record/query_cache.rb:9:in `cache'
    /Users/akweon/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/active_record/query_cache.rb:28:in `call'
    /Users/akweon/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:361:in `call'
    

    June 19th, 2009 @ 01:07 AM

  25. Rishav Rastogi
    Rishav Rastogi

    Same problem here as well. But It doesn't occur with Apache/Passenger.

    June 23rd, 2009 @ 12:05 PM

  26. Carlo Schiesaro
    Carlo Schiesaro

    I have the same problem too and I'm running Passenger! I have a multiple-files flash up-loader and for some jpg files (generally small size files) I receive this error:

    
    /!\ FAILSAFE /!\  Thu Jul 23 16:08:38 +0200 2009
      Status: 500 Internal Server Error
      bad content body
        /usr/lib/ruby/gems/1.8/gems/rack-1.0.0/lib/rack/utils.rb:315:in `parse_multipart'
        /usr/lib/ruby/gems/1.8/gems/rack-1.0.0/lib/rack/request.rb:141:in `POST'
        /usr/lib/ruby/gems/1.8/gems/rack-1.0.0/lib/rack/methodoverride.rb:15:in `call'
        /usr/lib/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/params_parser.rb:15:in `call'
        /usr/lib/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/rewindable_input.rb:25:in `call'
        /usr/lib/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/session/abstract_store.rb:122:in `call'
        /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/query_cache.rb:29:in `call'
        /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
        /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/query_cache.rb:9:in `cache'
        /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/query_cache.rb:28:in `call'
        /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:361:in `call'
        /usr/lib/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/failsafe.rb:11:in `call'
        /usr/lib/ruby/gems/1.8/gems/rack-1.0.0/lib/rack/lock.rb:11:in `call'
        /usr/lib/ruby/gems/1.8/gems/rack-1.0.0/lib/rack/lock.rb:11:in `synchronize'
        /usr/lib/ruby/gems/1.8/gems/rack-1.0.0/lib/rack/lock.rb:11:in `call'
        /usr/lib/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/dispatcher.rb:106:in `call'
        /usr/lib/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/cgi_process.rb:44:in `dispatch_cgi'
        /usr/lib/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/dispatcher.rb:102:in `dispatch_cgi'
        /usr/lib/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/dispatcher.rb:28:in `dispatch'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/railz/request_handler.rb:38:in `process_request'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/abstract_request_handler.rb:165:in `main_loop'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/railz/application_spawner.rb:313:in `start_request_handler'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/railz/application_spawner.rb:281:in `handle_spawn_application'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/utils.rb:163:in `safe_fork'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/utils.rb:161:in `fork'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/utils.rb:161:in `safe_fork'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/railz/application_spawner.rb:279:in `handle_spawn_application'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/utils.rb:163:in `safe_fork'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/utils.rb:161:in `fork'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/utils.rb:161:in `safe_fork'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/railz/application_spawner.rb:278:in `handle_spawn_application'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/abstract_server.rb:317:in `__send__'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/abstract_server.rb:317:in `main_loop'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/abstract_server.rb:168:in `start_synchronously'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/abstract_server.rb:135:in `start'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/abstract_server.rb:112:in `fork'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/abstract_server.rb:112:in `start'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/railz/application_spawner.rb:178:in `start'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/railz/framework_spawner.rb:270:in `handle_spawn_application'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/railz/framework_spawner.rb:263:in `synchronize'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/railz/framework_spawner.rb:263:in `handle_spawn_application'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/abstract_server.rb:317:in `__send__'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/abstract_server.rb:317:in `main_loop'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/abstract_server.rb:168:in `start_synchronously'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/abstract_server.rb:135:in `start'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/abstract_server.rb:112:in `fork'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/abstract_server.rb:112:in `start'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/railz/framework_spawner.rb:87:in `start'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/spawn_manager.rb:218:in `spawn_rails_application'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/spawn_manager.rb:213:in `synchronize'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/spawn_manager.rb:213:in `spawn_rails_application'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/spawn_manager.rb:122:in `spawn_application'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/spawn_manager.rb:247:in `handle_spawn_application'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/abstract_server.rb:317:in `__send__'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/abstract_server.rb:317:in `main_loop'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/lib/passenger/abstract_server.rb:168:in `start_synchronously'
        /usr/lib/ruby/gems/1.8/gems/passenger-2.0.4/bin/passenger-spawn-server:46
    

    July 23rd, 2009 @ 06:20 PM

  27. ian (at cocodot)
    ian (at cocodot)

    We're seeing this as well, but only on Safari 3.0.4. 3.1.2 and 3.2.1 and 4.x work fine.

    Seems that the multipart POST goes through fine but the subsequent 302 redirect maintains the multipart form boundary even though there is not multipart.

    I've attached a http dump of what's happening on our side. Notice there's a boundary declaration in the content-type but no actual boundary. Hence the bad content body message.

    GET /account/profile HTTP/1.1
    User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/523.10.3 (KHTML, like Gecko) Version/3.0.4 Safari/523.10
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundarywOlQsi2bYiV5wZZ9
    Accept-Encoding: gzip, deflate
    Referer: http://example.com/account/profile
    Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,/;q=0.5
    Accept-Language: en-us
    Cookie: utmz=101394963.1249421411.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); example-feedback=shown; user_credentials=a3ceda139fe0814524ca5f790364b69720c9d127424fb6224dbfd158a5fbec891f858d6f95567b174c7e445084f4dc2be4eb4b809d459fa052d9ed2626beec43%3A%3A501; utma=101394963.46971259123285960.1249421411.1250182330.1250187248.9; utmc=101394963; utmb=101394963.2.10.1250187248; _example_session=BAh7CzoQX2NzcmZfdG9rZW4iMXR6bXdGRWZFMk1lbXVWOTF3NSs0OVJqekxpMkdrK3VHSVZScmdOWkVud3c9IhV1c2VyX2NyZWRlbnRpYWxzIgGAYTNjZWRhMTM5ZmUwODE0NTI0Y2E1Zjc5MDM2NGI2OTcyMGM5ZDEyNzQyNGZiNjIyNGRiZmQxNThhNWZiZWM4OTFmODU4ZDZmOTU1NjdiMTc0YzdlNDQ1MDg0ZjRkYzJiZTRlYjRiODA5ZDQ1OWZhMDUyZDllZDI2MjZiZWVjNDM6D3Nlc3Npb25faWQiJWNiNTQ2YTZjOTdiNjdiZmM0YTFhNmNkMzNiNDliYTdjOgxwcm9kdWN0aQI1FyIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNoSGFzaHsGOgtub3RpY2UiFUFjY291bnQgdXBkYXRlZCEGOgpAdXNlZHsGOwlGIhh1c2VyX2NyZWRlbnRpYWxzX2lkaQL1AQ%3D%3D--40ef23bc3fc8d6d549fc809e1c623a252e842c74
    Pragma: no-cache
    Connection: keep-alive
    Host: example.com

    August 13th, 2009 @ 08:41 PM

  28. Manish Shah
    Manish Shah

    I'm having this issue with Safari 4.0.4. Firefox is fine. Any idea?

    I'm on Rails 2.3.4, rack 1.0.1, and ruby 1.8.6 using Mac os x leopard and mongrel in development mode

    December 5th, 2009 @ 07:34 PM

  29. Jens
    Jens
    • Tag changed from multipart, upload to failsafe, multipart, rack, upload
    • Importance changed from to

    Hi,

    I am having this as well, with GET requests that may or may not subsequently get redirected by a login before_filter. The error always ocurs in rack-1..1/lib/rack/utils.rb:319 in "parse_multipart", although with a simple GET request, there should be no multipart to parse (right?).

    It is also strange that in rack/request.rb, the POST method is called, although there was never a POST. Also, most(!) requests I receive that trigger this error come from Googlebots. But not all.

    Running Passenger 2.2.5 and Rails 2.3.5, with Rack 1.0.1 on Apache 2.2.3 on Debian 5.0.

    Any help would be appreciated. Root path for the output below is /opt/ruby-enterprise-1.8.7-2010.02/lib/ruby/gems/1.8/gems/ (cropped for better readability).

    /!\ FAILSAFE /!\  30.07.2010  06:28  Status: 500 Internal Server Error
      bad content body
    rack-1.0.1/lib/rack/utils.rb:319:in `parse_multipart'
    rack-1.0.1/lib/rack/request.rb:133:in `POST'
    rack-1.0.1/lib/rack/methodoverride.rb:15:in `call'
    actionpack-2.3.5/lib/action_controller/params_parser.rb:15:in `call'
    actionpack-2.3.5/lib/action_controller/session/cookie_store.rb:93:in `call'
    actionpack-2.3.5/lib/action_controller/failsafe.rb:26:in `call'
    rack-1.0.1/lib/rack/lock.rb:11:in `call'
    rack-1.0.1/lib/rack/lock.rb:11:in `synchronize'
    rack-1.0.1/lib/rack/lock.rb:11:in `call'
    actionpack-2.3.5/lib/action_controller/dispatcher.rb:106:in `call'
    passenger-2.2.15/lib/phusion_passenger/rack/request_handler.rb:92:in `process_request'
    

    July 30th, 2010 @ 06:21 AM

  30. aerende
    aerende

    I am seeing this problem as well with Rails 2.3.5. Has there been a solution?

    !\ FAILSAFE /!\ Thu Nov 11 23:51:39 CET 2010 Status: 500 Internal Server Error bad content body

    /usr/lib/ruby/gems/1.8/gems/rack-1.0.1/lib/rack/utils.rb:319:in `parse_multipart'
    

    November 12th, 2010 @ 02:38 AM

  31. Jim Haungs
    Jim Haungs

    I'm seeing this error again in production under rails 2.3.10 and passenger 3.0.3 under apache. The upgrade from passenger 2 is the only thing that has changed.

    Users are attempting to upload largish files (2-8mb). Most work, some fail; it's intermittent. The Rack version in use is 1.1.0.

    I don't know how to test Rails with Rack 1.2.1 to see if this is resolved in that version, as rack is loaded before environment.rb is run. If I try to force it by uninstalling Rack 1.1, I get the warning that the dependencies for rails 2.3.10 will break.

    January 16th, 2011 @ 02:20 AM