Does HTTPoison respect system proxy setting?

I’m in China, we have this so-called great firewall blocking access to some sites.

So we employ some proxies to bypass it, like running

export http_proxy=ip:port;export https_proxy=ip:port

command under my terminal.

After doing that, I would expect HTTPoison to use the proxy ip:port, but obviously it’s not in my test, so I have to pass the proxy option myself:

HTTPoison.get! "https://sites-get-blocked.org", [], [{:proxy, "http://127.0.0.1:8888"}]

My question is, does it respect the system proxy setting? Anyone has a better way to handle a problem like this?

Nope, neither HTTPoison nor HTTpotion, nor their underlying erlang libraries do that as far as a quick google turns out. But it should be easy to write a wrapper which looks up the environment variables and then appends the proxy option if it is not already there.

Yeah, this is what I do at last:

defmodule TelegramBot do
  use HTTPoison.Base

  @endpoint "https://api.telegram.org/bot"
  @token Application.get_env(:myflow, Telegram) |> Keyword.fetch!(:token)
  @proxy Application.get_env(:myflow, Telegram) |> Keyword.get(:proxy)

  def process_url(url) do
    @endpoint <> @token <> url
  end

  defp process_request_options(options) do
    if @proxy do Keyword.merge(options, [proxy: @proxy]) else options end
  end
end

When there’s proxy presented in dev.exs, pass it to HTTPoison.

Why don’t you use System.get_env/1?

Wow, I think it’s much better with System.get_env, thanks!

Be careful with using System.get_env/1. It will use the environment variables that are set when your app is compiled. It does not use the environment variables at runtime.

For more info: http://blog.plataformatec.com.br/2016/05/how-to-config-environment-variables-with-elixir-and-exrm/

1 Like

It’s not quite that simple. Well, now that I think about it, it might actually be even simpler than that. System.get_env/1 gets the environment variable at the moment it is executed. Full stop. There’s nothing special about this function doing different things at compile time or run time.

The challenge is understanding when it is executed. If used in a module attribute or macro, it gets executed at compile time. If used in a plain function, it gets executed at run time. If put in a config/*.exs file, it gets executed when mix executes. And this paragraph is true of any function. It’s nothing specific to System.get_env/1

2 Likes

We are not talking about using it in mix.exs or config/*.exs, we are talking about having it straight in the application. In a wrapper around another function call.

2 Likes

I think that was because you call it in Elixir’s config file which is consolidated at compile time.