-
-
Notifications
You must be signed in to change notification settings - Fork 48
Description
While attempting to use async-http
(0.71.0) with against a reverse proxy where we need to specify a Host
header, the library sends the header twice: one with the URL's hostname value, and one with the value specified in the request. For most web servers, this results in a 400 Bad Request.
url = URI.parse("https://my.reverse.proxy.com/path/to/resource")
headers = {
"Host" => "api.example.com"
}
body = JSON.dump({ foo: "bar" })
Sync do
Async::HTTP::Internet.post(url, headers, body) do |resp|
puts resp.inspect
end
end
It looks like this is coming from protocol-http1
where the host
header is always written, irrespective if it also exists in headers
. https://github.com/socketry/protocol-http1/blob/main/lib/protocol/http1/connection.rb#L133-L138
The reverse proxy use case is one, but it could also be for any situation where the TCP/TLS socket connection should be made to a different authority than what the HTTP Host header dictates. For example, this should also be completely valid:
url = URI.parse("http://localhost:9292/path/to/resource")
headers = {
"Host" => "example.multi.tenant.app.com" # used to lookup SaaS tenant, etc
}
body = JSON.dump({ foo: "bar" })
Sync do
Async::HTTP::Internet.post(url, headers, body) do |resp|
puts resp.inspect
end
end