From f0c9ab49e52a372ef29b275554329df81c9ee379 Mon Sep 17 00:00:00 2001 From: Akira Matsuda Date: Sun, 8 May 2022 00:51:20 +0900 Subject: [PATCH] Reuse the Array object from parent middleware in order not to allocate another Array object for passing the response to the next middleware --- lib/rack/chunked.rb | 8 ++++---- lib/rack/common_logger.rb | 7 ++++--- lib/rack/conditional_get.rb | 12 ++++++------ lib/rack/content_length.rb | 6 +++--- lib/rack/content_type.rb | 4 ++-- lib/rack/deflater.rb | 9 +++++---- lib/rack/etag.rb | 4 ++-- lib/rack/head.rb | 14 ++++++-------- lib/rack/runtime.rb | 4 ++-- lib/rack/sendfile.rb | 8 ++++---- lib/rack/show_status.rb | 14 +++++++------- lib/rack/tempfile_reaper.rb | 6 +++--- 12 files changed, 48 insertions(+), 48 deletions(-) diff --git a/lib/rack/chunked.rb b/lib/rack/chunked.rb index 6b314bece..47fb36ac1 100644 --- a/lib/rack/chunked.rb +++ b/lib/rack/chunked.rb @@ -99,7 +99,7 @@ def chunkable_version?(ver) # but does not have content-length or transfer-encoding headers, # modify the response to use chunked transfer-encoding. def call(env) - status, headers, body = @app.call(env) + status, headers, body = response = @app.call(env) if chunkable_version?(env[SERVER_PROTOCOL]) && !STATUS_WITH_NO_ENTITY_BODY.key?(status.to_i) && @@ -108,13 +108,13 @@ def call(env) headers[TRANSFER_ENCODING] = 'chunked' if headers['trailer'] - body = TrailerBody.new(body) + response[2] = TrailerBody.new(body) else - body = Body.new(body) + response[2] = Body.new(body) end end - [status, headers, body] + response end end end diff --git a/lib/rack/common_logger.rb b/lib/rack/common_logger.rb index d833e2e11..600fb9ab8 100644 --- a/lib/rack/common_logger.rb +++ b/lib/rack/common_logger.rb @@ -40,9 +40,10 @@ def initialize(app, logger = nil) # cause the request not to be logged. def call(env) began_at = Utils.clock_time - status, headers, body = @app.call(env) - body = BodyProxy.new(body) { log(env, status, headers, began_at) } - [status, headers, body] + status, headers, body = response = @app.call(env) + + response[2] = BodyProxy.new(body) { log(env, status, headers, began_at) } + response end private diff --git a/lib/rack/conditional_get.rb b/lib/rack/conditional_get.rb index a1e9fafd2..c3b334a2e 100644 --- a/lib/rack/conditional_get.rb +++ b/lib/rack/conditional_get.rb @@ -28,17 +28,17 @@ def initialize(app) def call(env) case env[REQUEST_METHOD] when "GET", "HEAD" - status, headers, body = @app.call(env) + status, headers, body = response = @app.call(env) + if status == 200 && fresh?(env, headers) - status = 304 + response[0] = 304 headers.delete(CONTENT_TYPE) headers.delete(CONTENT_LENGTH) - original_body = body - body = Rack::BodyProxy.new([]) do - original_body.close if original_body.respond_to?(:close) + response[2] = Rack::BodyProxy.new([]) do + body.close if body.respond_to?(:close) end end - [status, headers, body] + response else @app.call(env) end diff --git a/lib/rack/content_length.rb b/lib/rack/content_length.rb index 6a3711e23..cbac93abc 100644 --- a/lib/rack/content_length.rb +++ b/lib/rack/content_length.rb @@ -17,18 +17,18 @@ def initialize(app) end def call(env) - status, headers, body = @app.call(env) + status, headers, body = response = @app.call(env) if !STATUS_WITH_NO_ENTITY_BODY.key?(status.to_i) && !headers[CONTENT_LENGTH] && !headers[TRANSFER_ENCODING] && body.respond_to?(:to_ary) - body = body.to_ary + response[2] = body = body.to_ary headers[CONTENT_LENGTH] = body.sum(&:bytesize).to_s end - [status, headers, body] + response end end end diff --git a/lib/rack/content_type.rb b/lib/rack/content_type.rb index 48c91e6c4..341d52c09 100644 --- a/lib/rack/content_type.rb +++ b/lib/rack/content_type.rb @@ -20,13 +20,13 @@ def initialize(app, content_type = "text/html") end def call(env) - status, headers, body = @app.call(env) + status, headers, _ = response = @app.call(env) unless STATUS_WITH_NO_ENTITY_BODY.key?(status.to_i) headers[CONTENT_TYPE] ||= @content_type end - [status, headers, body] + response end end end diff --git a/lib/rack/deflater.rb b/lib/rack/deflater.rb index 7752d17e2..011996d6f 100644 --- a/lib/rack/deflater.rb +++ b/lib/rack/deflater.rb @@ -44,10 +44,10 @@ def initialize(app, options = {}) end def call(env) - status, headers, body = @app.call(env) + status, headers, body = response = @app.call(env) unless should_deflate?(env, status, headers, body) - return [status, headers, body] + return response end request = Request.new(env) @@ -67,9 +67,10 @@ def call(env) headers.delete(CONTENT_LENGTH) mtime = headers["last-modified"] mtime = Time.httpdate(mtime).to_i if mtime - [status, headers, GzipStream.new(body, mtime, @sync)] + response[2] = GzipStream.new(body, mtime, @sync) + response when "identity" - [status, headers, body] + response else # when nil # Only possible encoding values here are 'gzip', 'identity', and nil message = "An acceptable encoding for the requested resource #{request.fullpath} could not be found." diff --git a/lib/rack/etag.rb b/lib/rack/etag.rb index 7f90532b1..fa78b472f 100644 --- a/lib/rack/etag.rb +++ b/lib/rack/etag.rb @@ -26,7 +26,7 @@ def initialize(app, no_cache_control = nil, cache_control = DEFAULT_CACHE_CONTRO end def call(env) - status, headers, body = @app.call(env) + status, headers, body = response = @app.call(env) if etag_status?(status) && body.respond_to?(:to_ary) && !skip_caching?(headers) body = body.to_ary @@ -42,7 +42,7 @@ def call(env) end end - [status, headers, body] + response end private diff --git a/lib/rack/head.rb b/lib/rack/head.rb index 3bd9a75bb..c1c430f65 100644 --- a/lib/rack/head.rb +++ b/lib/rack/head.rb @@ -12,17 +12,15 @@ def initialize(app) end def call(env) - status, headers, body = @app.call(env) + _, _, body = response = @app.call(env) if env[REQUEST_METHOD] == HEAD - [ - status, headers, Rack::BodyProxy.new([]) do - body.close if body.respond_to? :close - end - ] - else - [status, headers, body] + response[2] = Rack::BodyProxy.new([]) do + body.close if body.respond_to? :close + end end + + response end end end diff --git a/lib/rack/runtime.rb b/lib/rack/runtime.rb index 405f4cbba..a1bfa696e 100644 --- a/lib/rack/runtime.rb +++ b/lib/rack/runtime.rb @@ -21,7 +21,7 @@ def initialize(app, name = nil) def call(env) start_time = Utils.clock_time - status, headers, body = @app.call(env) + _, headers, _ = response = @app.call(env) request_time = Utils.clock_time - start_time @@ -29,7 +29,7 @@ def call(env) headers[@header_name] = FORMAT_STRING % request_time end - [status, headers, body] + response end end end diff --git a/lib/rack/sendfile.rb b/lib/rack/sendfile.rb index 43cabf91a..45f0a8c36 100644 --- a/lib/rack/sendfile.rb +++ b/lib/rack/sendfile.rb @@ -111,7 +111,7 @@ def initialize(app, variation = nil, mappings = []) end def call(env) - status, headers, body = @app.call(env) + status, headers, body = response = @app.call(env) if body.respond_to?(:to_path) case type = variation(env) @@ -122,7 +122,7 @@ def call(env) # '?' must be percent-encoded because it is not query string but a part of path headers[type.downcase] = ::Rack::Utils.escape_path(url).gsub('?', '%3F') obody = body - body = Rack::BodyProxy.new([]) do + response[2] = Rack::BodyProxy.new([]) do obody.close if obody.respond_to?(:close) end else @@ -133,7 +133,7 @@ def call(env) headers[CONTENT_LENGTH] = '0' headers[type.downcase] = path obody = body - body = Rack::BodyProxy.new([]) do + response[2] = Rack::BodyProxy.new([]) do obody.close if obody.respond_to?(:close) end when '', nil @@ -141,7 +141,7 @@ def call(env) env[RACK_ERRORS].puts "Unknown x-sendfile variation: '#{type}'.\n" end end - [status, headers, body] + response end private diff --git a/lib/rack/show_status.rb b/lib/rack/show_status.rb index a32c523ea..b6f75a016 100644 --- a/lib/rack/show_status.rb +++ b/lib/rack/show_status.rb @@ -22,7 +22,7 @@ def initialize(app) end def call(env) - status, headers, body = @app.call(env) + status, headers, body = response = @app.call(env) empty = headers[CONTENT_LENGTH].to_i <= 0 # client or server error, or explicit message @@ -40,15 +40,15 @@ def call(env) html = @template.result(binding) size = html.bytesize - original_body = body - body = Rack::BodyProxy.new([html]) do - original_body.close if original_body.respond_to?(:close) + response[2] = Rack::BodyProxy.new([html]) do + body.close if body.respond_to?(:close) end - [status, headers.merge(CONTENT_TYPE => "text/html", CONTENT_LENGTH => size.to_s), body] - else - [status, headers, body] + headers[CONTENT_TYPE] = "text/html" + headers[CONTENT_LENGTH] = size.to_s end + + response end def h(obj) # :nodoc: diff --git a/lib/rack/tempfile_reaper.rb b/lib/rack/tempfile_reaper.rb index 6af0b6629..594182c17 100644 --- a/lib/rack/tempfile_reaper.rb +++ b/lib/rack/tempfile_reaper.rb @@ -17,16 +17,16 @@ def call(env) env[RACK_TEMPFILES] ||= [] begin - status, headers, body = @app.call(env) + _, _, body = response = @app.call(env) rescue Exception env[RACK_TEMPFILES].each(&:close!) unless env[RACK_TEMPFILES].nil? raise end - body_proxy = BodyProxy.new(body) do + response[2] = BodyProxy.new(body) do env[RACK_TEMPFILES].each(&:close!) unless env[RACK_TEMPFILES].nil? end - [status, headers, body_proxy] + response end end end