2

I would like to send HTTPS requests to the same host but I would like to choose the target IP every time.

For example "dig digitalocean.com" shows these IPs:

digitalocean.com.   300 IN  A   104.16.110.208
digitalocean.com.   300 IN  A   104.16.112.208
digitalocean.com.   300 IN  A   104.16.109.208
digitalocean.com.   300 IN  A   104.16.113.208
digitalocean.com.   300 IN  A   104.16.111.208

With HTTP it works:

HTTPoison.get("http://104.16.110.208/", [{"host","www.digitalocean.com"}])
{:ok,
 %HTTPoison.Response{body: "", headers: [...], request_url: "http://104.16.110.208/",
  status_code: 301}}

But with HTTPS I get an error:

HTTPoison.get("https://104.16.110.208/", [{"host", "www.digitalocean.com"}])
{:error,
 %HTTPoison.Error{id: nil,
  reason: {:options, {{:server_name_indication, '104.16.110.208'}}}}}

Is there a way to achieve this with HTTPS with HTTPoison, or in Elixir/Erlang without modifying etc/hosts?

Barna Kovacs
  • 1,226
  • 1
  • 14
  • 35
  • 2
    I don't know if this is possible without allowing insecure https (I needed to use `--insecure` to make this request with`curl` as well), but this works: `HTTPoison.get("https://104.16.110.208/", [{"host", "www.digitalocean.com"}], hackney: [:insecure])`. – Dogbert Apr 16 '18 at 17:05
  • @Dogbert thx, it makes sense. But I have copied your exact HTTPoison line and for me it doesn't work. Can you tell me the version it ran for you? – Barna Kovacs Apr 17 '18 at 08:13
  • I have found how to achieve it with curl `https:// DOMAIN.TLD --resolve 'DOMAIN.TLD:443:IP_ADDRESS'`. But I can't figure it out how to do it per request in Erlang/Elixir. – Barna Kovacs Apr 17 '18 at 11:52
  • Could you put that in the question? I have (almost, but HTTPotion as elixir lib) the same question… basically sth like “I'm looking for an equivalent of `curl`'s `--resolve` option” – Patrick J. S. Jun 13 '18 at 14:12
  • Try adding `ssl_options` in `hackney` with `server_name_indication` set to `www.digitalocean.com`. See http://erlang.org/doc/man/ssl.html. The thing is if you don't give a SNI name then it will be used from the host name/IP you used while connecting to the server – Tarun Lalwani Jun 13 '18 at 18:06
  • @PatrickJ.S., please check the answer I just posted – Tarun Lalwani Jun 14 '18 at 10:54

1 Answers1

2

You need to use it like below

HTTPoison.get("https://104.16.110.208/", [{"host","www.digitalocean.com"}], hackney: [{:ssl_options, [{:server_name_indication, "digitalocean.com"}]}])

or

HTTPoison.get("https://104.16.110.208/", [{"host","www.digitalocean.com"}], hackney: [ssl_options: [server_name_indication: 'digitalocean.com']])

Since you are using IP to connect, by default the server_name_indication will be assumed as the IP. This is what you need to override in your case

Working

Patrick J. S.
  • 2,885
  • 19
  • 26
Tarun Lalwani
  • 142,312
  • 9
  • 204
  • 265
  • That almost works. I had to use single quotes for the `ssl_option` (it said something the error above, which makes sense, since it is an erlang lib, there should be “erlang quotes”). Also, I think the formatting could be impoved. `get(…, hackney: [ssl_options: [server_name_indication: 'digitalocean.com]])'` worked for me. – Patrick J. S. Jun 18 '18 at 22:45
  • @PatrickJ.S., thanks for the feedback. Updated the answer with the same – Tarun Lalwani Jun 19 '18 at 12:12