Packages
phoenix
1.7.20
1.8.9
1.8.8
1.8.7
1.8.6
1.8.5
1.8.4
1.8.3
1.8.2
1.8.1
1.8.0
1.8.0-rc.4
1.8.0-rc.3
1.8.0-rc.2
1.8.0-rc.1
1.8.0-rc.0
1.7.24
1.7.23
1.7.22
1.7.21
1.7.20
1.7.19
1.7.18
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.7.0-rc.3
1.7.0-rc.2
1.7.0-rc.1
1.7.0-rc.0
1.6.17
1.6.16
1.6.15
1.6.14
1.6.13
1.6.12
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.6.0-rc.1
1.6.0-rc.0
1.5.15
1.5.14
1.5.13
1.5.12
1.5.11
1.5.10
1.5.9
1.5.8
1.5.7
1.5.6
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.5.0-rc.0
1.4.18
1.4.17
1.4.16
1.4.15
1.4.14
1.4.13
1.4.12
1.4.11
1.4.10
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.4.0-rc.3
1.4.0-rc.2
1.4.0-rc.1
1.4.0-rc.0
1.3.5
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.3.0-rc.3
1.3.0-rc.2
1.3.0-rc.1
1.3.0-rc.0
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.2.0-rc.1
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.17.1
0.17.0
0.16.1
0.16.0
0.15.0
0.14.0
0.13.1
0.13.0
0.12.0
0.11.0
0.10.0
0.9.0
0.8.0
0.7.2
0.7.1
0.7.0
0.6.2
0.6.1
0.6.0
0.5.0
0.4.1
0.4.0
0.3.1
0.3.0
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
Productive. Reliable. Fast. A productive web framework that does not compromise speed or maintainability.
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/phoenix/endpoint/cowboy2_adapter.ex
defmodule Phoenix.Endpoint.Cowboy2Adapter do
@moduledoc """
The Cowboy2 adapter for Phoenix.
## Endpoint configuration
This adapter uses the following endpoint configuration:
* `:http` - the configuration for the HTTP server. It accepts all options
as defined by [`Plug.Cowboy`](https://hexdocs.pm/plug_cowboy/). Defaults
to `false`
* `:https` - the configuration for the HTTPS server. It accepts all options
as defined by [`Plug.Cowboy`](https://hexdocs.pm/plug_cowboy/). Defaults
to `false`
* `:drainer` - a drainer process that triggers when your application is
shutting down to wait for any on-going request to finish. It accepts all
options as defined by [`Plug.Cowboy.Drainer`](https://hexdocs.pm/plug_cowboy/Plug.Cowboy.Drainer.html).
Defaults to `[]`, which will start a drainer process for each configured endpoint,
but can be disabled by setting it to `false`.
## Custom dispatch options
You can provide custom dispatch options in order to use Phoenix's
builtin Cowboy server with custom handlers. For example, to handle
raw WebSockets [as shown in Cowboy's docs](https://github.com/ninenines/cowboy/tree/master/examples)).
The options are passed to both `:http` and `:https` keys in the
endpoint configuration. However, once you pass your custom dispatch
options, you will need to manually wire the Phoenix endpoint by
adding the following rule:
{:_, Plug.Cowboy.Handler, {MyAppWeb.Endpoint, []}}
For example:
config :myapp, MyAppWeb.Endpoint,
http: [dispatch: [
{:_, [
{"/foo", MyAppWeb.CustomHandler, []},
{:_, Plug.Cowboy.Handler, {MyAppWeb.Endpoint, []}}
]}]]
It is also important to specify your handlers first, otherwise
Phoenix will intercept the requests before they get to your handler.
"""
require Logger
@doc false
def child_specs(endpoint, config) do
otp_app = Keyword.fetch!(config, :otp_app)
refs_and_specs =
for {scheme, port} <- [http: 4000, https: 4040], opts = config[scheme] do
port = :proplists.get_value(:port, opts, port)
unless port do
Logger.error(":port for #{scheme} config is nil, cannot start server")
raise "aborting due to nil port"
end
# Ranch options are read from the top, so we keep the user opts first.
opts = :proplists.delete(:port, opts) ++ [port: port_to_integer(port), otp_app: otp_app]
child_spec(scheme, endpoint, opts, config[:code_reloader])
end
{refs, child_specs} = Enum.unzip(refs_and_specs)
if drainer = refs != [] && Keyword.get(config, :drainer, []) do
child_specs ++ [{Plug.Cowboy.Drainer, Keyword.put_new(drainer, :refs, refs)}]
else
child_specs
end
end
defp child_spec(scheme, endpoint, config, code_reloader?) do
if scheme == :https do
Application.ensure_all_started(:ssl)
end
ref = make_ref(endpoint, scheme)
plug =
if code_reloader? do
{Phoenix.Endpoint.SyncCodeReloadPlug, {endpoint, []}}
else
{endpoint, []}
end
spec = Plug.Cowboy.child_spec(ref: ref, scheme: scheme, plug: plug, options: config)
spec = update_in(spec.start, &{__MODULE__, :start_link, [scheme, endpoint, &1]})
{ref, spec}
end
@doc false
def start_link(scheme, endpoint, {m, f, [ref | _] = a}) do
# ref is used by Ranch to identify its listeners, defaulting
# to plug.HTTP and plug.HTTPS and overridable by users.
case apply(m, f, a) do
{:ok, pid} ->
Logger.info(info(scheme, endpoint, ref))
{:ok, pid}
{:error, {:shutdown, {_, _, {:listen_error, _, :eaddrinuse}}}} = error ->
Logger.error([info(scheme, endpoint, ref), " failed, port already in use"])
error
{:error, {:shutdown, {_, _, {{_, {:error, :eaddrinuse}}, _}}}} = error ->
Logger.error([info(scheme, endpoint, ref), " failed, port already in use"])
error
{:error, _} = error ->
error
end
end
defp info(scheme, endpoint, ref) do
server = "cowboy #{Application.spec(:cowboy)[:vsn]}"
"Running #{inspect(endpoint)} with #{server} at #{bound_address(scheme, ref)}"
end
defp bound_address(scheme, ref) do
case :ranch.get_addr(ref) do
{:local, unix_path} ->
"#{unix_path} (#{scheme}+unix)"
{addr, port} ->
"#{:inet.ntoa(addr)}:#{port} (#{scheme})"
end
rescue
_ -> scheme
end
# TODO: Remove this once {:system, env_var} deprecation is removed
defp port_to_integer({:system, env_var}), do: port_to_integer(System.get_env(env_var))
defp port_to_integer(port) when is_binary(port), do: String.to_integer(port)
defp port_to_integer(port) when is_integer(port), do: port
def server_info(endpoint, scheme) do
address =
endpoint
|> make_ref(scheme)
|> :ranch.get_addr()
{:ok, address}
rescue
e -> {:error, Exception.message(e)}
end
defp make_ref(endpoint, scheme) do
Module.concat(endpoint, scheme |> Atom.to_string() |> String.upcase())
end
end