summary refs log tree commit
diff options
context:
space:
mode:
authorHongli Lai (Phusion) <hongli@phusion.nl>2009-06-17 17:32:24 -0500
committerJoshua Peek <josh@joshpeek.com>2009-06-17 17:32:24 -0500
commitfd1c1d2e494d9a7d15e0458602ef121f244addc3 (patch)
treed5d113d0b29a7df17c674aef180f29248bdf98ab
parentd8d812ec5f8984d271dbf13e40aecf2cf0ac7436 (diff)
downloadrack-fd1c1d2e494d9a7d15e0458602ef121f244addc3.tar.gz
Document more clearly that rack.input must be opened in binary mode, and enforce it in Rack::Lint
Signed-off-by: Joshua Peek <josh@joshpeek.com>
-rw-r--r--lib/rack/lint.rb11
-rw-r--r--test/spec_rack_lint.rb22
2 files changed, 32 insertions, 1 deletions
diff --git a/lib/rack/lint.rb b/lib/rack/lint.rb
index bf2e9787..796807a0 100644
--- a/lib/rack/lint.rb
+++ b/lib/rack/lint.rb
@@ -233,8 +233,17 @@ module Rack
     ## === The Input Stream
     ##
     ## The input stream is an IO-like object which contains the raw HTTP
-    ## POST data. If it is a file then it must be opened in binary mode.
+    ## POST data.
     def check_input(input)
+      ## When applicable, its external encoding must be "ASCII-8BIT" and it
+      ## must be opened in binary mode, for Ruby 1.9 compatibility.
+      assert("rack.input #{input} does not have ASCII-8BIT as its external encoding") {
+        input.external_encoding.name == "ASCII-8BIT"
+      } if input.respond_to?(:external_encoding)
+      assert("rack.input #{input} is not opened in binary mode") {
+        input.binmode?
+      } if input.respond_to?(:binmode?)
+      
       ## The input stream must respond to +gets+, +each+, +read+ and +rewind+.
       [:gets, :each, :read, :rewind].each { |method|
         assert("rack.input #{input} does not respond to ##{method}") {
diff --git a/test/spec_rack_lint.rb b/test/spec_rack_lint.rb
index 8c6419dd..a227b56d 100644
--- a/test/spec_rack_lint.rb
+++ b/test/spec_rack_lint.rb
@@ -110,6 +110,28 @@ context "Rack::Lint" do
       Rack::Lint.new(nil).call(env("rack.input" => ""))
     }.should.raise(Rack::Lint::LintError).
       message.should.match(/does not respond to #gets/)
+    
+    lambda {
+      input = Object.new
+      def input.binmode?
+        false
+      end
+      Rack::Lint.new(nil).call(env("rack.input" => input))
+    }.should.raise(Rack::Lint::LintError).
+      message.should.match(/is not opened in binary mode/)
+    
+    lambda {
+      input = Object.new
+      def input.external_encoding
+        result = Object.new
+        def result.name
+          "US-ASCII"
+        end
+        result
+      end
+      Rack::Lint.new(nil).call(env("rack.input" => input))
+    }.should.raise(Rack::Lint::LintError).
+      message.should.match(/does not have ASCII-8BIT as its external encoding/);puts RUBY_VERSION
   end
 
   specify "notices error errors" do