summary refs log tree commit
diff options
context:
space:
mode:
authorLisa Ugray <lisa.ugray@shopify.com>2017-07-07 16:59:02 -0400
committerLisa Ugray <lisa.ugray@shopify.com>2017-07-10 07:45:13 -0400
commit7fa67d8c02719b67f792eae2f1024c6b64a804ba (patch)
tree420fd73267755145a072c482c7ecc9c3dfe072d2
parent0362a54dba92626582d42f3343c209b7cdb7e713 (diff)
downloadrack-7fa67d8c02719b67f792eae2f1024c6b64a804ba.tar.gz
Stop replacing the environment in Rack::Lock
While the flow of environment information is generally downstream only,
test frameworks sometimes rely on being able to pull information added
to the environment after `.call`.
-rw-r--r--lib/rack/lock.rb15
-rw-r--r--test/spec_lock.rb12
2 files changed, 23 insertions, 4 deletions
diff --git a/lib/rack/lock.rb b/lib/rack/lock.rb
index 923dca59..b5a41e8e 100644
--- a/lib/rack/lock.rb
+++ b/lib/rack/lock.rb
@@ -11,12 +11,21 @@ module Rack
 
     def call(env)
       @mutex.lock
+      @env = env
+      @old_rack_multithread = env[RACK_MULTITHREAD]
       begin
-        response = @app.call(env.merge(RACK_MULTITHREAD => false))
-        returned = response << BodyProxy.new(response.pop) { @mutex.unlock }
+        response = @app.call(env.merge!(RACK_MULTITHREAD => false))
+        returned = response << BodyProxy.new(response.pop) { unlock }
       ensure
-        @mutex.unlock unless returned
+        unlock unless returned
       end
     end
+
+    private
+
+    def unlock
+      @mutex.unlock
+      @env[RACK_MULTITHREAD] = @old_rack_multithread
+    end
   end
 end
diff --git a/test/spec_lock.rb b/test/spec_lock.rb
index aa3efa54..c6f7c05e 100644
--- a/test/spec_lock.rb
+++ b/test/spec_lock.rb
@@ -147,7 +147,8 @@ describe Rack::Lock do
     }, false)
     env = Rack::MockRequest.env_for("/")
     env['rack.multithread'].must_equal true
-    app.call(env)
+    _, _, body = app.call(env)
+    body.close
     env['rack.multithread'].must_equal true
   end
 
@@ -191,4 +192,13 @@ describe Rack::Lock do
     lambda { app.call(env) }.must_raise Exception
     lock.synchronized.must_equal false
   end
+
+  it "not replace the environment" do
+    env  = Rack::MockRequest.env_for("/")
+    app  = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, [inner_env.object_id.to_s]] })
+
+    _, _, body = app.call(env)
+
+    body.to_enum.to_a.must_equal [env.object_id.to_s]
+  end
 end