From c6cf1f69f0591e4fbe0882342a70588d1ceb6da0 Mon Sep 17 00:00:00 2001 From: Janko Marohnić Date: Sat, 29 Apr 2017 09:58:20 +1000 Subject: Rely on input #size instead of #length in MockRequest.env_for StringIO is the only IO object that responds to #length, the Ruby IO interface actually uses #size. Furthermore #size is actually implemented on IO-like inputs on web servers like Unicorn and Passenger (TeeInput). This change allows using (Temp)file objects as the Rack input. --- lib/rack/mock.rb | 2 +- test/spec_mock.rb | 6 ++++++ test/spec_multipart.rb | 6 +++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/rack/mock.rb b/lib/rack/mock.rb index f3321772..d2ef2659 100644 --- a/lib/rack/mock.rb +++ b/lib/rack/mock.rb @@ -139,7 +139,7 @@ module Rack rack_input.set_encoding(Encoding::BINARY) env[RACK_INPUT] = rack_input - env["CONTENT_LENGTH"] ||= env[RACK_INPUT].length.to_s + env["CONTENT_LENGTH"] ||= env[RACK_INPUT].size.to_s opts.each { |field, value| env[field] = value if String === field diff --git a/test/spec_mock.rb b/test/spec_mock.rb index a4d4e5a5..6e5555d1 100644 --- a/test/spec_mock.rb +++ b/test/spec_mock.rb @@ -84,6 +84,12 @@ describe Rack::MockRequest do it "set content length" do env = Rack::MockRequest.env_for("/", :input => "foo") env["CONTENT_LENGTH"].must_equal "3" + + env = Rack::MockRequest.env_for("/", :input => StringIO.new("foo")) + env["CONTENT_LENGTH"].must_equal "3" + + env = Rack::MockRequest.env_for("/", :input => Tempfile.new("name").tap { |t| t << "foo" }) + env["CONTENT_LENGTH"].must_equal "3" end it "allow posting" do diff --git a/test/spec_multipart.rb b/test/spec_multipart.rb index 2f957d92..6f1f0d9a 100644 --- a/test/spec_multipart.rb +++ b/test/spec_multipart.rb @@ -107,8 +107,8 @@ describe Rack::Multipart do def rd.rewind; end wr.sync = true - # mock out length to make this pipe look like a Tempfile - def rd.length + # mock out size to make this pipe look like a Tempfile + def rd.size 1024 * 1024 * 8 end @@ -136,7 +136,7 @@ describe Rack::Multipart do fixture = { "CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x", - "CONTENT_LENGTH" => rd.length.to_s, + "CONTENT_LENGTH" => rd.size.to_s, :input => rd, } -- cgit v1.2.3-24-ge0c7