From df4a028a9c992db19ee50e7d8cc00d5d1f54f1a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janko=20Marohni=C4=87?= Date: Fri, 18 Aug 2017 18:58:53 +0200 Subject: [PATCH] Don't use #eof? when parsing multipart On chunked requests (`Transfer-Encoding: chunked`) content length won't be present, so `#eof?` will be called on the Rack input directly. However, the Rack input doesn't have to respond to `#eof?`, it's not part of the Rack specification. For example, `Rack::Lint::InputWrapper` and `Unicorn::StreamInput` don't respond to `#eof?`. This means that in development and on Unicorn, multipart parsing will fail for chunked request. This change refactors the multipart parser so that it doesn't call `#eof?`. --- lib/rack/multipart/parser.rb | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/lib/rack/multipart/parser.rb b/lib/rack/multipart/parser.rb index c02e26f6b..c19aefa77 100644 --- a/lib/rack/multipart/parser.rb +++ b/lib/rack/multipart/parser.rb @@ -39,8 +39,6 @@ def read(size) str end - def eof?; @content_length == @cursor; end - def rewind @io.rewind end @@ -65,11 +63,11 @@ def self.parse(io, content_length, content_type, tmpfile, bufsize, qp) io = BoundedIO.new(io, content_length) if content_length parser = new(boundary, tmpfile, bufsize, qp) - parser.on_read io.read(bufsize), io.eof? + parser.on_read io.read(bufsize) loop do break if parser.state == :DONE - parser.on_read io.read(bufsize), io.eof? + parser.on_read io.read(bufsize) end io.rewind @@ -181,8 +179,8 @@ def initialize(boundary, tempfile, bufsize, query_parser) @collector = Collector.new tempfile end - def on_read content, eof - handle_empty_content!(content, eof) + def on_read content + handle_empty_content!(content) @buf << content run_parser end @@ -358,10 +356,9 @@ def tag_multipart_encoding(filename, content_type, name, body) end - def handle_empty_content!(content, eof) + def handle_empty_content!(content) if content.nil? || content.empty? - raise EOFError if eof - return true + raise EOFError end end end