diff options
-rw-r--r-- | lib/rack/deflater.rb | 26 | ||||
-rw-r--r-- | lib/rack/multipart/parser.rb | 6 | ||||
-rw-r--r-- | test/multipart/filename_multi | 6 | ||||
-rw-r--r-- | test/spec_multipart.rb | 6 |
4 files changed, 33 insertions, 11 deletions
diff --git a/lib/rack/deflater.rb b/lib/rack/deflater.rb index e177fabb..9b877ce4 100644 --- a/lib/rack/deflater.rb +++ b/lib/rack/deflater.rb @@ -77,6 +77,9 @@ module Rack # Body class used for gzip encoded responses. class GzipStream + + BUFFER_LENGTH = 128 * 1_024 + # Initialize the gzip stream. Arguments: # body :: Response body to compress with gzip # mtime :: The modification time of the body, used to set the @@ -93,14 +96,21 @@ module Rack @writer = block gzip = ::Zlib::GzipWriter.new(self) gzip.mtime = @mtime if @mtime - @body.each { |part| - # Skip empty strings, as they would result in no output, - # and flushing empty parts would raise Zlib::BufError. - next if part.empty? - - gzip.write(part) - gzip.flush if @sync - } + # @body.each is equivalent to @body.gets (slow) + if @body.is_a? ::File + while part = @body.read(BUFFER_LENGTH) + gzip.write(part) + gzip.flush if @sync + end + else + @body.each { |part| + # Skip empty strings, as they would result in no output, + # and flushing empty parts would raise Zlib::BufError. + next if part.empty? + gzip.write(part) + gzip.flush if @sync + } + end ensure gzip.close end diff --git a/lib/rack/multipart/parser.rb b/lib/rack/multipart/parser.rb index 06164731..03da566f 100644 --- a/lib/rack/multipart/parser.rb +++ b/lib/rack/multipart/parser.rb @@ -300,10 +300,10 @@ module Rack when RFC2183 params = Hash[*head.scan(DISPPARM).flat_map(&:compact)] - if filename = params['filename'] - filename = $1 if filename =~ /^"(.*)"$/ - elsif filename = params['filename*'] + if filename = params['filename*'] encoding, _, filename = filename.split("'", 3) + elsif filename = params['filename'] + filename = $1 if filename =~ /^"(.*)"$/ end when BROKEN_QUOTED, BROKEN_UNQUOTED filename = $1 diff --git a/test/multipart/filename_multi b/test/multipart/filename_multi new file mode 100644 index 00000000..9ab5e1ef --- /dev/null +++ b/test/multipart/filename_multi @@ -0,0 +1,6 @@ +--AaB03x
+Content-Disposition: form-data; name="files"; filename="foo"; filename*=utf-8''bar
+Content-Type: application/octet-stream
+
+contents
+--AaB03x--
diff --git a/test/spec_multipart.rb b/test/spec_multipart.rb index b8917943..f4de71cf 100644 --- a/test/spec_multipart.rb +++ b/test/spec_multipart.rb @@ -49,6 +49,12 @@ describe Rack::Multipart do params["text"].must_equal "contents" end + it "parse multipart content with different filename and filename*" do + env = Rack::MockRequest.env_for '/', multipart_fixture(:filename_multi) + params = Rack::Multipart.parse_multipart(env) + params["files"][:filename].must_equal "bar" + end + it "set US_ASCII encoding based on charset" do env = Rack::MockRequest.env_for("/", multipart_fixture(:content_type_and_no_filename)) params = Rack::Multipart.parse_multipart(env) |