-
-
Notifications
You must be signed in to change notification settings - Fork 14
POST requests with no body include content-length
header twice
#51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This feels like a bug in Faraday, as it should depend on the underlying protocol to set the content length (if needed).
Separately, headers that contain upper case characters (e.g. cc @iMacTia |
@ioquatix I think you're right, but I wondered if all Faraday adapters would play nicely and add require "rubygems"
require "bundler/inline"
gemfile do
source "https://rubygems.org"
gem "async-http-faraday", require: false
gem "faraday-em_http", require: false
gem "faraday-em_synchrony", require: false
gem "faraday-excon", require: false
gem "faraday-httpclient", "~> 2.0", require: false
gem "faraday-net_http_persistent", "~> 2.0", require: false
gem "faraday-patron", require: false
gem "faraday-typhoeus", require: false
gem "faraday-http", require: false
gem "httpx", require: false
end
require "socket"
require "faraday"
# Faraday adapters
require "async/http/faraday"
require "faraday/em_http"
#require "faraday/em_synchrony"
require "faraday/excon"
require "faraday/http"
require "faraday/httpclient"
require "faraday/net_http_persistent"
require "faraday/patron"
require "faraday/typhoeus"
require "httpx/adapters/faraday"
# Patch Faraday::Env to not set content-length, instead change it to x-content-length
class Faraday::Env
remove_const(:ContentLength)
ContentLength = "x-content-length".freeze
end
%i[
async_http
excon
http
httpclient
httpx
net_http
net_http_persistent
patron
typhoeus
].each do |adapter|
Faraday::METHODS_WITH_BODY.each do |method|
server_thread = Thread.new do
server = TCPServer.new(2000)
socket = server.accept
while l = socket.gets
print l.inspect[1..-2]
print " ✅" if l.match?(/^content-length: 0\r\n/i)
puts
break if l == "\r\n"
end
socket.close
server.close
end
conn = Faraday.new(url: "http://localhost:2000") do |f|
f.adapter adapter
end
puts "** #{method.upcase} with no body using #{adapter} adapter: **"
begin
conn.send(method, "/")
rescue Faraday::ConnectionFailed
end
server_thread.join
puts
end
end And here's the output, stripped to just the relevant parts:
So it seems all adapters correctly add Also, I didn't test EM::HTTP and EM::Synchrony, since I couldn't make those adapters work on first try. Not sure how important the
Should I open an issue on Faraday for this then? |
This is most excellent work, well done and thanks for the extremely detailed comparison. I do believe that we should open an issue on Faraday and see what they think. In the mean time, I'm okay to implement a patch to strip that header from the request. If you have time, do you want to submit a PR for that? |
This is great @pilaf, really love the thorough research here 👏 ! |
@iMacTia Got it, and thanks for taking the time to look into this. I opened a ticket on Faraday's GitHub since it seemed more appropriate to continue the discussion over there. |
I'll see if I can come up with a patch, but I can't promise I'll deliver one since I'm not familiar with |
Minimal reproduction (requires a webserver running on localhost:9292):
Here's the raw request I get, notice the double
content-length
(although with different capitalization):Changing the Faraday adapter to
:net_http
doesn't have this problem.The capitalized
Content-Length
seems to be set by Faraday itself atFaraday::Env#clear_body
.Async::HTTP
seems to be adding the lower-case one.I also noticed that setting the body to empty string doesn't suffer from this issue, but I can't do that in my case since I'm using a 3rd party library:
Results in:
The text was updated successfully, but these errors were encountered: