mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
Support large file uploads, moving them into a Tempfile should they cross the MAX_BODY threshold. The only change here really is that HttpRequest#body is now an IO object rather than a string. I changed the various handlers to support this.
git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@157 19e92222-5c0b-0410-8929-a290d50e31e9
This commit is contained in:
parent
3e5ca782bc
commit
c8e46fcb00
4 changed files with 25 additions and 10 deletions
|
|
@ -281,7 +281,7 @@ if __FILE__ == $0
|
|||
# Use the Configurator as an example rather than Mongrel::Camping.start
|
||||
config = Mongrel::Configurator.new :host => "0.0.0.0" do
|
||||
listener :port => 3002 do
|
||||
uri "/blog", :handler => CampingHandler.new(Blog)
|
||||
uri "/blog", :handler => Mongrel::Camping::CampingHandler.new(Blog)
|
||||
uri "/favicon", :handler => Mongrel::Error404Handler.new("")
|
||||
trap("INT") { stop }
|
||||
run
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
require 'socket'
|
||||
require 'http11'
|
||||
require 'tempfile'
|
||||
require 'thread'
|
||||
require 'stringio'
|
||||
require 'mongrel/cgi'
|
||||
|
|
@ -125,6 +126,9 @@ module Mongrel
|
|||
# this, but we'd also like to do this as well.
|
||||
MAX_HEADER=1024 * (80 + 32)
|
||||
|
||||
# Maximum request body size before it is moved out of memory and into a tempfile for reading.
|
||||
MAX_BODY=MAX_HEADER
|
||||
|
||||
# A frozen format for this is about 15% faster
|
||||
STATUS_FORMAT = "HTTP/1.1 %d %s\r\nContent-Length: %d\r\nConnection: close\r\n".freeze
|
||||
CONTENT_TYPE = "Content-Type".freeze
|
||||
|
|
@ -164,13 +168,26 @@ module Mongrel
|
|||
@params = params
|
||||
@socket = socket
|
||||
|
||||
# now, if the initial_body isn't long enough for the content length we have to fill it
|
||||
# TODO: adapt for big ass stuff by writing to a temp file
|
||||
# if the body size is too large, move into a tempfile
|
||||
clen = params[Const::CONTENT_LENGTH].to_i
|
||||
if @body.length < clen
|
||||
@body << @socket.read(clen - @body.length)
|
||||
if clen > Const::MAX_BODY
|
||||
tmpf = Tempfile.new(self.class.name)
|
||||
tmpf.binmode
|
||||
tmpf.write(@body)
|
||||
# TODO: throw an error if content-length doesn't match??
|
||||
while clen > 0
|
||||
readlen = clen < Const::CHUNK_SIZE ? clen : Const::CHUNK_SIZE
|
||||
tmpf.write(@socket.read(readlen))
|
||||
clen -= readlen
|
||||
end
|
||||
tmpf.rewind
|
||||
@body = tmpf
|
||||
else
|
||||
if @body.length < clen
|
||||
@body << @socket.read(clen - @body.length)
|
||||
end
|
||||
@body = StringIO.new(@body)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def self.escape(s)
|
||||
|
|
@ -205,7 +222,6 @@ module Mongrel
|
|||
return params
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -32,8 +32,7 @@ module Mongrel
|
|||
end
|
||||
|
||||
def process(request, response)
|
||||
req = StringIO.new(request.body)
|
||||
controller = @klass.run(req, request.params)
|
||||
controller = @klass.run(request.body, request.params)
|
||||
sendfile, clength = nil
|
||||
response.status = controller.status
|
||||
controller.headers.each do |k, v|
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ module Mongrel
|
|||
@request = request
|
||||
@response = response
|
||||
@args = *args
|
||||
@input = StringIO.new(request.body)
|
||||
@input = request.body
|
||||
@head = {}
|
||||
@out_called = false
|
||||
super(*args)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue