summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/rack/deflater.rb26
-rw-r--r--lib/rack/multipart/parser.rb6
-rw-r--r--test/multipart/filename_multi6
-rw-r--r--test/spec_multipart.rb6
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)