All Projects → remi → plug_canonical_host

remi / plug_canonical_host

Licence: MIT license
PlugCanonicalHost ensures that all requests are served by a single canonical host.

Programming Languages

elixir
2628 projects
Makefile
30231 projects

Labels

Projects that are alternatives of or similar to plug canonical host

Dotfiles
Configurations for the tools I use every day
Stars: ✭ 898 (+3353.85%)
Mutual labels:  plug
Reverse proxy plug
🔛 an Elixir reverse proxy Plug with HTTP/2, chunked transfer and path proxying support
Stars: ✭ 112 (+330.77%)
Mutual labels:  plug
plug
A collection of pluggable traits for Eloquent (Laravel) models
Stars: ✭ 13 (-50%)
Mutual labels:  plug
Liberator
An Elixir library for building RESTful applications.
Stars: ✭ 28 (+7.69%)
Mutual labels:  plug
Flutter weather bg
A rich and cool weather dynamic background plug-in
Stars: ✭ 89 (+242.31%)
Mutual labels:  plug
Plexy
A toolkit for building excellent APIs with Elixir
Stars: ✭ 152 (+484.62%)
Mutual labels:  plug
Elixir Boilerplate
⚗ The stable base upon which we build our Elixir projects at Mirego.
Stars: ✭ 627 (+2311.54%)
Mutual labels:  plug
alternate
Plug and Phoenix helpers to localize your web app via the URL
Stars: ✭ 26 (+0%)
Mutual labels:  plug
Ewebmachine
The HTTP decision tree as a plug (full elixir rewriting of basho/webmachine with improvements)
Stars: ✭ 95 (+265.38%)
Mutual labels:  plug
Absinthe plug
Plug support for Absinthe, the GraphQL toolkit for Elixir
Stars: ✭ 209 (+703.85%)
Mutual labels:  plug
Authex
Authex is an opinionated JWT authentication and authorization library for Elixir.
Stars: ✭ 73 (+180.77%)
Mutual labels:  plug
Multiverse
Elixir package that allows to add compatibility layers via API gateways.
Stars: ✭ 87 (+234.62%)
Mutual labels:  plug
Logster
Easily parsable single line, plain text and JSON logger for Plug and Phoenix applications
Stars: ✭ 171 (+557.69%)
Mutual labels:  plug
Plug and play
Set up an Elixir Plug application with less boilerplate.
Stars: ✭ 13 (-50%)
Mutual labels:  plug
elixir plug server timing
Bring Elixir/Phoenix server-side performance metrics 📈 to Chrome's Developer Tools via the Server Timing API. Production Safe™.
Stars: ✭ 49 (+88.46%)
Mutual labels:  plug
Dot vim
🐉 The Vim Configuration of Champions. Uses Plug to manage roughly four thousand plugins. The dragon symbolizes complexity.
Stars: ✭ 660 (+2438.46%)
Mutual labels:  plug
Plug logger json
Elixir Plug that formats http request logs as json
Stars: ✭ 125 (+380.77%)
Mutual labels:  plug
taeseung vimrc
Taeseung Lee's vim setting
Stars: ✭ 16 (-38.46%)
Mutual labels:  plug
plug-blockchain
The official plug node
Stars: ✭ 16 (-38.46%)
Mutual labels:  plug
Appsignal Elixir
🟪 AppSignal for Elixir package
Stars: ✭ 176 (+576.92%)
Mutual labels:  plug



PlugCanonicalHost ensures that all requests are served by a single canonical host.
It will redirect all requests from non-canonical hosts to the canonical one.

Installation

Add plug_canonical_host to the deps function in your project’s mix.exs file:

defp deps do
  [,
    {:plug_canonical_host, "~> 2.0"}
  ]
end

Then run mix do deps.get, deps.compile inside your project’s directory.

Usage

PlugCanonicalHost can be used just as any other plugs. Add PlugCanonicalHost before all of the other plugs you want to happen after successful redirect to your canonical host.

The recommended way to define a canonical host is with an environment variable.

