From 7a9401dadf27dedee36d1920727b0384facbb37b Mon Sep 17 00:00:00 2001 From: Akira Matsuda Date: Sat, 9 Jul 2022 16:46:19 +0900 Subject: Reuse the Array object from parent middleware (#1887) in order not to allocate another Array object for passing the response to the next middleware. Co-authored-by: Samuel Williams --- 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 6b314bec..47fb36ac 100644 --- a/lib/rack/chunked.rb +++ b/lib/rack/chunked.rb @@ -99,7 +99,7 @@ module Rack # 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 @@ module Rack 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 42bc135b..2feb0674 100644 --- a/lib/rack/common_logger.rb +++ b/lib/rack/common_logger.rb @@ -40,9 +40,10 @@ module Rack # 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 a1e9fafd..c3b334a2 100644 --- a/lib/rack/conditional_get.rb +++ b/lib/rack/conditional_get.rb @@ -28,17 +28,17 @@ module Rack 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 6a3711e2..cbac93ab 100644 --- a/lib/rack/content_length.rb +++ b/lib/rack/content_length.rb @@ -17,18 +17,18 @@ module Rack 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 58c734a3..19f07824 100644 --- a/lib/rack/content_type.rb +++ b/lib/rack/content_type.rb @@ -21,13 +21,13 @@ module Rack 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 8e18e160..3f6177e6 100644 --- a/lib/rack/deflater.rb +++ b/lib/rack/deflater.rb @@ -44,10 +44,10 @@ module Rack 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 @@ module Rack 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 7f90532b..fa78b472 100644 --- a/lib/rack/etag.rb +++ b/lib/rack/etag.rb @@ -26,7 +26,7 @@ module Rack 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 @@ module Rack end end - [status, headers, body] + response end private diff --git a/lib/rack/head.rb b/lib/rack/head.rb index 3bd9a75b..c1c430f6 100644 --- a/lib/rack/head.rb +++ b/lib/rack/head.rb @@ -12,17 +12,15 @@ module Rack 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 405f4cbb..a1bfa696 100644 --- a/lib/rack/runtime.rb +++ b/lib/rack/runtime.rb @@ -21,7 +21,7 @@ module Rack 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 @@ module Rack 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 43cabf91..45f0a8c3 100644 --- a/lib/rack/sendfile.rb +++ b/lib/rack/sendfile.rb @@ -111,7 +111,7 @@ module Rack 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 @@ module Rack # '?' 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 @@ module Rack 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 @@ module Rack 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 a32c523e..b6f75a01 100644 --- a/lib/rack/show_status.rb +++ b/lib/rack/show_status.rb @@ -22,7 +22,7 @@ module Rack 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 @@ module Rack 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 6f3b8bc5..0b94cc73 100644 --- a/lib/rack/tempfile_reaper.rb +++ b/lib/rack/tempfile_reaper.rb @@ -17,17 +17,17 @@ module Rack env[RACK_TEMPFILES] ||= [] begin - status, headers, body = @app.call(env) + _, _, body = response = @app.call(env) rescue Exception env[RACK_TEMPFILES]&.each(&:close!) raise end - body_proxy = BodyProxy.new(body) do + response[2] = BodyProxy.new(body) do env[RACK_TEMPFILES]&.each(&:close!) end - [status, headers, body_proxy] + response end end end -- cgit v1.2.3-24-ge0c7