Using an environment variable as :host for WS Origin check

Given the following configuration of a phoenix application :

use Mix.Config

config :sitecc, Sitecc.Endpoint,
  http: [port: {:system, "PORT"}],
  url: [host: "foo", port: {:system, "PORT"}],
  cache_static_manifest: "priv/static/manifest.json",
  server: true,
  root: '.',
  version: Mix.Project.config[:version]

My /etc/hosts file aliases “foo” to localhost

// From /etc/hosts
127.0.0.1  localhost foo

When I release a prod version of the application, and start the app with a POST from environment variable (eg 4000), I can connect with a browser using websockets with url "http://foo:4000/".

However, my application will be deployed several time in different production environments, with different hostname.
So I’d like to use an environment variable.
It seems like Phoenix supports that, so I tried as documented here:

 config :sitecc, Sitecc.Endpoint,
  http: [port: {:system, "PORT"}],
  url: [host: {:system, "HOST"}, port: {:system, "PORT"}],
  cache_static_manifest: "priv/static/manifest.json",
  server: true,
  root: '.',
  version: Mix.Project.config[:version]

However, when I start the server this way, Websockets connections are refused.

HOST=foo PORT=4000 _build/prod/rel/site/bin/site console 
...
16:04:06.295 [error] Could not check origin for Phoenix.Socket transport.

This happens when you are attempting a socket connection to
a different host than the one configured in your config/
files. For example, in development the host is configured
to "localhost" but you may be trying to access it from
"127.0.0.1". To fix this issue, you may either:

  1. update [url: [host: ...]] to your actual host in the
     config file for your current environment (recommended)

  2. pass the :check_origin option when configuring your
     endpoint or when configuring the transport in your
     UserSocket module, explicitly outlining which origins
     are allowed:

        check_origin: ["https://example.com",
                       "//another.com:888", "//other.com"]

Am I missing something ? Is it a bug in elixir ?

The suggested solution (explicitely setting check_origin) has roughly the same issue ; it seems like it is expanded at compile time, and I can not use a function to read the System’s env at startup.

Any idea on how to tackle that ?

2 Likes

Phoenix 1.3 introduces a way to specificy configuration on Endpoint init for cases like this where releases cannot depend mix config and runtime dependent values:

https://github.com/phoenixframework/phoenix/blob/master/lib/phoenix/endpoint.ex#L63-L83

3 Likes