如何向同一主机发送HTTPS GET请求并指定目标IP?
Great question! Since you already have the HTTP case working by specifying the host header alongside an IP-based URL, HTTPS needs a small adjustment because of SSL certificate validation—certificates are tied to domain names, not raw IP addresses. Let’s break down how to make this work with HTTPoison:
The Core Issue
If you tried using https://104.16.110.208/ with a Host header directly, HTTPoison would reject the connection. That’s because the SSL certificate for digitalocean.com doesn’t match the IP address in the URL. Instead, we need to:
- Use the actual domain in the request URL (so certificate validation passes)
- Force the underlying socket to connect to your manually chosen IP address
Working Code Example
# Pick your target IP from the dig results target_ip = "104.16.110.208" # The domain the SSL certificate is issued for target_domain = "digitalocean.com" # Convert the IP string to an Erlang-style tuple (required for socket options) ip_tuple = target_ip |> String.split(".") |> Enum.map(&String.to_integer/1) |> List.to_tuple() # Send the HTTPS request case HTTPoison.get("https://#{target_domain}/", [], transport_options: [ socket_opts: [ {:inet, :addr, ip_tuple} # Force connection to this specific IP ] ] ) do {:ok, response} -> IO.inspect(response.status_code) {:error, reason} -> IO.inspect(reason) end
How This Works
- We use
https://digitalocean.comas the URL, so HTTPoison automatically validates the SSL certificate against the domain (no certificate errors) - The
transport_options[:socket_opts][{:inet, :addr, ip_tuple}]tells the underlying Erlang socket to connect directly to your chosen IP, skipping standard DNS resolution for the domain - The
Hostheader is automatically set todigitalocean.comfrom the URL, so the server knows which virtual host to route the request to
Custom Host Header (If Needed)
If you need to specify a custom Host header (like www.digitalocean.com instead of the root domain), just add it to the headers list:
HTTPoison.get("https://#{target_domain}/", [{"Host", "www.digitalocean.com"}], transport_options: [ socket_opts: [ {:inet, :addr, ip_tuple} ] ] )
IPv6 Notes
If you’re working with IPv6 addresses, convert the string to an Erlang tuple using :inet.parse_address/1 instead:
{:ok, ip_tuple} = :inet.parse_address("2604:a880:400:d1::891:6001")
内容的提问来源于stack exchange,提问作者Barna Kovacs

