### Example: Normal HTTP Response Initialization Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-handler.md Illustrates the expected return value from Plug.Cowboy.Handler.init/2 for a standard GET request. ```elixir # Normal HTTP response Plug.Cowboy.Handler.init( %{method: "GET", path: "/", ...}, {MyApp.Router, []} ) # Returns: {:ok, updated_req, {MyApp.Router, []}} ``` -------------------------------- ### Start HTTP Server (Quick Reference) Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/OVERVIEW.md A quick way to start an HTTP server on a specified port. ```elixir Plug.Cowboy.http(Plug, [], port: 4000) ``` -------------------------------- ### WebSocket Upgrade Flow Example Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-handler.md This outlines the sequence of calls starting from Plug.Conn.upgrade_adapter/3 to the WebSocket handler's initialization. ```elixir # 1. Plug calls: Plug.Conn.upgrade_adapter(conn, :websocket, # {MyApp.WebSocket, user_state, %{idle_timeout: 30_000}}) # # 2. Handler stores in conn.adapter # # 3. init/2 detects upgrade, returns upgrade tuple # # 4. Cowboy calls upgrade/4 # # 5. :cowboy_websocket.upgrade/5 starts WebSocket protocol handler # # 6. MyApp.WebSocket.websocket_init/1 called with user_state ``` -------------------------------- ### Get Peer Data Example Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/types.md An example showing how to retrieve and destructure peer data using Plug.Conn.get_peer_data/1. ```elixir %{address: ip, port: port, ssl_cert: cert} = Plug.Conn.get_peer_data(conn) # ip = {127, 0, 0, 1} # port = 54321 # cert = nil (HTTP) or binary (HTTPS) ``` -------------------------------- ### Start Basic HTTP Server Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/OVERVIEW.md Starts an HTTP listener on the specified port. Assumes Cowboy is already started. Returns the listener PID on success. ```elixir {:ok, _pid} = Plug.Cowboy.http(MyApp.Router, [], port: 4000) ``` -------------------------------- ### Start Cowboy with HTTP and HTTPS Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy.md Example of configuring children for a supervision tree, starting Cowboy servers on both HTTP and HTTPS ports with specified plugs and options. ```elixir defmodule MyApp.Application do use Application def start(_type, _args) do children = [ {Plug.Cowboy, scheme: :http, plug: MyApp.Router, port: 4000}, {Plug.Cowboy, scheme: :https, plug: MyApp.Router, port: 4001, keyfile: "priv/ssl/key.pem", certfile: "priv/ssl/cert.pem"} ] opts = [strategy: :one_for_one, name: MyApp.Supervisor] Supervisor.start_link(children, opts) end end ``` -------------------------------- ### Start HTTPS Server Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/INDEX.md Starts an HTTPS server with SSL/TLS configuration. Provide the correct paths for your key and certificate files. ```elixir {:ok, _pid} = Plug.Cowboy.https(MyApp, [], port: 443, keyfile: "priv/ssl/key.pem", certfile: "priv/ssl/cert.pem") ``` -------------------------------- ### Start Basic HTTPS Server Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/OVERVIEW.md Starts a TLS-enabled HTTPS listener on the specified port, requiring key and certificate files. Ensures the :ssl application is started and configures SSL defaults. ```elixir {:ok, _pid} = Plug.Cowboy.https(MyApp.Router, [], port: 443, keyfile: "priv/ssl/key.pem", certfile: "priv/ssl/cert.pem") ``` -------------------------------- ### Start Drainer with Non-Existent Listener Reference Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-drainer.md Illustrates starting the drainer with a reference to a listener that does not exist. The drainer starts successfully, but the non-existent listener is silently skipped. ```elixir Plug.Cowboy.Drainer.start_link(refs: [NonExistent.HTTP]) # Starts successfully, but draining a non-existent listener has no effect ``` -------------------------------- ### WebSocket Upgrade Example Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/types.md An example demonstrating how to use Plug.Conn.upgrade_adapter/3 with specific handler module, state, and Cowboy options for a WebSocket connection. ```elixir Plug.Conn.upgrade_adapter(conn, :websocket, { MyApp.WebSocketHandler, %{user_id: user_id}, %{ max_frame_size: 16_000, idle_timeout: 3_600_000, compress: true } }) ``` -------------------------------- ### Start Drainer with Missing :refs Option Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-drainer.md Demonstrates starting the drainer without the required `:refs` option, which results in a `KeyError`. ```elixir Plug.Cowboy.Drainer.start_link([]) # raises KeyError: key :refs not found ``` -------------------------------- ### Start HTTP Server Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/INDEX.md Starts an HTTP server using Plug.Cowboy. Ensure your application module is correctly defined. ```elixir {:ok, _pid} = Plug.Cowboy.http(MyApp, [], port: 4000) ``` -------------------------------- ### Example: WebSocket Upgrade Initialization Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-handler.md Illustrates the expected return value from Plug.Cowboy.Handler.init/2 when a WebSocket upgrade is initiated. ```elixir # WebSocket upgrade Plug.Cowboy.Handler.init( %{method: "GET", path: "/ws", ...}, {MyApp.Router, []} ) # Returns: {Plug.Cowboy.Handler, req_with_headers, {WS.Handler, state}, %{}} ``` -------------------------------- ### Start Cowboy with Plug Options Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy.md Demonstrates how to pass plug-specific options, such as `:otp_app`, when configuring Plug.Cowboy within a supervision tree. ```elixir children = [ {Plug.Cowboy, scheme: :http, plug: {MyApp.Router, [otp_app: :my_app]}, port: 4000} ] ``` -------------------------------- ### Start Plug.Cowboy HTTP Adapter Source: https://github.com/elixir-plug/plug_cowboy/blob/master/README.md Start the Plug.Cowboy adapter for HTTP. Ensure MyPlug is defined elsewhere. ```elixir Plug.Cowboy.http MyPlug, [] ``` -------------------------------- ### Start HTTP Server with Plug.Cowboy Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy.md Starts an HTTP server using Plug.Cowboy. Requires a Plug module, initialization options, and optional Cowboy configurations. ```elixir defmodule MyApp do def start_plug_server do Plug.Cowboy.http(MyApp.Router, [environment: :dev], port: 4000) end end ``` -------------------------------- ### init/2 Callback for WebSocket Upgrades Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-handler.md This example demonstrates the return value when Plug.Conn.upgrade_adapter/3 is used for a WebSocket upgrade within Plug.Cowboy.Handler.init/2. ```elixir def init(req, {plug, opts}) {__MODULE__, req_with_headers, {handler, state}, cowboy_opts} ``` -------------------------------- ### Start HTTPS Server Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/README.md Starts an HTTPS server using Plug.Cowboy. Ensure the keyfile and certfile paths are correct and accessible. ```elixir Plug.Cowboy.https(MyApp, [], port: 443, keyfile: "priv/ssl/key.pem", certfile: "priv/ssl/cert.pem") ``` -------------------------------- ### Application Supervisor with Plug.Cowboy.Drainer Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-drainer.md Example of starting Plug.Cowboy listeners and the Drainer within an application's supervision tree. The drainer should be placed after the listeners to ensure graceful shutdown. ```elixir defmodule MyApp.Application do use Application def start(_type, _args) do children = [ {Plug.Cowboy, scheme: :http, plug: MyApp.Router, port: 4000}, {Plug.Cowboy, scheme: :https, plug: MyApp.Router, port: 4001}, {Plug.Cowboy.Drainer, refs: [MyApp.Router.HTTP, MyApp.Router.HTTPS]} ] opts = [strategy: :one_for_one, name: MyApp.Supervisor] Supervisor.start_link(children, opts) end end ``` -------------------------------- ### Start HTTP Server Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/README.md Starts an HTTP server using Plug.Cowboy and provides a command to shut it down. Ensure MyApp is defined and configured. ```elixir {:ok, _pid} = Plug.Cowboy.http(MyApp, [], port: 4000) Plug.Cowboy.shutdown(MyApp.HTTP) ``` -------------------------------- ### HTTP Protocol Version Example Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/types.md An example demonstrating conditional logic based on the HTTP protocol version obtained from Plug.Conn.get_http_protocol/1. ```elixir case Plug.Conn.get_http_protocol(conn) do :"HTTP/2" -> enable_server_push(conn) :"HTTP/1.1" -> conn :"HTTP/1.0" -> conn end ``` -------------------------------- ### IO Data Examples Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/types.md Illustrates different forms of IO data, including a single binary, a list of binaries, a nested iolist, and an example for chunked responses. ```elixir # Binary "Hello, World!" # List of binaries ["Hello", ", ", "World", "!"] # Nested list (iolist) ["Hello", [", ", ["World", "!"]]] # Optimized for chunked responses chunks = [ "chunk 1", IO.iodata_to_binary(["chunk ", "2"]), "chunk 3" ] ``` -------------------------------- ### Example Output: Plug Handler Exception Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-translator.md This is an example of how a Plug handler exception is formatted by the translator, including connection context and the specific error. ```text [error] #PID<0.1234.0> running MyApp.Router (connection #PID<0.5678.0>, stream id 1) terminated Server: localhost:4000 (http) Request: GET /api/users?page=1 ** (RuntimeError) something went wrong (my_app 0.1.0) lib/my_app/router.ex:25: MyApp.Router.call/2 ``` -------------------------------- ### init/2 Callback for Normal Responses Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-handler.md This example shows the return value for a normal HTTP response handled by Plug.Cowboy.Handler.init/2. ```elixir def init(req, {plug, opts}) {:ok, req, {plug, opts}} ``` -------------------------------- ### Plug Exception (NotSentError) Metadata Example Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-translator.md Example of the metadata generated for a Plug.Conn.NotSentError, including the full conn struct. ```elixir [ crash_reason: {%Plug.Conn.NotSentError{}, [...]}, domain: [:cowboy], conn: %Plug.Conn{...} # Full conn struct ] ``` -------------------------------- ### Starting Plug.Cowboy.Drainer Process Manually Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-drainer.md Starts the drainer GenServer process directly. This is useful for testing or specific scenarios where manual process management is needed. Ensure the `:refs` option is provided. ```elixir Plug.Cowboy.Drainer.start_link( refs: [MyApp.HTTP, MyApp.HTTPS], shutdown: 10_000, check_interval: 500 ) ``` -------------------------------- ### Start HTTPS Server with Plug.Cowboy Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy.md Starts an HTTPS server using Plug.Cowboy. Requires a Plug module, initialization options, and optional Cowboy configurations including SSL/TLS settings. ```elixir defmodule MyApp do def start_https_server do Plug.Cowboy.https( MyApp.Router, [], port: 443, keyfile: "priv/ssl/key.pem", certfile: "priv/ssl/cert.pem", password: "secret" ) end end ``` -------------------------------- ### Example Output: Protocol Error Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-translator.md This is an example of how a protocol error from Cowboy or Ranch is formatted, showing the protocol PID and the specific protocol error. ```text [error] Ranch protocol #PID<0.1234.0> of listener MyApp.HTTP (connection #PID<0.5678.0>, stream id 1) terminated {:protocol_error, :invalid_request_line} ``` -------------------------------- ### http/3 Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy.md Starts a Cowboy HTTP server with the given Plug module and options. It returns a PID for the listener process on success or an error tuple. ```APIDOC ## http/3 ### Description Starts a Cowboy HTTP server with the given Plug module and options. It returns a PID for the listener process on success or an error tuple. ### Function Signature ```elixir @spec http(module(), Keyword.t(), Keyword.t()) :: {:ok, pid} | {:error, :eaddrinuse} | {:error, term} def http(plug, opts, cowboy_options \ []) ``` ### Parameters #### Path Parameters - **plug** (module()) - Required - The Plug module to handle incoming requests. Must implement `c:Plug.init/1` and `c:Plug.call/2`. - **opts** (Keyword.t()) - Required - Options passed to the Plug module's `init/1` function. - **cowboy_options** (Keyword.t()) - Optional - Configuration options for Cowboy listener and socket. Defaults to `[]`. ### Return Value - `{:ok, pid}` where `pid` is the listener process identifier. - `{:error, :eaddrinuse}` if the port is already in use. - `{:error, term}` for other startup failures. ### Throws - `RuntimeError` if Cowboy application cannot be started or is not listed as a dependency. ### Example ```elixir defmodule MyApp do def start_plug_server do Plug.Cowboy.http(MyApp.Router, [environment: :dev], port: 4000) end end # Shutdown later with: Plug.Cowboy.shutdown(MyApp.Router.HTTP) ``` ``` -------------------------------- ### Socket Address Tuple Examples Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/types.md Represents a network address for binding. Examples cover IPv4, IPv6, and Unix domain sockets. ```elixir inet_address() :: {a, b, c, d} | # IPv4 {a, b, c, d, e, f, g, h} | # IPv6 {:local, String.t()} # Unix domain socket ``` ```elixir # Localhost {127, 0, 0, 1} # All interfaces {0, 0, 0, 0} # Specific interface {192, 168, 1, 100} ``` ```elixir # Localhost {0, 0, 0, 0, 0, 0, 0, 1} # All interfaces {0, 0, 0, 0, 0, 0, 0, 0} # Link-local {0xfe80, 0, 0, 0, 0xaaaa, 0, 0, 0x1} ``` ```elixir {:local, "/tmp/my_app.sock"} {:local, "/var/run/app/server.sock"} ``` -------------------------------- ### start_link/1 Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-drainer.md Starts the drainer GenServer process. This function initiates the drainer process, which will then manage the graceful shutdown of specified Cowboy listeners. ```APIDOC ## start_link/1 ### Description Starts the drainer GenServer process. ### Function Signature ```elixir @spec start_link(opts :: Keyword.t()) :: {:ok, pid} | {:error, term} def start_link(opts) ``` ### Parameters #### Path Parameters - **opts** (Keyword.t()) - Required - Configuration options (see `child_spec/1` for option details). ### Return Value - `{:ok, pid}` - Process started successfully - `{:error, term}` - Startup failed ### Raises - `KeyError` if `:refs` option is missing - `ArgumentError` if `:refs` is not `:all` or a list ### Process Behavior Sets the process flag `:trap_exit` to handle graceful shutdown. During termination, the process suspends each configured listener, waits for existing connections to close, and checks the connection count at the specified interval until zero or timeout. ### Example ```elixir {:ok, drainer_pid} = Plug.Cowboy.Drainer.start_link( refs: [MyApp.HTTP, MyApp.HTTPS], shutdown: 10_000, check_interval: 500 ) ``` ``` -------------------------------- ### Start Drainer with Invalid :refs Type Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-drainer.md Shows starting the drainer with an invalid type for the `:refs` option, leading to an `ArgumentError`. ```elixir Plug.Cowboy.Drainer.start_link(refs: 123) # raises ArgumentError: ":refs should be :all or a list of references, got: 123" ``` -------------------------------- ### Start Server in Supervisor Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/INDEX.md Defines children for a supervisor to manage Plug.Cowboy HTTP servers and the Drainer for graceful shutdowns. Ensure the 'MyApp.HTTP' reference is correctly set if used. ```elixir children = [ {Plug.Cowboy, scheme: :http, plug: MyApp, port: 4000}, {Plug.Cowboy.Drainer, refs: [MyApp.HTTP]} ] ``` -------------------------------- ### Start HTTP Server in Supervision Tree Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/README.md Integrates Plug.Cowboy into an Elixir supervision tree for robust process management. Requires defining MyApp and its HTTP reference. ```elixir children = [ {Plug.Cowboy, scheme: :http, plug: MyApp, port: 4000}, {Plug.Cowboy.Drainer, refs: [MyApp.HTTP]} ] Supervisor.start_link(children, strategy: :one_for_one) ``` -------------------------------- ### https/3 Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy.md Starts a Cowboy HTTPS server with the given Plug module and options, including SSL/TLS settings. It returns a PID for the listener process on success or an error tuple. ```APIDOC ## https/3 ### Description Starts a Cowboy HTTPS server with the given Plug module and options, including SSL/TLS settings. It returns a PID for the listener process on success or an error tuple. ### Function Signature ```elixir @spec https(module(), Keyword.t(), Keyword.t()) :: {:ok, pid} | {:error, :eaddrinuse} | {:error, term} def https(plug, opts, cowboy_options \ []) ``` ### Parameters #### Path Parameters - **plug** (module()) - Required - The Plug module to handle incoming requests. - **opts** (Keyword.t()) - Required - Options passed to the Plug module's `init/1` function. - **cowboy_options** (Keyword.t()) - Optional - Configuration options including SSL/TLS settings and Cowboy options. All options from `Plug.SSL.configure/1` are accepted. Defaults to `[]`. ### Return Value - `{:ok, pid}` where `pid` is the listener process identifier. - `{:error, :eaddrinuse}` if the port is already in use. - `{:error, term}` for other startup failures. ### Additional Processing Before starting the server, this function calls `Plug.SSL.configure/1` on the `cowboy_options` to ensure SSL/TLS settings are properly configured. It also ensures the `:ssl` application is started. ### Example ```elixir defmodule MyApp do def start_https_server do Plug.Cowboy.https( MyApp.Router, [], port: 443, keyfile: "priv/ssl/key.pem", certfile: "priv/ssl/cert.pem", password: "secret" ) end end # Shutdown later with: Plug.Cowboy.shutdown(MyApp.Router.HTTPS) ``` ``` -------------------------------- ### Configure SSL Files for https/3 Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/errors.md When using https/3, ensure that the specified keyfile and certfile paths are correct and the files exist. An example of invalid configuration is provided. ```elixir Plug.Cowboy.https(MyPlug, [], keyfile: "nonexistent.pem", certfile: "nonexistent.pem") # ArgumentError: could not start Cowboy2 adapter, ... ``` ```elixir Plug.Cowboy.https(MyPlug, [], keyfile: "priv/ssl/key.pem", certfile: "priv/ssl/cert.pem", password: "secret") ``` -------------------------------- ### Start HTTP and HTTPS Servers Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/OVERVIEW.md Configure Plug.Cowboy to run both HTTP and HTTPS servers. Ensure your SSL certificate and key files are correctly specified for HTTPS. ```elixir children = [ {Plug.Cowboy, scheme: :http, plug: MyApp, port: 80}, {Plug.Cowboy, scheme: :https, plug: MyApp, port: 443, keyfile: "priv/ssl/key.pem", certfile: "priv/ssl/cert.pem"}, {Plug.Cowboy.Drainer, refs: [MyApp.HTTP, MyApp.HTTPS]} ] ``` -------------------------------- ### Start Server via Unix Socket Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/OVERVIEW.md Configure Plug.Cowboy to listen on a Unix socket instead of a TCP port. This is useful for inter-process communication on the same machine. ```elixir {Plug.Cowboy, scheme: :http, plug: MyApp, ip: {:local, "/tmp/app.sock"}, port: 0} ``` -------------------------------- ### Start Supervised HTTP Server with Graceful Shutdown Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/OVERVIEW.md Configures a supervised HTTP listener and a drainer for graceful shutdown. The listener restarts if it crashes, and the drainer ensures connections are closed before the listener stops. ```elixir children = [ {Plug.Cowboy, scheme: :http, plug: MyApp.Router, port: 4000}, {Plug.Cowboy.Drainer, refs: [MyApp.Router.HTTP]} ] Supervisor.start_link(children, strategy: :one_for_one) ``` -------------------------------- ### Start Plug.Cowboy in Supervision Tree Source: https://github.com/elixir-plug/plug_cowboy/blob/master/README.md Configure Plug.Cowboy as a child process in an OTP application's supervision tree. Specify the scheme, the Plug module, and the port. ```elixir children = [ {Plug.Cowboy, scheme: :http, plug: MyApp, port: 4040} ] ``` ```elixir opts = [strategy: :one_for_one, name: MyApp.Supervisor] Supervisor.start_link(children, opts) ``` -------------------------------- ### Use Environment Variable for HTTP Port in Application Startup Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/configuration.md Retrieve the configured HTTP port from the application environment and use it to start the Plug.Cowboy server. ```elixir port = Application.get_env(:my_app, :http_port) Plug.Cowboy.http(MyApp, [], port: port) ``` -------------------------------- ### Read HTTP Port from Environment Variable Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/configuration.md Configure the HTTP port using environment variables for runtime flexibility. This example uses `System.get_env` and specifies a default value. ```elixir # config/runtime.exs (Elixir 1.11+) config :my_app, :http_port, System.get_env("HTTP_PORT", "4000") |> String.to_integer() ``` -------------------------------- ### Example Exception Log Entry Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/errors.md Illustrates a typical log entry for an exception occurring during request processing. By default, only server errors (5xx) are logged. ```elixir ERROR [domain: [:cowboy]] #PID<0.1234.0> running MyApp.Router (connection #PID<0.5678.0>, stream id 1) terminated Server: example.com:8080 (http) Request: GET /api/users?page=1 ** (RuntimeError) something went wrong (my_app 0.1.0) lib/my_app/router.ex:25: MyApp.Router.call/2 ``` -------------------------------- ### Provide Required :refs Option to Drainer Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/errors.md The Plug.Cowboy.Drainer.start_link/1 function requires the :refs option. An example of invalid usage is shown, followed by the correct way to provide the option. ```elixir Plug.Cowboy.Drainer.start_link([]) # KeyError: key :refs not found ``` ```elixir Plug.Cowboy.Drainer.start_link(refs: [MyApp.HTTP, MyApp.HTTPS]) ``` -------------------------------- ### Production Environment with Graceful Shutdown Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/configuration.md Configure Plug.Cowboy for production, including HTTPS, exception logging, connection metadata exclusion, and graceful shutdown with a drainer. This setup prioritizes security and availability. ```elixir config :plug_cowboy, log_exceptions_with_status_code: [500..599], conn_in_exception_metadata: false ``` ```elixir children = [ {Plug.Cowboy, scheme: :https, plug: MyApp.Router, port: 443, ip: {0, 0, 0, 0}, keyfile: "/etc/ssl/private/key.pem", certfile: "/etc/ssl/certs/cert.pem", transport_options: [num_acceptors: 200, max_connections: 50_000]}, {Plug.Cowboy.Drainer, refs: [MyApp.Router.HTTPS], shutdown: 45_000, check_interval: 100} ] Supervisor.start_link(children, strategy: :one_for_one) ``` -------------------------------- ### Use Valid :refs Value in Drainer Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/errors.md The :refs option for Plug.Cowboy.Drainer.start_link/1 must be either :all or a list of references. Examples of invalid values and correct usage are provided. ```elixir Plug.Cowboy.Drainer.start_link(refs: 123) # ArgumentError: :refs should be :all or a list of references, got: 123 Plug.Cowboy.Drainer.start_link(refs: "all") # ArgumentError: :refs should be :all or a list of references, got: "all" ``` ```elixir # Drain all listeners Plug.Cowboy.Drainer.start_link(refs: :all) # Drain specific listeners Plug.Cowboy.Drainer.start_link(refs: [MyApp.HTTP, MyApp.HTTPS]) ``` -------------------------------- ### Deployment Without Request Loss Configuration Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-drainer.md Configuration example for Plug.Cowboy.Drainer suitable for containerized environments like Kubernetes. It sets a 45-second shutdown timeout and a 100ms check interval to align with typical SIGTERM grace periods. ```elixir {Plug.Cowboy.Drainer, refs: :all, shutdown: 45_000, # 45s for SIGTERM grace period check_interval: 100 # Check every 100ms} ``` -------------------------------- ### Attach to Plug Cowboy Telemetry Events Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/OVERVIEW.md Demonstrates how to attach a handler to various Cowboy telemetry events, such as request start, stop, and exceptions. This allows for custom observability and logging of server activity. ```elixir # Attach to events :telemetry.attach_many( "my-handler", [ [:cowboy, :request, :start], [:cowboy, :request, :stop], [:cowboy, :request, :exception], [:cowboy, :request, :early_error] ], &MyApp.Telemetry.handle_event/4, nil ) # Handler def handle_event(event, measurements, metadata, _config) do case event do [:cowboy, :request, :start] -> IO.inspect({:start, metadata}) [:cowboy, :request, :stop] -> IO.inspect({:stop, measurements, metadata}) [:cowboy, :request, :exception] -> IO.inspect({:exception, metadata}) end end ``` -------------------------------- ### Configure SSL (Quick Reference) Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/OVERVIEW.md Configure SSL options for an HTTPS server using Plug.Cowboy.https and Plug.SSL.configure. ```elixir Plug.Cowboy.https(Plug, [], [port: 443] ++ Plug.SSL.configure(...)) ``` -------------------------------- ### Protocol Error (Invalid Request) Log Output Example Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-translator.md Example of log output for a Ranch protocol error, such as an invalid request line. This type of error is always logged. ```elixir [error] Ranch protocol #PID<0.1234.0> of listener MyApp.HTTP (connection #PID<0.5678.0>, stream id 1) terminated {:invalid_request_line} ``` -------------------------------- ### Configure IPv6 Binding Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy.md Example of setting a socket option to bind the Cowboy server only to IPv6 addresses. ```elixir ipv6_v6only: true # Bind only to IPv6 addresses ``` -------------------------------- ### Get HTTP Protocol Version Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-conn.md Returns the HTTP protocol version used by the client. This is determined by calling `:cowboy_req.version/1`. ```elixir @impl true def get_http_protocol(req) ``` ```elixir protocol = Plug.Conn.get_http_protocol(conn) # :"HTTP/1.1" ``` -------------------------------- ### Handle Unsupported Upgrade Protocols Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/errors.md Demonstrates how to handle unsupported upgrade protocols by checking the return value of Plug.Conn.upgrade_adapter/3. Only :websocket is supported. ```elixir Plug.Conn.upgrade_adapter(conn, :spdy, args) # returns {:error, :not_supported} ``` ```elixir case Plug.Conn.upgrade_adapter(conn, :websocket, {handler, state, opts}) do {:ok, conn} -> handle_websocket(conn) {:error, :not_supported} -> Plug.Conn.send_resp(conn, 400, "Not supported") end ``` -------------------------------- ### Plug Module Init Function Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-handler.md Implement the init/1 function to validate and return options. This is required for Plug.Cowboy.Handler to function correctly. ```elixir def init(opts) do # Validate and return opts opts end ``` -------------------------------- ### Supervisor Child Specification Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/types.md Map returned by Plug.Cowboy.child_spec/1 for integration with Supervisor.start_link/2. It defines how a Cowboy child process should be started and managed. ```elixir Supervisor.child_spec() ``` ```elixir spec = Plug.Cowboy.child_spec( scheme: :http, plug: MyApp.Router, port: 4000, id: MyApp.HTTP, shutdown: 10_000 ) # Returns: %{ id: {some_ranch_module, MyApp.HTTP}, start: {some_ranch_module, :start_link, [...]}, restart: :permanent, shutdown: 10_000, type: :supervisor, modules: [...] } ``` -------------------------------- ### child_spec/1 Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy.md Generates a supervisor child specification for integrating Cowboy into an Elixir supervision tree. This function is essential for starting Cowboy as a supervised process. ```APIDOC ## child_spec/1 ### Description Returns a supervisor child specification for starting Cowboy as part of a supervision tree. ### Function Signature ```elixir @spec child_spec(keyword()) :: Supervisor.child_spec() def child_spec(opts) ``` ### Parameters #### Path Parameters - **opts** (Keyword.t()) - Required - Supervisor child options with required `:scheme` and `:plug` keys. ### Child Specification Options #### Key Parameters - **:scheme** (:http | :https) - Required - The protocol scheme for the listener. - **:plug** (module() | {module(), Keyword.t()}) - Required - The Plug module to handle requests, or a tuple with the module and plug options. - **:id** (term()) - Optional - Custom ID for the child spec. Defaults to the auto-generated ranch listener module. - **:shutdown** (pos_integer() | :brutal_kill | :infinity) - Optional - Grace period in milliseconds for graceful shutdown. Defaults to 5000. - **:options** (Keyword.t()) - Optional - Deprecated; use Cowboy options at the top level instead. - **Other keys** (—) - Optional - All other top-level keys are passed as Cowboy/socket options (see module documentation for full list). ### Return Value Returns a `Supervisor.child_spec()` map compatible with `Supervisor.start_link/2`. ### Example ```elixir defmodule MyApp.Application do use Application def start(_type, _args) do children = [ {Plug.Cowboy, scheme: :http, plug: MyApp.Router, port: 4000}, {Plug.Cowboy, scheme: :https, plug: MyApp.Router, port: 4001, keyfile: "priv/ssl/key.pem", certfile: "priv/ssl/cert.pem"} ] opts = [strategy: :one_for_one, name: MyApp.Supervisor] Supervisor.start_link(children, opts) end end # Using plug options children = [ {Plug.Cowboy, scheme: :http, plug: {MyApp.Router, [otp_app: :my_app]}, port: 4000} ] ``` ``` -------------------------------- ### Development Server Configuration Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/INDEX.md A simple HTTP server configuration for development environments. ```elixir # Simple HTTP server {Plug.Cowboy, scheme: :http, plug: MyApp, port: 4000} ``` -------------------------------- ### Basic HTTP Server Configuration Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/INDEX.md Configure a basic HTTP server to listen on a specific port. ```elixir # Basic Plug.Cowboy.http(MyApp, [], port: 8080) ``` -------------------------------- ### Stream Response (Quick Reference) Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/OVERVIEW.md Initiate a chunked response and send data in chunks using Plug.Conn.send_chunked and Plug.Conn.chunk. ```elixir Plug.Conn.send_chunked(conn, 200) Plug.Conn.chunk(conn, data) ``` -------------------------------- ### WebSocket Upgrade (Quick Reference) Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/OVERVIEW.md Upgrade an incoming connection to a WebSocket using Plug.Conn.upgrade_adapter. ```elixir Plug.Conn.upgrade_adapter(conn, :websocket, {Handler, state, opts}) ``` -------------------------------- ### Handle Unsupported Protocol Upgrade Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-conn.md Illustrates that attempting to upgrade to an unsupported protocol like `:spdy` using `upgrade_adapter/3` returns `{:error, :not_supported}`. ```elixir Plug.Conn.upgrade_adapter(conn, :spdy, {handler, state, %{}}) # returns {:error, :not_supported} ``` -------------------------------- ### Drain Specific Listeners Configuration Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-drainer.md Configuration example for Plug.Cowboy.Drainer to drain specific listeners with a 5-second timeout. This is useful when you need fine-grained control over which listeners are drained. ```elixir {Plug.Cowboy.Drainer, refs: [MyApp.HTTP, MyApp.HTTPS]} ``` -------------------------------- ### Add Plug.Cowboy to Supervisor (Quick Reference) Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/OVERVIEW.md Integrate Plug.Cowboy as a child process in a supervisor tree. ```elixir {Plug.Cowboy, scheme: :http, plug: Plug, port: 4000} ``` -------------------------------- ### Production Server Configuration Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/INDEX.md Configure HTTP and HTTPS listeners with graceful shutdown for production. Includes environment variable usage for SSL certificates. ```elixir # HTTP + HTTPS with graceful shutdown children = [ {Plug.Cowboy, scheme: :http, plug: MyApp, port: 80, ip: {0, 0, 0, 0}, transport_options: [num_acceptors: 100, max_connections: 16_384]}, {Plug.Cowboy, scheme: :https, plug: MyApp, port: 443, ip: {0, 0, 0, 0}, keyfile: System.get_env("SSL_KEY_PATH"), certfile: System.get_env("SSL_CERT_PATH"), transport_options: [num_acceptors: 100, max_connections: 16_384]}, {Plug.Cowboy.Drainer, refs: :all, shutdown: 45_000} ] # Application configuration config :plug_cowboy, log_exceptions_with_status_code: [500..599], conn_in_exception_metadata: false ``` -------------------------------- ### File Sizes and Line Counts Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/MANIFEST.md Provides an overview of the file sizes and line counts for various documentation files within the Plug.Cowboy project. This helps in understanding the scope and depth of the documentation. ```text plug-cowboy.md (361 lines, 12 KB) plug-cowboy-conn.md (514 lines, 13 KB) plug-cowboy-drainer.md (229 lines, 5.9 KB) plug-cowboy-handler.md (431 lines, 11 KB) plug-cowboy-translator.md (353 lines, 9.2 KB) configuration.md (417 lines, 12 KB) types.md (422 lines, 9.0 KB) errors.md (570 lines, 12 KB) OVERVIEW.md (542 lines, 14 KB) INDEX.md (418 lines, 13 KB) README.md (82 lines, 4.1 KB) MANIFEST.md (this file) ───────────────────────────────────────────── TOTAL: (4,731 lines, ~132 KB) ``` -------------------------------- ### Custom Logger Backend to Handle Cowboy Errors Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-translator.md Example of a custom logger backend that specifically handles Cowboy errors by inspecting the metadata domain and crash reason. ```elixir defmodule MyLogger do def handle_event({_level, _gl, {_mod, _msg, _ts, meta}}, state) do case meta[:domain] do [:cowboy] -> Logger.error("Cowboy error: #{inspect(meta[:crash_reason])}") _ -> :ok end state end end ``` -------------------------------- ### Catching Plug.Cowboy Startup Errors Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/errors.md Handles potential errors during Plug.Cowboy server startup, such as the port already being in use or other reasons for failure. Logs the specific error encountered. ```elixir case Plug.Cowboy.http(MyPlug, [], port: 4000) do {:ok, pid} -> {:ok, pid} {:error, :eaddrinuse} -> Logger.error("Port 4000 already in use") {:error, :eaddrinuse} {:error, reason} -> Logger.error("Failed to start: #{inspect(reason)}") {:error, reason} end ``` -------------------------------- ### Upgrade Connection to WebSocket Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy.md Use Plug.Conn.upgrade_adapter/3 to establish WebSocket connections. The application must validate the upgrade request before calling this function. ```elixir Plug.Conn.upgrade_adapter(conn, :websocket, {handler_module, handler_state, cowboy_opts}) ``` -------------------------------- ### Get Peer Data from Cowboy Request Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-conn.md Retrieves client connection information including IP address, port, and SSL certificate from a Cowboy request object. Useful for logging or security checks. ```elixir @impl true def get_peer_data(%{peer: {ip, port}, cert: cert}) ``` ```elixir %{address: ip, port: port, ssl_cert: cert} = Plug.Conn.get_peer_data(conn) # ip = {127, 0, 0, 1} # port = 54321 # cert = nil (HTTP) or binary (HTTPS) ``` -------------------------------- ### Enable Full Conn Struct in Exception Metadata Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-translator.md Configure Plug Cowboy to include the full Plug.Conn struct in log metadata when an exception occurs. Set to false to exclude it. ```elixir config :plug_cowboy, conn_in_exception_metadata: true ``` -------------------------------- ### Drain All Listeners Configuration with Custom Intervals Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-drainer.md Configuration example for Plug.Cowboy.Drainer to drain all listeners with custom shutdown and check intervals, and a specific child spec ID. This provides flexibility for different shutdown scenarios. ```elixir {Plug.Cowboy.Drainer, refs: :all, shutdown: 30_000, check_interval: 100, id: :graceful_shutdown} ``` -------------------------------- ### HTTPS Server Configuration Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/configuration.md Configure an HTTPS server with certificate and key files. Ensure the password, verification mode, and CA certificate file are correctly specified. ```elixir Plug.Cowboy.https(MyPlug, [], port: 443, keyfile: "priv/ssl/key.pem", certfile: "priv/ssl/cert.pem", password: "secret", verify: :verify_peer, cacertfile: "priv/ssl/ca.pem") ``` -------------------------------- ### File Structure Overview Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/INDEX.md This snippet outlines the directory structure of the Plug.Cowboy project, indicating the purpose of each markdown file and the organization of API reference documentation. ```markdown ``` /output/ ├── INDEX.md (this file) ├── OVERVIEW.md (architecture & concepts) ├── configuration.md (all config options) ├── types.md (type definitions) ├── errors.md (error conditions) └── api-reference/ ├── plug-cowboy.md (main module) ├── plug-cowboy-drainer.md (graceful shutdown) ├── plug-cowboy-conn.md (adapter implementation) ├── plug-cowboy-handler.md (stream handler) └── plug-cowboy-translator.md (error logging) ``` ``` -------------------------------- ### Initiate HTTP/2 Server Push Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-conn.md Initiates HTTP/2 server push for a given resource path and headers. This is an HTTP/2 only feature and is ignored for HTTP/1.1 requests. ```elixir @impl true def push(req, path, headers) ``` ```elixir conn = Plug.Conn.push(conn, "/static/style.css", [{"content-type", "text/css"}]) ``` -------------------------------- ### Enable Compression and Custom Stream Handlers in Plug.Cowboy Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/configuration.md Configure gzip compression or specify custom stream handlers for Plug.Cowboy. Note that compression conflicts with custom stream handlers if not explicitly included. ```elixir # Enable compression with default telemetry Plug.Cowboy.http(MyPlug, [], compress: true) # Custom stream handlers (no telemetry) Plug.Cowboy.http(MyPlug, [], stream_handlers: [:cowboy_stream_h]) # Custom handlers with compression Plug.Cowboy.http(MyPlug, [], stream_handlers: [:cowboy_compress_h, :cowboy_stream_h]) ``` -------------------------------- ### Development Environment HTTP Configuration Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/configuration.md Configure HTTP server settings for the development environment, including port and IP address. This is typically done in `config/dev.exs` and `lib/my_app/application.ex`. ```elixir config :my_app, MyApp.Application, http: [port: 4000, ip: {127, 0, 0, 1}] ``` ```elixir port = Application.get_env(:my_app, MyApp.Application)[:http][:port] children = [ {Plug.Cowboy, scheme: :http, plug: MyApp.Router, port: port} ] Supervisor.start_link(children, strategy: :one_for_one) ``` -------------------------------- ### Configure Drainer with Deprecated and New Options Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-drainer.md Compares the old style of configuring the drainer with the deprecated `:drain_check_interval` option and the new preferred style using `:check_interval`. ```elixir # Old style (still works) {Plug.Cowboy.Drainer, refs: [...], drain_check_interval: 1000} # New style (preferred) {Plug.Cowboy.Drainer, refs: [...], check_interval: 1000} ``` -------------------------------- ### Stop Server (Quick Reference) Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/OVERVIEW.md Gracefully shut down a running Plug.Cowboy server instance. ```elixir Plug.Cowboy.shutdown(Plug.HTTP) ``` -------------------------------- ### Add Graceful Shutdown to Supervisor (Quick Reference) Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/OVERVIEW.md Configure Plug.Cowboy.Drainer for graceful shutdown alongside the main Plug.Cowboy child. ```elixir Add {Plug.Cowboy.Drainer, refs: [Plug.HTTP]} after Plug.Cowboy child ``` -------------------------------- ### Multiple Port Configuration Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/INDEX.md Configure the server to listen on multiple ports simultaneously. ```elixir # Multiple ports [ {Plug.Cowboy, scheme: :http, plug: MyApp, ref: MyApp.HTTP_8080, port: 8080}, {Plug.Cowboy, scheme: :http, plug: MyApp, ref: MyApp.HTTP_8081, port: 8081} ] ``` -------------------------------- ### High Performance Server Configuration Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/INDEX.md Tune the server for high performance, supporting 10k+ concurrent connections with optimized socket options and timeouts. ```elixir # Tuned for 10k+ concurrent connections {Plug.Cowboy, scheme: :http, plug: MyApp, port: 8080, ip: {0, 0, 0, 0}, transport_options: [ num_acceptors: 500, max_connections: 100_000, socket_opts: [ {:raw, 6, 4, 1}, # TCP_NODELAY {:raw, 6, 9, 1} # TCP_KEEPALIVE ] ], protocol_options: [ idle_timeout: 60_000, request_timeout: 30_000, max_request_line_length: 50_000 ], compress: true} ``` -------------------------------- ### Handle File Not Found Error Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/api-reference/plug-cowboy-conn.md Demonstrates how `send_file/3` raises a `File.Error` when the specified file does not exist. ```elixir Plug.Conn.send_file(conn, 200, [], "/nonexistent") # raises File.Error ``` -------------------------------- ### Configure Multiple HTTP Ports with Plug Cowboy Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/OVERVIEW.md Sets up Plug Cowboy to listen on multiple HTTP ports by defining separate child specifications for each port in the application's supervision tree. Each listener is assigned a unique reference. ```elixir children = [ {Plug.Cowboy, scheme: :http, plug: MyApp, ref: MyApp.HTTP_8080, port: 8080}, {Plug.Cowboy, scheme: :http, plug: MyApp, ref: MyApp.HTTP_8081, port: 8081} ] ``` -------------------------------- ### Configure Listener Reference and Dispatch for Plug.Cowboy Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/configuration.md Manage listener references for graceful shutdown and configure custom dispatch tables for advanced routing. Useful when binding the same plug to multiple ports. ```elixir # Default ref: MyApp.HTTP or MyApp.HTTPS Plug.Cowboy.http(MyApp, []) # Custom refs for multiple ports Plug.Cowboy.http(MyApp, [], ref: MyApp.HTTP_4000, port: 4000) Plug.Cowboy.http(MyApp, [], ref: MyApp.HTTP_5000, port: 5000) # Shutdown by custom ref Plug.Cowboy.shutdown(MyApp.HTTP_4000) Plug.Cowboy.shutdown(MyApp.HTTP_5000) ``` -------------------------------- ### Send File Response Source: https://github.com/elixir-plug/plug_cowboy/blob/master/_autodocs/INDEX.md Use this for zero-copy file sending. Specify the file path and range. ```elixir Plug.Conn.send_file(conn, 200, [], "path/to/file", 0, :all) ```