summary refs log tree commit
diff options
context:
space:
mode:
authoreileencodes <eileencodes@gmail.com>2017-05-12 15:55:17 -0400
committereileencodes <eileencodes@gmail.com>2017-05-12 17:15:43 -0400
commitc7ee52f6ba4684ce917b97c1ff4c7c523760a9d2 (patch)
treec9dc072a6664742e986728a42531287aa5485176
parent2ed117a11a8ed0455260b10f6696d4d3919f7dc5 (diff)
downloadrack-c7ee52f6ba4684ce917b97c1ff4c7c523760a9d2.tar.gz
Ensure env values are ASCII 8BIT encoded
When web servers read data from the socket it's encoded as ASCII_8BIT
because we don't know the encoding. This change makes the env closer to
what a real web server will return in production.

We don't want to run this if it's Ruby 1.8 because it doesn't support
encodings.
-rw-r--r--lib/rack/mock.rb30
-rw-r--r--test/spec_mock.rb20
2 files changed, 43 insertions, 7 deletions
diff --git a/lib/rack/mock.rb b/lib/rack/mock.rb
index 217ae0f7..6a0b7208 100644
--- a/lib/rack/mock.rb
+++ b/lib/rack/mock.rb
@@ -91,13 +91,7 @@ module Rack
 
       env = DEFAULT_ENV.dup
 
-      env[REQUEST_METHOD] = opts[:method] ? opts[:method].to_s.upcase : "GET"
-      env["SERVER_NAME"] = uri.host || "example.org"
-      env["SERVER_PORT"] = uri.port ? uri.port.to_s : "80"
-      env[QUERY_STRING] = uri.query.to_s
-      env[PATH_INFO] = (!uri.path || uri.path.empty?) ? "/" : uri.path
-      env["rack.url_scheme"] = uri.scheme || "http"
-      env["HTTPS"] = env["rack.url_scheme"] == "https" ? "on" : "off"
+      env_with_encoding(env, opts, uri)
 
       env[SCRIPT_NAME] = opts[:script_name] || ""
 
@@ -148,6 +142,28 @@ module Rack
 
       env
     end
+
+    if "<3".respond_to? :encoding
+      def self.env_with_encoding(env, opts, uri)
+        env[REQUEST_METHOD] = (opts[:method] ? opts[:method].to_s.upcase : "GET").b
+        env["SERVER_NAME"] = (uri.host || "example.org").b
+        env["SERVER_PORT"] = (uri.port ? uri.port.to_s : "80").b
+        env[QUERY_STRING] = (uri.query.to_s).b
+        env[PATH_INFO] = ((!uri.path || uri.path.empty?) ? "/" : uri.path).b
+        env["rack.url_scheme"] = (uri.scheme || "http").b
+        env["HTTPS"] = (env["rack.url_scheme"] == "https" ? "on" : "off").b
+      end
+    else
+      def self.env_with_encoding(env, opts, uri)
+        env[REQUEST_METHOD] = opts[:method] ? opts[:method].to_s.upcase : "GET"
+        env["SERVER_NAME"] = uri.host || "example.org"
+        env["SERVER_PORT"] = uri.port ? uri.port.to_s : "80"
+        env[QUERY_STRING] = uri.query.to_s
+        env[PATH_INFO] = (!uri.path || uri.path.empty?) ? "/" : uri.path
+        env["rack.url_scheme"] = uri.scheme || "http"
+        env["HTTPS"] = env["rack.url_scheme"] == "https" ? "on" : "off"
+      end
+    end
   end
 
   # Rack::MockResponse provides useful helpers for testing your apps.
diff --git a/test/spec_mock.rb b/test/spec_mock.rb
index 3ebd7776..1bb22974 100644
--- a/test/spec_mock.rb
+++ b/test/spec_mock.rb
@@ -211,6 +211,26 @@ describe Rack::MockRequest do
     Rack::MockRequest.new(capp).get('/', :lint => true)
     called.should.equal true
   end
+
+  unless "<3".respond_to? :encoding
+    should "defaults encoding to ASCII 8BIT" do
+      req = Rack::MockRequest.env_for("/foo")
+
+      keys = [
+        Rack::REQUEST_METHOD,
+        "SERVER_NAME",
+        "SERVER_PORT",
+        Rack::QUERY_STRING,
+        Rack::PATH_INFO,
+        "rack.url_scheme",
+        "HTTPS"
+      ]
+
+      keys.each do |k|
+        req[k].encoding.should.equal Encoding::ASCII_8BIT
+      end
+    end
+  end
 end
 
 describe Rack::MockResponse do