Rails can't handle binary file upload?

Hi,

I am trying to upload local file to a rails-app through HTTP
without multipart encoding. Doing so, I expect to get some
performance boost on transferring large files. I am stucked
Rails can’t handle binary file upload, while it’s OK with plain
text files. Let me show a sample application skeleton:

config/routes.rb:

map.connect ‘upload’, :controller => ‘application’, :action => ‘upload’

app/controllers/application.rb:

class ApplicationController < ActionController::Base
def upload
render :text => request.raw_post
end
end

Uploading plain file succeeds as following:

$ curl -v -T 42.txt http://localhost/upload

  • About to connect() to localhost port 80
  • Trying 127.0.0.1… * connected
  • Connected to localhost (127.0.0.1) port 80

PUT /upload HTTP/1.1
User-Agent: curl/7.13.1 (powerpc-apple-darwin8.0) libcurl/7.13.1
OpenSSL/0.9.7i zlib/1.2.3
Host: localhost
Pragma: no-cache
Accept: /
Content-Length: 3
Expect: 100-continue

< HTTP/1.1 100 Continue
< HTTP/1.1 200 OK
< Date: Mon, 25 Sep 2006 18:51:11 GMT
< Server: Mongrel 0.3.13.4

  • Added cookie _session_id=“b64a0dde1c857bd0d94ea95869f90294” for
    domain localhost, path /, expire 0
    < Set-Cookie: _session_id=b64a0dde1c857bd0d94ea95869f90294;
    domain=localhost; path=/
    < Status: 200 OK
    < Cache-Control: no-cache
    < Content-Type: text/html; charset=UTF-8
    < Content-Length: 3
    42
  • Connection #0 to host localhost left intact
  • Closing connection #0

Uploading binary file fails like this:

$ curl -v -T photo1.jpg http://localhost/upload

  • About to connect() to localhost port 80
  • Trying 127.0.0.1… * connected
  • Connected to localhost (127.0.0.1) port 80

PUT /upload HTTP/1.1
User-Agent: curl/7.13.1 (powerpc-apple-darwin8.0) libcurl/7.13.1
OpenSSL/0.9.7i zlib/1.2.3
Host: localhost
Pragma: no-cache
Accept: /
Content-Length: 60591
Expect: 100-continue

< HTTP/1.1 100 Continue
< HTTP/1.1 200 OK
< Date: Mon, 25 Sep 2006 18:52:15 GMT
< Content-Type: text/html
< Content-Length: 380
Status: 500 Internal Server Error
Content-Type: text/html

Application error (Apache)

Change this error message for exceptions thrown outside of an action (like in Dispatcher setups or broken Ruby code) in public/500.html

* Connection #0 to host localhost left intact * Closing connection #0

I’ve written small cgi application to prove it might perform better,
and it doesn’t show any problem. So I would like to apply my idea
to Rails application too. Comments are appreciated.


http://nohmad.sub-port.net

On Tue, 10 Oct 2006 07:13:01 +0900
“Gyoung-Yoon N.” [email protected] wrote:

Hi,

I am trying to upload local file to a rails-app through HTTP
without multipart encoding. Doing so, I expect to get some
performance boost on transferring large files. I am stucked
Rails can’t handle binary file upload, while it’s OK with plain
text files. Let me show a sample application skeleton:

Rails probably can’t, but you could go straight to source and use a
Mongrel handler. Here’s the shell to get you started:

class BinaryUploadHandler < Mongrel::HttpHandler

def process(req, resp)
# req.body at this point is a IO object, either StringIO or Tmpfile
end
end

uri “/uploadstuff”, :handler => BinaryUploadHandler.new

Put that in a mongrel.conf and start mongrel with:

mongrel_rails start -e production -S mongrel.conf

Then you’re job is to fill in the process(req,resp) method to take the
req.body and either move it or copy it to where you want. You also have
access to headers and other goodies and can do responses.

Check out the code to mongrel_upload_progress (gem install
mongrel_upload_progress) for a good example of doing this and also
tracking the upload. You could probably just modify that gem and be
done with 80% of the work already.


Zed A. Shaw, MUDCRAP-CE Master Black Belt Sifu

http://mongrel.rubyforge.org/
http://www.lingr.com/room/3yXhqKbfPy8 – Come get help.

Hi, Zed.

I had already implemented with standalone mongrel-powered server
which rely on a number of existing rails models. However, I’d like to
handle file-upload on my rails-app, because well… here is rails list!?
:slight_smile:

Another question: mongrel can handle 100 Expect request?
FYI, here’s my sample CGI application:

if ENV[‘HTTP_EXPECT’] == ‘100-Continue’
puts “Status: HTTP 100 Continue”
content = STDIN.read(ENV[‘CONTENT_LENGTH’].to_i)
File.open(‘upload.data’, ‘w’).write(content)
end
puts “Content-Type: text/html”
puts
puts “Done.”

2006/10/10, Zed A. Shaw [email protected]:

Rails can’t handle binary file upload, while it’s OK with plain
end


Zed A. Shaw, MUDCRAP-CE Master Black Belt Sifu
http://www.zedshaw.com/
http://mongrel.rubyforge.org/
http://www.lingr.com/room/3yXhqKbfPy8 – Come get help.


http://nohmad.sub-port.net