summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Williams <samuel.williams@oriontransfer.co.nz>2020-03-11 12:41:25 +1300
committerSamuel Williams <samuel.williams@oriontransfer.co.nz>2020-07-28 18:19:12 +1200
commit918459ac2e0980198486e3091a0f9651d5a54413 (patch)
tree3b31412e1a3d8c732604dc88366c7932c3662a33
parent649c72bab9e7b50d657b5b432d0c205c95c2be07 (diff)
downloadrack-918459ac2e0980198486e3091a0f9651d5a54413.tar.gz
Remove `rack.multithread`/`rack.multiprocess`/`rack.run_once`.
These variables generally come too late to be useful. Removed `Rack::Lock` which depends on these variables.
-rw-r--r--CHANGELOG.md4
-rw-r--r--README.rdoc1
-rw-r--r--SPEC.rdoc13
-rw-r--r--lib/rack.rb4
-rw-r--r--lib/rack/handler/cgi.rb3
-rw-r--r--lib/rack/handler/webrick.rb3
-rwxr-xr-xlib/rack/lint.rb19
-rw-r--r--lib/rack/lock.rb32
-rw-r--r--lib/rack/mock.rb3
-rw-r--r--lib/rack/request.rb1
-rw-r--r--test/spec_lock.rb203
-rw-r--r--test/spec_session_pool.rb2
-rw-r--r--test/spec_thin.rb3
-rw-r--r--test/spec_webrick.rb3
14 files changed, 6 insertions, 288 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1bc4a7ad..3766b6fd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -28,6 +28,10 @@ All notable changes to this project will be documented in this file. For info on
- [[CVE-2020-8184](https://nvd.nist.gov/vuln/detail/CVE-2020-8184)] Do not allow percent-encoded cookie name to override existing cookie names. BREAKING CHANGE: Accessing cookie names that require URL encoding with decoded name no longer works. ([@fletchto99](https://github.com/fletchto99))
+### Removed
+
+- Remove `rack.multithread`/`rack.multiprocess`/`rack.run_once`. These variables generally come too late to be useful. Removed `Rack::Lock` which depends on these variables. ([#1618](https://github.com/rack/rack/pull/1591), [@ioquatix](https://github.com/ioquatix))
+
## [2.2.2] - 2020-02-11
### Fixed
diff --git a/README.rdoc b/README.rdoc
index caebc845..37d9fa6a 100644
--- a/README.rdoc
+++ b/README.rdoc
@@ -77,7 +77,6 @@ middleware:
* Rack::Files, for serving static files.
* Rack::Head, for returning an empty body for HEAD requests.
* Rack::Lint, for checking conformance to the \Rack API.
-* Rack::Lock, for serializing requests using a mutex.
* Rack::Logger, for setting a logger to handle logging errors.
* Rack::MethodOverride, for modifying the request method based on a submitted
parameter.
diff --git a/SPEC.rdoc b/SPEC.rdoc
index 4cb02d74..89981fd7 100644
--- a/SPEC.rdoc
+++ b/SPEC.rdoc
@@ -74,19 +74,6 @@ Rack-specific variables:
request URL.
<tt>rack.input</tt>:: See below, the input stream.
<tt>rack.errors</tt>:: See below, the error stream.
-<tt>rack.multithread</tt>:: true if the application object may be
- simultaneously invoked by another thread
- in the same process, false otherwise.
-<tt>rack.multiprocess</tt>:: true if an equivalent application object
- may be simultaneously invoked by another
- process, false otherwise.
-<tt>rack.run_once</tt>:: true if the server expects
- (but does not guarantee!) that the
- application will only be invoked this one
- time during the life of its containing
- process. Normally, this will only be true
- for a server based on CGI
- (or something similar).
<tt>rack.hijack?</tt>:: present and true if the server supports
connection hijacking. See below, hijacking.
<tt>rack.hijack</tt>:: an object responding to #call that must be
diff --git a/lib/rack.rb b/lib/rack.rb
index b931292e..31690bcc 100644
--- a/lib/rack.rb
+++ b/lib/rack.rb
@@ -55,9 +55,6 @@ module Rack
RACK_SESSION = 'rack.session'
RACK_SESSION_OPTIONS = 'rack.session.options'
RACK_SHOWSTATUS_DETAIL = 'rack.showstatus.detail'
- RACK_MULTITHREAD = 'rack.multithread'
- RACK_MULTIPROCESS = 'rack.multiprocess'
- RACK_RUNONCE = 'rack.run_once'
RACK_URL_SCHEME = 'rack.url_scheme'
RACK_HIJACK = 'rack.hijack'
RACK_IS_HIJACK = 'rack.hijack?'
@@ -94,7 +91,6 @@ module Rack
autoload :Handler, "rack/handler"
autoload :Head, "rack/head"
autoload :Lint, "rack/lint"
- autoload :Lock, "rack/lock"
autoload :Logger, "rack/logger"
autoload :MediaType, "rack/media_type"
autoload :MethodOverride, "rack/method_override"
diff --git a/lib/rack/handler/cgi.rb b/lib/rack/handler/cgi.rb
index b514fe74..df0864a1 100644
--- a/lib/rack/handler/cgi.rb
+++ b/lib/rack/handler/cgi.rb
@@ -18,9 +18,6 @@ module Rack
RACK_VERSION => Rack::VERSION,
RACK_INPUT => Rack::RewindableInput.new($stdin),
RACK_ERRORS => $stderr,
- RACK_MULTITHREAD => false,
- RACK_MULTIPROCESS => true,
- RACK_RUNONCE => true,
RACK_URL_SCHEME => ["yes", "on", "1"].include?(ENV[HTTPS]) ? "https" : "http"
)
diff --git a/lib/rack/handler/webrick.rb b/lib/rack/handler/webrick.rb
index 07c7f9e0..9ce73b40 100644
--- a/lib/rack/handler/webrick.rb
+++ b/lib/rack/handler/webrick.rb
@@ -75,9 +75,6 @@ module Rack
RACK_VERSION => Rack::VERSION,
RACK_INPUT => rack_input,
RACK_ERRORS => $stderr,
- RACK_MULTITHREAD => true,
- RACK_MULTIPROCESS => false,
- RACK_RUNONCE => false,
RACK_URL_SCHEME => ["yes", "on", "1"].include?(env[HTTPS]) ? "https" : "http",
RACK_IS_HIJACK => true,
RACK_HIJACK => lambda { raise NotImplementedError, "only partial hijack is supported."},
diff --git a/lib/rack/lint.rb b/lib/rack/lint.rb
index 67264771..c7c621ef 100755
--- a/lib/rack/lint.rb
+++ b/lib/rack/lint.rb
@@ -157,22 +157,6 @@ module Rack
## <tt>rack.errors</tt>:: See below, the error stream.
- ## <tt>rack.multithread</tt>:: true if the application object may be
- ## simultaneously invoked by another thread
- ## in the same process, false otherwise.
-
- ## <tt>rack.multiprocess</tt>:: true if an equivalent application object
- ## may be simultaneously invoked by another
- ## process, false otherwise.
-
- ## <tt>rack.run_once</tt>:: true if the server expects
- ## (but does not guarantee!) that the
- ## application will only be invoked this one
- ## time during the life of its containing
- ## process. Normally, this will only be true
- ## for a server based on CGI
- ## (or something similar).
-
## <tt>rack.hijack?</tt>:: present and true if the server supports
## connection hijacking. See below, hijacking.
@@ -274,8 +258,7 @@ module Rack
##
%w[REQUEST_METHOD SERVER_NAME QUERY_STRING
- rack.version rack.input rack.errors
- rack.multithread rack.multiprocess rack.run_once].each { |header|
+ rack.version rack.input rack.errors].each { |header|
assert("env missing required key #{header}") { env.include? header }
}
diff --git a/lib/rack/lock.rb b/lib/rack/lock.rb
deleted file mode 100644
index 4bae3a90..00000000
--- a/lib/rack/lock.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-require 'thread'
-
-module Rack
- # Rack::Lock locks every request inside a mutex, so that every request
- # will effectively be executed synchronously.
- class Lock
- def initialize(app, mutex = Mutex.new)
- @app, @mutex = app, mutex
- end
-
- 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) { unlock }
- ensure
- unlock unless returned
- end
- end
-
- private
-
- def unlock
- @mutex.unlock
- @env[RACK_MULTITHREAD] = @old_rack_multithread
- end
- end
-end
diff --git a/lib/rack/mock.rb b/lib/rack/mock.rb
index f330ae18..c704ef82 100644
--- a/lib/rack/mock.rb
+++ b/lib/rack/mock.rb
@@ -44,9 +44,6 @@ module Rack
RACK_VERSION => Rack::VERSION,
RACK_INPUT => StringIO.new,
RACK_ERRORS => StringIO.new,
- RACK_MULTITHREAD => true,
- RACK_MULTIPROCESS => true,
- RACK_RUNONCE => false,
}.freeze
def initialize(app)
diff --git a/lib/rack/request.rb b/lib/rack/request.rb
index 74377ede..3225066f 100644
--- a/lib/rack/request.rb
+++ b/lib/rack/request.rb
@@ -159,7 +159,6 @@ module Rack
def content_length; get_header('CONTENT_LENGTH') end
def logger; get_header(RACK_LOGGER) end
def user_agent; get_header('HTTP_USER_AGENT') end
- def multithread?; get_header(RACK_MULTITHREAD) end
# the referer of the client
def referer; get_header('HTTP_REFERER') end
diff --git a/test/spec_lock.rb b/test/spec_lock.rb
deleted file mode 100644
index 89570498..00000000
--- a/test/spec_lock.rb
+++ /dev/null
@@ -1,203 +0,0 @@
-# frozen_string_literal: true
-
-require_relative 'helper'
-
-class Lock
- attr_reader :synchronized
-
- def initialize
- @synchronized = false
- end
-
- def lock
- @synchronized = true
- end
-
- def unlock
- @synchronized = false
- end
-end
-
-module LockHelpers
- def lock_app(app, lock = Lock.new)
- app = if lock
- Rack::Lock.new app, lock
- else
- Rack::Lock.new app
- end
- Rack::Lint.new app
- end
-end
-
-describe Rack::Lock do
- include LockHelpers
-
- describe 'Proxy' do
- include LockHelpers
-
- it 'delegate each' do
- env = Rack::MockRequest.env_for("/")
- response = Class.new {
- attr_accessor :close_called
- def initialize; @close_called = false; end
- def each; %w{ hi mom }.each { |x| yield x }; end
- }.new
-
- app = lock_app(lambda { |inner_env| [200, { "Content-Type" => "text/plain" }, response] })
- response = app.call(env)[2]
- list = []
- response.each { |x| list << x }
- list.must_equal %w{ hi mom }
- end
-
- it 'delegate to_path' do
- lock = Lock.new
- env = Rack::MockRequest.env_for("/")
-
- res = ['Hello World']
- def res.to_path ; "/tmp/hello.txt" ; end
-
- app = Rack::Lock.new(lambda { |inner_env| [200, { "Content-Type" => "text/plain" }, res] }, lock)
- body = app.call(env)[2]
-
- body.must_respond_to :to_path
- body.to_path.must_equal "/tmp/hello.txt"
- end
-
- it 'not delegate to_path if body does not implement it' do
- env = Rack::MockRequest.env_for("/")
-
- res = ['Hello World']
-
- app = lock_app(lambda { |inner_env| [200, { "Content-Type" => "text/plain" }, res] })
- body = app.call(env)[2]
-
- body.wont_respond_to :to_path
- end
- end
-
- it 'call super on close' do
- env = Rack::MockRequest.env_for("/")
- response = Class.new {
- attr_accessor :close_called
- def initialize; @close_called = false; end
- def close; @close_called = true; end
- }.new
-
- app = lock_app(lambda { |inner_env| [200, { "Content-Type" => "text/plain" }, response] })
- app.call(env)
- response.close_called.must_equal false
- response.close
- response.close_called.must_equal true
- end
-
- it "not unlock until body is closed" do
- lock = Lock.new
- env = Rack::MockRequest.env_for("/")
- response = Object.new
- app = lock_app(lambda { |inner_env| [200, { "Content-Type" => "text/plain" }, response] }, lock)
- lock.synchronized.must_equal false
- response = app.call(env)[2]
- lock.synchronized.must_equal true
- response.close
- lock.synchronized.must_equal false
- end
-
- it "return value from app" do
- env = Rack::MockRequest.env_for("/")
- body = [200, { "Content-Type" => "text/plain" }, %w{ hi mom }]
- app = lock_app(lambda { |inner_env| body })
-
- res = app.call(env)
- res[0].must_equal body[0]
- res[1].must_equal body[1]
- res[2].to_enum.to_a.must_equal ["hi", "mom"]
- end
-
- it "call synchronize on lock" do
- lock = Lock.new
- env = Rack::MockRequest.env_for("/")
- app = lock_app(lambda { |inner_env| [200, { "Content-Type" => "text/plain" }, %w{ a b c }] }, lock)
- lock.synchronized.must_equal false
- app.call(env)
- lock.synchronized.must_equal true
- end
-
- it "unlock if the app raises" do
- lock = Lock.new
- env = Rack::MockRequest.env_for("/")
- app = lock_app(lambda { raise Exception }, lock)
- lambda { app.call(env) }.must_raise Exception
- lock.synchronized.must_equal false
- end
-
- it "unlock if the app throws" do
- lock = Lock.new
- env = Rack::MockRequest.env_for("/")
- app = lock_app(lambda {|_| throw :bacon }, lock)
- lambda { app.call(env) }.must_throw :bacon
- lock.synchronized.must_equal false
- end
-
- it "set multithread flag to false" do
- app = lock_app(lambda { |env|
- env['rack.multithread'].must_equal false
- [200, { "Content-Type" => "text/plain" }, %w{ a b c }]
- }, false)
- env = Rack::MockRequest.env_for("/")
- env['rack.multithread'].must_equal true
- _, _, body = app.call(env)
- body.close
- env['rack.multithread'].must_equal true
- end
-
- it "reset original multithread flag when exiting lock" do
- app = Class.new(Rack::Lock) {
- def call(env)
- env['rack.multithread'].must_equal true
- super
- end
- }.new(lambda { |env| [200, { "Content-Type" => "text/plain" }, %w{ a b c }] })
- Rack::Lint.new(app).call(Rack::MockRequest.env_for("/"))
- end
-
- it 'not unlock if an error is raised before the mutex is locked' do
- lock = Class.new do
- def initialize() @unlocked = false end
- def unlocked?() @unlocked end
- def lock() raise Exception end
- def unlock() @unlocked = true end
- end.new
- env = Rack::MockRequest.env_for("/")
- app = lock_app(proc { [200, { "Content-Type" => "text/plain" }, []] }, lock)
- lambda { app.call(env) }.must_raise Exception
- lock.unlocked?.must_equal false
- end
-
- it "not reset the environment while the body is proxied" do
- proxy = Class.new do
- attr_reader :env
- def initialize(env) @env = env end
- end
- app = Rack::Lock.new lambda { |env| [200, { "Content-Type" => "text/plain" }, proxy.new(env)] }
- response = app.call(Rack::MockRequest.env_for("/"))[2]
- response.env['rack.multithread'].must_equal false
- end
-
- it "unlock if an exception occurs before returning" do
- lock = Lock.new
- env = Rack::MockRequest.env_for("/")
- app = lock_app(proc { [].freeze }, lock)
- 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
diff --git a/test/spec_session_pool.rb b/test/spec_session_pool.rb
index aba93fb1..306786f6 100644
--- a/test/spec_session_pool.rb
+++ b/test/spec_session_pool.rb
@@ -225,7 +225,7 @@ describe Rack::Session::Pool do
tnum = rand(7).to_i + 5
r = Array.new(tnum) do
Thread.new(treq) do |run|
- run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
+ run.get('/', "HTTP_COOKIE" => cookie)
end
end.reverse.map{|t| t.run.join.value }
r.each do |resp|
diff --git a/test/spec_thin.rb b/test/spec_thin.rb
index 5f714e0f..26917836 100644
--- a/test/spec_thin.rb
+++ b/test/spec_thin.rb
@@ -47,9 +47,6 @@ describe Rack::Handler::Thin do
it "have rack headers" do
GET("/")
response["rack.version"].must_equal [1, 0]
- response["rack.multithread"].must_equal false
- response["rack.multiprocess"].must_equal false
- response["rack.run_once"].must_equal false
end
it "have CGI headers on GET" do
diff --git a/test/spec_webrick.rb b/test/spec_webrick.rb
index b0bfa2b0..a6ea3cb5 100644
--- a/test/spec_webrick.rb
+++ b/test/spec_webrick.rb
@@ -50,9 +50,6 @@ describe Rack::Handler::WEBrick do
it "have rack headers" do
GET("/test")
response["rack.version"].must_equal [1, 3]
- response["rack.multithread"].must_equal true
- assert_equal false, response["rack.multiprocess"]
- assert_equal false, response["rack.run_once"]
end
it "have CGI headers on GET" do