Using a HTTP proxy (such as NordVPN) with hackney for HTTPoison/Tesla

Hackney is the adapter behind HTTPoison and Hackney, because it is awesome, offering features such as HTTP Keepalive, SSL support, pools and it’s battle tested and stable.

One of the experiments I recently tried was how to use a HTTP Proxy (NordVPN offers a http proxy as part of their package) with it.

You can easily do this by passing in proxy and proxy_auth.

Using plain ol’ hackney:

options = [
  proxy: {'au1111.nordvpn.com', 80},
  proxy_auth: {"mysecretusername", "mypassword"},
  with_body: true
]
:hackney.get("https://api.ipify.org?format=json", [], [], options)

Returns:

{:ok, 200,
 [
   {"Server", "Cowboy"},
   {"Connection", "keep-alive"},
   {"Content-Type", "application/json"},
   {"Vary", "Origin"},
   {"Date", "Mon, 02 Mar 2020 04:15:49 GMT"},
   {"Content-Length", "21"},
   {"Via", "1.1 vegur"}
 ], "{\"ip\":\"123.123.123.123\"}"}

HTTPoison:

HTTPoison.get(
  "https://api.ipify.org?format=json",
  [],
  [
    hackney: [
      proxy: {'au1111.nordvpn.com', 80},
      proxy_auth: {"mysecretusername", "mypassword"}
    ]
  ]
)

Returns:

{:ok,
 %HTTPoison.Response{
   body: "{\"ip\":\"123.123.123.123\"}",
   headers: [
     {"Server", "Cowboy"},
     {"Connection", "keep-alive"},
     {"Content-Type", "application/json"},
     {"Vary", "Origin"},
     {"Date", "Mon, 02 Mar 2020 04:17:55 GMT"},
     {"Content-Length", "21"},
     {"Via", "1.1 vegur"}
   ],
   request: %HTTPoison.Request{
     body: "",
     headers: [],
     method: :get,
     options: [
       hackney: [
         proxy: {'au1111.nordvpn.com', 80},
         proxy_auth: {"mysecretusername", "mysecretpassword"}
       ]
     ],
     params: %{},
     url: "https://api.ipify.org?format=json"
   },
   request_url: "https://api.ipify.org?format=json",
   status_code: 200
 }
}

Tesla:

get(
 "https://api.ipify.org?format=json",
 opts: [
   adapter: [
     proxy: {'au1111.nordvpn.com', 80},
     proxy_auth: {"mysecretusername", "mypassword"}
   ]
 ]
)

Returns:

{:ok,
 %Tesla.Env{
   __client__: %Tesla.Client{adapter: nil, fun: nil, post: [], pre: []},
   __module__: Foobar,
   body: %{"ip" => "123.123.123.123"},
   headers: [
     {"server", "Cowboy"},
     {"connection", "keep-alive"},
     {"content-type", "application/json"},
     {"vary", "Origin"},
     {"date", "Mon, 02 Mar 2020 04:19:01 GMT"},
     {"content-length", "21"},
     {"via", "1.1 vegur"}
   ],
   method: :get,
   opts: [
     adapter: [
       proxy: {'au1111.nordvpn.com', 80},
       proxy_auth: {"mysecretusername", "mysecretpassword"}
     ]
   ],
   query: [],
   status: 200,
   url: "https://api.ipify.org?format=json"
 }}