Packages
plug
0.12.2
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/ssl.ex
defmodule Plug.SSL do
@moduledoc """
A plug to force SSL
If the scheme of a request is https, it'll add `strict-transport-security`
header to enable HTTP Strict Transport Security.
Otherwise, the request will be redirected to a corresponding location
with `https` scheme by setting the `location` header of the reponse.
And the status code will be 301 if method of `conn` is `GET` or `HEAD`,
or 307 in other situations.
## Options
* `:hsts` - a boolean on enabling HSTS or not and defaults to true.
* `:expires` - seconds to expires for HSTS, defaults to 31536000(a year).
* `:subdomains` - a boolean on including subdomains or not in HSTS,
defaults to false.
* `:host` - a new host to redirect to if the request's scheme is `http`.
"""
@behaviour Plug
import Plug.Conn
alias Plug.Conn
def init(opts) do
{hsts_header(opts), Keyword.get(opts, :host)}
end
def call(conn, {hsts, host}) do
if conn.scheme == :https do
put_hsts_header(conn, hsts)
else
redirect_to_https(conn, host)
end
end
# http://tools.ietf.org/html/draft-hodges-strict-transport-sec-02
defp hsts_header(opts) do
if Keyword.get(opts, :hsts, true) do
expires = Keyword.get(opts, :expires, 31536000)
subdomains = Keyword.get(opts, :subdomains, false)
"max-age=#{expires}" <>
if(subdomains, do: "; includeSubDomains", else: "")
end
end
defp put_hsts_header(conn, hsts_header) when is_binary(hsts_header) do
put_resp_header(conn, "strict-transport-security", hsts_header)
end
defp put_hsts_header(conn, _), do: conn
defp redirect_to_https(%Conn{host: host} = conn, custom_host) do
status = if conn.method in ~w(HEAD GET), do: 301, else: 307
uri = %URI{scheme: "https", host: custom_host || host,
path: full_path(conn), query: conn.query_string}
conn
|> put_resp_header("location", to_string(uri))
|> send_resp(status, "")
|> halt
end
end