Skip to content

Commit d7672e0

Browse files
committed
Use given content-length header to set body length
1 parent 6f0e4bb commit d7672e0

File tree

1 file changed

+19
-13
lines changed

1 file changed

+19
-13
lines changed

lib/async/http/faraday/adapter.rb

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,16 @@ class BodyReadWrapper < ::Protocol::HTTP::Body::Readable
3232
#
3333
# @parameter body [Interface(:read)] The input body to wrap.
3434
# @parameter block_size [Integer] The size of the blocks to read from the body.
35-
def initialize(body, block_size: 4096)
35+
# @parameter length [Integer | Nil] The length of the body, if known.
36+
def initialize(body, length = nil, block_size: 4096)
3637
@body = body
38+
@length = length
3739
@block_size = block_size
3840
end
3941

42+
# @attribute [Integer | Nil] The total length of the body, or `nil` if the length is unknown.
43+
attr :length
44+
4045
# Close the body if possible.
4146
def close(error = nil)
4247
@body.close if @body.respond_to?(:close)
@@ -168,28 +173,29 @@ def call(env)
168173

169174
def perform_request(env)
170175
with_client(env) do |endpoint, client|
176+
if headers = env.request_headers
177+
headers = ::Protocol::HTTP::Headers[headers]
178+
179+
# Use content-length to inform body length if given, but remove the header since it will be
180+
# set for us later anyway, and not doing so could result in a duplicate content-length headers
181+
# if capitalization differs
182+
content_length = headers.delete("content-length")&.to_i
183+
end
184+
171185
if body = env.body
172186
# We need to ensure the body is wrapped in a Readable object so that it can be read in chunks:
173187
# Faraday's body only responds to `#read`.
174188
if body.is_a?(::Protocol::HTTP::Body::Readable)
175189
# Good to go
176190
elsif body.respond_to?(:read)
177-
body = BodyReadWrapper.new(body)
191+
body = BodyReadWrapper.new(body, content_length)
178192
else
179-
body = ::Protocol::HTTP::Body::Buffered.wrap(body)
193+
body = ::Protocol::HTTP::Body::Buffered.wrap(body).then do |buffered|
194+
::Protocol::HTTP::Body::Buffered.new(buffered.chunks, content_length)
195+
end
180196
end
181197
end
182198

183-
if headers = env.request_headers
184-
# Ignore Content-Length if given, it will be set for us later anyway (lowercased)
185-
if headers.has_key?("Content-Length")
186-
headers = headers.dup
187-
headers.delete("Content-Length")
188-
end
189-
190-
headers = ::Protocol::HTTP::Headers[headers]
191-
end
192-
193199
method = env.method.to_s.upcase
194200

195201
request = ::Protocol::HTTP::Request.new(endpoint.scheme, endpoint.authority, method, endpoint.path, nil, headers, body)

0 commit comments

Comments
 (0)