10
votes

I am trying to get the identifier of a website based on its domain, but after writing a plug for it, i am running into a problem wherein all the links in the system are returning the root url content.

lib/myapp/plugs/request_var.ex

defmodule Myapp.Plug.RequestVar do
  import Plug.Conn

  @doc false
  def init(default), do: default

  @doc false
  def call(conn, router) do
    host = conn.host
    if host == "ll.com" || host == "domain1.com" do
      slug = "domain1"
    else
      slug = "domain2"
    end

    conn |> put_private(:site_slug, slug)
  end
end

In lib/myapp/endpoint.ex

plug Myapp.Plug.RequestVar, Myapp.Router
plug Myapp.Router

Is anything wrong with this plug?

Edit: Fixed the "if" condition based on the responses.

2

2 Answers

6
votes

The url is generated from your endpoint.url and not the host for the Plug.Conn

From https://github.com/phoenixframework/phoenix/blob/8fe0538fd7be2adb05e2362b02fa8bd6bf3c6c46/lib/phoenix/router/helpers.ex#L13:

  def url(_router, %Conn{private: private}) do
    private.phoenix_endpoint.url
  end

  def url(_router, %Socket{endpoint: endpoint}) do
    endpoint.url
  end

  def url(_router, %URI{} = uri) do
    uri_to_string(uri)
  end

  def url(_router, endpoint) when is_atom(endpoint) do
    endpoint.url
  end

You can override this by using struct_url/0:

struct_url = update_in(Endpoint.struct_url.host, fn (_) -> "domain2" end)
some_url(struct_url, :index)

You can also define a second endpoint for your second domain. If your links are internal then you should consider using the _path functions instead of the _url functions. The _url helpers are generally used when the domain is required (such as emails.)

3
votes

You have an error in your if clause. It will always be true.

iex(1)> host = "l2.com"
"l2.com"
iex(2)> host == "ll.com" || "domain1.com"
"domain1.com"

For both valid and invalid domains.

iex(3)> host = "ll.com"                  
"ll.com"
iex(4)> host == "ll.com" || "domain1.com"
true

Test:

iex(6)> if host == "ll.com" || "domain1.com" do
...(6)>   IO.puts "if"
...(6)> end
if
:ok

You have to change your clause to if host == "ll.com" || host == "domain1.com" do. But. It is not idiomatic to use this kind of clauses. It is generally better to use pattern-matching.