softwaremill / sttp

The Scala HTTP client you always wanted!
https://sttp.softwaremill.com
Apache License 2.0
1.44k stars 301 forks source link

Cannot make Async-http-client use tls #1291

Open adamstarlight opened 2 years ago

adamstarlight commented 2 years ago

I'm trying to make a request through a secure http proxy using sttp and async-http-client-backend-zio1 client. The proxy (squid) is working fine, I was able to connect through it on node.js without any issues at all. Here is how it was implemented in Javascript:

import fetch from "node-fetch";
import HttpsProxyAgent from "https-proxy-agent";

const agent = new HttpsProxyAgent({
  host: "**proxy-domain-name**",
  port: 443,
  secureProxy: true,
});

fetch("https://api.ipify.org?format=json", { agent })
  .then((response) => response.json())
  .then((response) => {
    console.log("Response received");
    console.log(response);
  })
  .catch((err) => console.log(err));

However recreating something similar in Scala proven to be much more difficult! I used code below to make a request. This solution fails with Bad request, Client sent an HTTP request to an HTTPS server..

def buildBackend = AsyncHttpClientZioBackend(
  options = SttpBackendOptions.httpProxy(
    "**proxy-domain-name**",
    443
  )
)

for {
  _ <- putStrLn("Executing fetch task")
  backend <- buildBackend
  response <- request(uri"https://api.ipify.org?format=json").send(backend)
  _ <- putStrLn(response.toString())
} yield ()

How to correctly configure secure proxy using sttp?

adamstarlight commented 2 years ago

Checked network traffic in Wireshark. Node.js seem to connect to proxy using HTTPS, while sttp does not use TLS at all. Is there any way to customize this behavior?

adamstarlight commented 2 years ago

Given up on Async-http-client, this should not be this hard and disappointing to figure simple configurations... And thank you all for supporting multiple backends! Armeria was so much friendlier)

val proxyConfig =
  ProxyConfig.connect(new InetSocketAddress("***proxy-ip***", 443), true)

val clientFactory = ClientFactory.builder().proxyConfig(proxyConfig).build()
val webClient = WebClient.builder().factory(clientFactory).build()
val buildBackend = ArmeriaZioBackend.usingClient(webClient)
adamw commented 2 years ago

Thanks for the report. Maybe we are integrating with async-http-client incorrectly someplace, that would need testing. But on first look, there's no special options available for https. So to debug and determine if it's a problem with sttp or async-http-client, we'd first need to reproduce (or not) using async-http-client itself.

Out of curiosity, didn't setting the proxy using SttpBackendOptions.httpProxy work for you with the armeria backend?

halfhp commented 2 years ago

FWIW I am having similar proxy usage related issues with AsyncHttpClientCatsBackend. May not be the exact same problem in my case but definitely there are issues around using proxies with async.