From 6f0e4bb880e31bc44c1308d1773f2547680a1d26 Mon Sep 17 00:00:00 2001 From: Pedro Fayolle Date: Mon, 24 Feb 2025 16:12:09 +0900 Subject: [PATCH 1/3] Ignore Content-Length from env.request_headers --- lib/async/http/faraday/adapter.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/async/http/faraday/adapter.rb b/lib/async/http/faraday/adapter.rb index 089b787..4e0894f 100644 --- a/lib/async/http/faraday/adapter.rb +++ b/lib/async/http/faraday/adapter.rb @@ -111,7 +111,7 @@ def self.setup_parallel_manager(**options) SocketError ].freeze - # Create a Farady compatible adapter. + # Create a Faraday compatible adapter. # # @parameter timeout [Integer] The timeout for requests. # @parameter options [Hash] Additional options to pass to the underlying Async::HTTP::Client. @@ -181,6 +181,12 @@ def perform_request(env) end if headers = env.request_headers + # Ignore Content-Length if given, it will be set for us later anyway (lowercased) + if headers.has_key?("Content-Length") + headers = headers.dup + headers.delete("Content-Length") + end + headers = ::Protocol::HTTP::Headers[headers] end From d7672e06bcd96cd04b249cc38e6afe18a732edef Mon Sep 17 00:00:00 2001 From: Pedro Fayolle Date: Sun, 9 Mar 2025 15:52:12 +0900 Subject: [PATCH 2/3] Use given content-length header to set body length --- lib/async/http/faraday/adapter.rb | 32 ++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/lib/async/http/faraday/adapter.rb b/lib/async/http/faraday/adapter.rb index 4e0894f..189ffe4 100644 --- a/lib/async/http/faraday/adapter.rb +++ b/lib/async/http/faraday/adapter.rb @@ -32,11 +32,16 @@ class BodyReadWrapper < ::Protocol::HTTP::Body::Readable # # @parameter body [Interface(:read)] The input body to wrap. # @parameter block_size [Integer] The size of the blocks to read from the body. - def initialize(body, block_size: 4096) + # @parameter length [Integer | Nil] The length of the body, if known. + def initialize(body, length = nil, block_size: 4096) @body = body + @length = length @block_size = block_size end + # @attribute [Integer | Nil] The total length of the body, or `nil` if the length is unknown. + attr :length + # Close the body if possible. def close(error = nil) @body.close if @body.respond_to?(:close) @@ -168,28 +173,29 @@ def call(env) def perform_request(env) with_client(env) do |endpoint, client| + if headers = env.request_headers + headers = ::Protocol::HTTP::Headers[headers] + + # Use content-length to inform body length if given, but remove the header since it will be + # set for us later anyway, and not doing so could result in a duplicate content-length headers + # if capitalization differs + content_length = headers.delete("content-length")&.to_i + end + if body = env.body # We need to ensure the body is wrapped in a Readable object so that it can be read in chunks: # Faraday's body only responds to `#read`. if body.is_a?(::Protocol::HTTP::Body::Readable) # Good to go elsif body.respond_to?(:read) - body = BodyReadWrapper.new(body) + body = BodyReadWrapper.new(body, content_length) else - body = ::Protocol::HTTP::Body::Buffered.wrap(body) + body = ::Protocol::HTTP::Body::Buffered.wrap(body).then do |buffered| + ::Protocol::HTTP::Body::Buffered.new(buffered.chunks, content_length) + end end end - if headers = env.request_headers - # Ignore Content-Length if given, it will be set for us later anyway (lowercased) - if headers.has_key?("Content-Length") - headers = headers.dup - headers.delete("Content-Length") - end - - headers = ::Protocol::HTTP::Headers[headers] - end - method = env.method.to_s.upcase request = ::Protocol::HTTP::Request.new(endpoint.scheme, endpoint.authority, method, endpoint.path, nil, headers, body) From aeaa67975eed2a7d1982fd1f308d6ea328931610 Mon Sep 17 00:00:00 2001 From: Pedro Fayolle Date: Mon, 10 Mar 2025 20:58:01 +0900 Subject: [PATCH 3/3] Revert passing length to buffered body --- lib/async/http/faraday/adapter.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/async/http/faraday/adapter.rb b/lib/async/http/faraday/adapter.rb index 189ffe4..eef1351 100644 --- a/lib/async/http/faraday/adapter.rb +++ b/lib/async/http/faraday/adapter.rb @@ -190,9 +190,7 @@ def perform_request(env) elsif body.respond_to?(:read) body = BodyReadWrapper.new(body, content_length) else - body = ::Protocol::HTTP::Body::Buffered.wrap(body).then do |buffered| - ::Protocol::HTTP::Body::Buffered.new(buffered.chunks, content_length) - end + body = ::Protocol::HTTP::Body::Buffered.wrap(body) end end