Skip to content

Commit

Permalink
Use buffer string when parsing multipart requests
Browse files Browse the repository at this point in the history
Passing a buffer string as a second argument to `IO#read` will make the
Rack input IO, instead of creating a new string object on each read,
load each chunk into the same string instance (overwriting the previous
content). This greatly reduces string allocations.
  • Loading branch information
janko committed Jun 11, 2018
1 parent 7420be2 commit 14aeddd
Showing 1 changed file with 6 additions and 5 deletions.
11 changes: 6 additions & 5 deletions lib/rack/multipart/parser.rb
Expand Up @@ -20,15 +20,15 @@ def initialize(io, content_length)
@cursor = 0
end

def read(size)
def read(size, outbuf = nil)
return if @cursor >= @content_length

left = @content_length - @cursor

str = if left < size
@io.read left
@io.read left, outbuf
else
@io.read size
@io.read size, outbuf
end

if str
Expand Down Expand Up @@ -63,13 +63,14 @@ def self.parse(io, content_length, content_type, tmpfile, bufsize, qp)
return EMPTY unless boundary

io = BoundedIO.new(io, content_length) if content_length
outbuf = String.new

parser = new(boundary, tmpfile, bufsize, qp)
parser.on_read io.read(bufsize)
parser.on_read io.read(bufsize, outbuf)

loop do
break if parser.state == :DONE
parser.on_read io.read(bufsize)
parser.on_read io.read(bufsize, outbuf)
end

io.rewind
Expand Down

0 comments on commit 14aeddd

Please sign in to comment.