class Async::HTTP::Internet

def call(method, url, headers = nil, body = nil)

def call(method, url, headers = nil, body = nil)
	endpoint = Endpoint.parse(url)
	client = self.client_for(endpoint)
	
	body = Body::Buffered.wrap(body)
	headers = ::Protocol::HTTP::Headers[headers]
	
	request = ::Protocol::HTTP::Request.new(endpoint.scheme, endpoint.authority, method, endpoint.path, nil, headers, body)
	
	return client.call(request)
end

def client_for(endpoint)

def client_for(endpoint)
	key = host_key(endpoint)
	
	@clients.fetch(key) do
		@clients[key] = self.make_client(endpoint)
	end
end

def close

def close
	# The order of operations here is to avoid a race condition between iterating over clients (#close may yield) and creating new clients.
	clients = @clients.values
	@clients.clear
	
	clients.each(&:close)
end

def host_key(endpoint)

def host_key(endpoint)
	url = endpoint.url.dup
	
	url.path = ""
	url.fragment = nil
	url.query = nil
	
	return url
end

def initialize(**options)

def initialize(**options)
	@clients = Hash.new
	@options = options
end

def make_client(endpoint)

def make_client(endpoint)
	::Protocol::HTTP::AcceptEncoding.new(
		Client.new(endpoint, **@options)
	)
end