# config/releases.exs
config :my_app,
  canonical_host: System.get_env("CANONICAL_HOST")

# lib/my_app/endpoint.ex
defmodule MyApp.Endpoint do
  plug(:canonical_host)

  defp canonical_host(conn, _opts) do
    :my_app
    |> Application.get_env(:canonical_host)
    |> case do
      host when is_binary(host) ->
        opts = PlugCanonicalHost.init(canonical_host: host)
        PlugCanonicalHost.call(conn, opts)

      _ ->
        conn
    end
  end
end

For example, if your CANONICAL_HOST is www.example.com but your application is accessible via both example.com and www.example.com, all traffic coming through example.com will be redirected (with a 301 HTTP status) to the matching www.example.com URL.

$ curl -sI "http://example.com/foo?bar=1"
#> HTTP/1.1 301 Moved Permanently
#> Location: http://www.example.com/foo?bar=1

Allow multiple hosts

If you want to support multiple hosts, you can make them skip the canonical host behavior but you’re still going to have to specify a canonical host for unknown hosts redirects.

# config/releases.exs
config :my_app,
  canonical_host: System.get_env("CANONICAL_HOST"),
  passthrough_hosts: String.split(System.get_env("PASSTHROUGH_HOSTS"), ",")

# lib/my_app/endpoint.ex
defmodule MyApp.Endpoint do
  plug(:canonical_host)

  defp canonical_host(%Plug.Conn{host: host} = conn, _opts) do
    canonical_host = Application.get_env(:app, :canonical_host)
    passthrough_hosts = Application.get_env(:my_app, :passthrough_hosts)

    cond do
      host in passthrough_hosts ->
        conn
      is_binary(canonical_host) ->
        opts = PlugCanonicalHost.init(canonical_host: canonical_host)
        PlugCanonicalHost.call(conn, opts)
      true ->
        conn
    end
  end
end

Let’s say we have CANONICAL_HOST=www.example.com and PASSTHROUGH_HOSTS=foo.example.com,bar.example.com.

Now, all requests going through www.example.com, foo.example.com or bar.example.com path will skip the canonical host redirect behavior. Other hosts will redirect to www.example.com.

$ curl -sI "http://example.com/foo?bar=1"
#> HTTP/1.1 301 Moved Permanently
#> Location: http://www.example.com/foo?bar=1

$ curl -sI "http://foo.example.com/foo?bar=1"
#> HTTP/1.1 200 OK

$ curl -sI "http://bar.example.com/foo?bar=1"
#> HTTP/1.1 200 OK

$ curl -sI "http://www.example.com/foo?bar=1"
#> HTTP/1.1 200 OK

Exclude certain requests

If you want to exclude certain requests from redirecting to the canonical host, you can use simple pattern matching in your function arguments:

# config/releases.exs
config :my_app,
  canonical_host: System.get_env("CANONICAL_HOST")

# lib/my_app/endpoint.ex
defmodule MyApp.Endpoint do
  plug(:canonical_host)

  defp canonical_host(%Plug.Conn{request_path: "/ignore-me"} = conn, _opts) do
    Plug.Conn.send_resp(conn, 200, "👋")
  end

  defp canonical_host(conn, _opts) do
    :my_app
    |> Application.get_env(:canonical_host)
    |> case do
      host when is_binary(host) ->
        opts = PlugCanonicalHost.init(canonical_host: host)
        PlugCanonicalHost.call(conn, opts)

      _ ->
        conn
    end
  end
end

Now, all requests going to the /ignore-me path will skip the canonical host redirect behavior.

$ curl -sI "http://example.com/foo?bar=1"
#> HTTP/1.1 301 Moved Permanently
#> Location: http://www.example.com/foo?bar=1

$ curl -sI "http://example.com/ignore-me"
#> HTTP/1.1 200 OK

License

PlugCanonicalHost is © 2016-2020 Rémi Prévost and may be freely distributed under the MIT license. See the LICENSE.md file for more information.

The plug logo is based on this lovely icon by Vectors Market, from The Noun Project. Used under a Creative Commons BY 3.0 license.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].