Packages
plug
1.12.0
1.20.3
1.20.2
1.20.1
retired
1.20.0
retired
1.19.5
1.19.4
1.19.3
1.19.2
1.19.1
1.19.0
1.18.5
1.18.4
1.18.3
1.18.2
1.18.1
1.18.0
1.17.4
1.17.3
1.17.2
1.17.1
1.17.0
1.16.6
1.16.5
1.16.4
1.16.3
1.16.2
1.16.1
1.16.0
1.15.6
1.15.5
1.15.4
1.15.3
1.15.2
1.15.1
1.15.0
1.14.2
1.14.1
1.14.0
1.13.6
1.13.5
1.13.4
1.13.3
1.13.2
1.13.1
retired
1.13.0
retired
1.12.1
1.12.0
1.11.1
1.11.0
1.10.4
1.10.3
1.10.2
1.10.1
1.10.0
1.9.0
1.8.3
1.8.2
1.8.1
1.8.0
1.7.2
1.7.1
1.7.0
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.1
1.5.0
1.5.0-rc.2
1.5.0-rc.1
1.5.0-rc.0
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.4.0-rc.0
1.3.6
1.3.5
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.2.0-rc.0
1.1.9
1.1.8
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.14.0
0.13.1
0.13.0
0.12.2
0.12.1
0.12.0
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.0
0.6.0
0.5.3
0.5.2
0.5.1
0.5.0
0.4.4
0.4.3
0.4.2
0.4.1
Compose web applications with functions
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/plug/rewrite_on.ex
defmodule Plug.RewriteOn do
@moduledoc """
A plug to rewrite the request's host/port/protocol from `x-forwarded-*` headers.
If your Plug application is behind a proxy that handles HTTPS, you may
need to tell Plug to parse the proper protocol from the `x-forwarded-*`
header.
plug Plug.RewriteOn, [:x_forwarded_host, :x_forwarded_port, :x_forwarded_proto]
The supported values are:
* `:x_forwarded_host` - to override the host based on on the "x-forwarded-host" header
* `:x_forwarded_port` - to override the port based on on the "x-forwarded-port" header
* `:x_forwarded_proto` - to override the protocol based on on the "x-forwarded-proto" header
Since rewriting the scheme based on `x-forwarded-*` headers can open up
security vulnerabilities, only use this plug if:
* your app is behind a proxy
* your proxy strips the given `x-forwarded-*` headers from all incoming requests
* your proxy sets the `x-forwarded-*` headers and sends it to Plug
"""
@behaviour Plug
import Plug.Conn, only: [get_req_header: 2]
@impl true
def init(header), do: List.wrap(header)
@impl true
def call(conn, [:x_forwarded_proto | rewrite_on]) do
conn
|> put_scheme(get_req_header(conn, "x-forwarded-proto"))
|> call(rewrite_on)
end
def call(conn, [:x_forwarded_port | rewrite_on]) do
conn
|> put_port(get_req_header(conn, "x-forwarded-port"))
|> call(rewrite_on)
end
def call(conn, [:x_forwarded_host | rewrite_on]) do
conn
|> put_host(get_req_header(conn, "x-forwarded-host"))
|> call(rewrite_on)
end
def call(_conn, [other | _rewrite_on]) do
raise "unknown rewrite: #{inspect(other)}"
end
def call(conn, []) do
conn
end
defp put_scheme(%{scheme: :http, port: 80} = conn, ["https"]),
do: %{conn | scheme: :https, port: 443}
defp put_scheme(conn, ["https"]),
do: %{conn | scheme: :https}
defp put_scheme(%{scheme: :https, port: 443} = conn, ["http"]),
do: %{conn | scheme: :http, port: 80}
defp put_scheme(conn, ["http"]),
do: %{conn | scheme: :http}
defp put_scheme(conn, _scheme),
do: conn
defp put_host(conn, [proper_host]),
do: %{conn | host: proper_host}
defp put_host(conn, _),
do: conn
defp put_port(conn, headers) do
with [header] <- headers,
{port, ""} <- Integer.parse(header) do
%{conn | port: port}
else
_ -> conn
end
end
end