Initial commit on Forgejo
Fresh repository history for elektrine/tarakan hosted at https://git.elektrine.com/elektrine/tarakan.
This commit is contained in:
commit
af6077b9c3
455 changed files with 78366 additions and 0 deletions
45
lib/tarakan_web/plugs/forwarded_proto.ex
Normal file
45
lib/tarakan_web/plugs/forwarded_proto.ex
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
defmodule TarakanWeb.Plugs.ForwardedProto do
|
||||
@moduledoc """
|
||||
Rewrites `conn.scheme` from a trusted reverse proxy's `X-Forwarded-Proto`.
|
||||
|
||||
Only applies when:
|
||||
|
||||
1. `:trusted_proxies` is configured (CIDR strings or IPs), and
|
||||
2. the direct TCP peer is inside that set.
|
||||
|
||||
Must run before `Plug.SSL`: behind a TLS-terminating proxy every request
|
||||
arrives as plain HTTP, so `Plug.SSL` can only tell external HTTPS from HTTP
|
||||
through this header - and the header is only meaningful from a peer we
|
||||
trust. Untrusted peers keep the real scheme, so a direct client cannot
|
||||
suppress the HTTPS redirect or HSTS by forging `X-Forwarded-Proto`.
|
||||
"""
|
||||
|
||||
@behaviour Plug
|
||||
|
||||
import Plug.Conn
|
||||
|
||||
alias TarakanWeb.Plugs.ClientIp
|
||||
|
||||
@impl true
|
||||
def init(opts), do: opts
|
||||
|
||||
@impl true
|
||||
def call(conn, _opts) do
|
||||
proxies = Application.get_env(:tarakan, :trusted_proxies, [])
|
||||
|
||||
if proxies != [] and ClientIp.trusted_ip?(conn.remote_ip, proxies) do
|
||||
rewrite_scheme(conn)
|
||||
else
|
||||
conn
|
||||
end
|
||||
end
|
||||
|
||||
# Mirrors Plug.RewriteOn's :x_forwarded_proto semantics.
|
||||
defp rewrite_scheme(conn) do
|
||||
case get_req_header(conn, "x-forwarded-proto") do
|
||||
["https" | _rest] -> %{conn | scheme: :https}
|
||||
["http" | _rest] -> %{conn | scheme: :http}
|
||||
_other -> conn
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue